diff --git a/mayan/apps/appearance/templates/appearance/calculate_form_title.html b/mayan/apps/appearance/templates/appearance/calculate_form_title.html index e27204e32c..da6f1c075a 100644 --- a/mayan/apps/appearance/templates/appearance/calculate_form_title.html +++ b/mayan/apps/appearance/templates/appearance/calculate_form_title.html @@ -1,7 +1,7 @@ {% load i18n %} {% if title %} - {{ title|striptags }} + {{ title }} {% else %} {% if read_only %} {% blocktrans %}Details for: {{ object }}{% endblocktrans %} diff --git a/mayan/apps/document_indexing/apps.py b/mayan/apps/document_indexing/apps.py index aef05f315d..fed0dadcaa 100644 --- a/mayan/apps/document_indexing/apps.py +++ b/mayan/apps/document_indexing/apps.py @@ -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( diff --git a/mayan/apps/document_indexing/managers.py b/mayan/apps/document_indexing/managers.py index c389a108c3..4eea5fd87b 100644 --- a/mayan/apps/document_indexing/managers.py +++ b/mayan/apps/document_indexing/managers.py @@ -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) diff --git a/mayan/apps/document_indexing/models.py b/mayan/apps/document_indexing/models.py index d57100daed..744d94767e 100644 --- a/mayan/apps/document_indexing/models.py +++ b/mayan/apps/document_indexing/models.py @@ -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() diff --git a/mayan/apps/document_indexing/tasks.py b/mayan/apps/document_indexing/tasks.py index 5b115d9d35..e6cfe43bc3 100644 --- a/mayan/apps/document_indexing/tasks.py +++ b/mayan/apps/document_indexing/tasks.py @@ -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() diff --git a/mayan/apps/document_indexing/templates/document_indexing/node_details.html b/mayan/apps/document_indexing/templates/document_indexing/node_details.html new file mode 100644 index 0000000000..9fa2ffee6c --- /dev/null +++ b/mayan/apps/document_indexing/templates/document_indexing/node_details.html @@ -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 %} +

{{ title }}

+
+ {% endif %} + +
+
+ {{ navigation }} +
+ +
+ {% include 'appearance/generic_list_subtemplate.html' %} +
+
+ +{% endblock %} diff --git a/mayan/apps/document_indexing/views.py b/mayan/apps/document_indexing/views.py index c21fe2741c..fb0da0beb7 100644 --- a/mayan/apps/document_indexing/views.py +++ b/mayan/apps/document_indexing/views.py @@ -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: diff --git a/mayan/apps/document_indexing/widgets.py b/mayan/apps/document_indexing/widgets.py index f7371e92c0..880c57777e 100644 --- a/mayan/apps/document_indexing/widgets.py +++ b/mayan/apps/document_indexing/widgets.py @@ -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 = '%(value)s' - - 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( + '{text}'.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('
') + + 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( + '{count}{space} {text}'.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('
') + + return mark_safe(''.join(result))