Add new split move index navigation.

This commit is contained in:
Roberto Rosario
2016-03-15 04:11:19 -04:00
parent 3d36f1b828
commit 1a20d93e4c
8 changed files with 105 additions and 72 deletions

View File

@@ -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(

View File

@@ -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)

View File

@@ -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()

View File

@@ -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()

View File

@@ -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 %}

View File

@@ -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:

View File

@@ -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='&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' * level,
text=escape(element)
)
)
result.append('</div>')
return mark_safe(''.join(result))