Improve SourceColumn workflow by allowing explicit functions as columns. Remove usage of encapsulate. Move instances of 'extra_columns' to SourceColumn.
This commit is contained in:
@@ -10,7 +10,6 @@ from django.http import Http404
|
|||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from common.utils import encapsulate
|
|
||||||
from common.views import (
|
from common.views import (
|
||||||
AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView,
|
AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView,
|
||||||
SingleObjectListView
|
SingleObjectListView
|
||||||
|
|||||||
@@ -87,7 +87,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if not hide_columns %}
|
{% if not hide_columns %}
|
||||||
{% for column in object|get_source_columns %}
|
{% for column in object|get_source_columns %}
|
||||||
<td>{{ object|object_property:column.attribute }}</td>
|
<td>{% source_column_resolve column=column %}</td>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for column in extra_columns %}
|
{% for column in extra_columns %}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ from __future__ import unicode_literals
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from common import MayanAppConfig, menu_object, menu_sidebar
|
from common import MayanAppConfig, menu_object, menu_sidebar
|
||||||
from common.utils import encapsulate
|
|
||||||
from navigation import SourceColumn
|
from navigation import SourceColumn
|
||||||
|
|
||||||
from .links import (
|
from .links import (
|
||||||
@@ -23,9 +22,7 @@ class ConverterApp(MayanAppConfig):
|
|||||||
SourceColumn(source=Transformation, label=_('Order'), attribute='order')
|
SourceColumn(source=Transformation, label=_('Order'), attribute='order')
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Transformation, label=_('Transformation'),
|
source=Transformation, label=_('Transformation'),
|
||||||
attribute=encapsulate(
|
func=lambda context: unicode(context['object'])
|
||||||
lambda transformation: unicode(transformation)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Transformation, label=_('Arguments'), attribute='arguments'
|
source=Transformation, label=_('Arguments'), attribute='arguments'
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ from datetime import datetime
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from common import MayanAppConfig, menu_object, menu_setup, menu_sidebar
|
from common import MayanAppConfig, menu_object, menu_setup, menu_sidebar
|
||||||
from common.utils import encapsulate
|
|
||||||
from navigation import SourceColumn
|
from navigation import SourceColumn
|
||||||
|
|
||||||
from .api import Key, KeyStub
|
from .api import Key, KeyStub
|
||||||
@@ -23,34 +22,31 @@ class DjangoGPGApp(MayanAppConfig):
|
|||||||
def ready(self):
|
def ready(self):
|
||||||
super(DjangoGPGApp, self).ready()
|
super(DjangoGPGApp, self).ready()
|
||||||
|
|
||||||
SourceColumn(source=Key, label='ID', attribute='key_id')
|
SourceColumn(source=Key, label=_('ID'), attribute='key_id')
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Key, label='Owner', attribute=encapsulate(
|
source=Key, label=_('Owner'),
|
||||||
lambda key: ', '.join(key.uids)
|
func=lambda context: ', '.join(context['object'].uids)
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=KeyStub, label='ID', attribute=encapsulate(
|
source=KeyStub, label=_('ID'),
|
||||||
lambda key: '...{0}'.format(key.key_id[-16:])
|
func=lambda context: '...{0}'.format(context['object'].key_id[-16:])
|
||||||
)
|
)
|
||||||
)
|
SourceColumn(source=KeyStub, label=_('Type'), attribute='key_type')
|
||||||
SourceColumn(source=KeyStub, label='Type', attribute='key_type')
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=KeyStub, label='Creation date', attribute=encapsulate(
|
source=KeyStub, label=_('Creation date'),
|
||||||
lambda key: datetime.fromtimestamp(int(key.date))
|
func=lambda context: datetime.fromtimestamp(
|
||||||
|
int(context['object'].date)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=KeyStub, label='Expiration date', attribute=encapsulate(
|
source=KeyStub, label=_('Expiration date'),
|
||||||
lambda key: datetime.fromtimestamp(int(key.expires)) if key.expires else _('No expiration')
|
func=lambda context: datetime.fromtimestamp(int(context['object'].expires)) if context['object'].expires else _('No expiration')
|
||||||
)
|
)
|
||||||
)
|
SourceColumn(source=KeyStub, label=_('Length'), attribute='length')
|
||||||
SourceColumn(source=KeyStub, label='Length', attribute='length')
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=KeyStub, label='Identities', attribute=encapsulate(
|
source=KeyStub, label=_('Identities'),
|
||||||
lambda key: ', '.join(key.uids)
|
func=lambda context: ', '.join(context['object'].uids)
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
menu_object.bind_links(links=(link_key_delete,), sources=(Key,))
|
menu_object.bind_links(links=(link_key_delete,), sources=(Key,))
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ from django.template import RequestContext
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from common.generics import SimpleView, SingleObjectListView
|
from common.generics import SimpleView, SingleObjectListView
|
||||||
from common.utils import encapsulate
|
|
||||||
from permissions import Permission
|
from permissions import Permission
|
||||||
|
|
||||||
from .api import Key
|
from .api import Key
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
|
|
||||||
from acls import ModelPermission
|
from acls import ModelPermission
|
||||||
from common import MayanAppConfig, menu_facet, menu_object, menu_sidebar
|
from common import MayanAppConfig, menu_facet, menu_object, menu_sidebar
|
||||||
from common.utils import encapsulate
|
|
||||||
from documents.models import Document
|
from documents.models import Document
|
||||||
from navigation import SourceColumn
|
from navigation import SourceColumn
|
||||||
|
|
||||||
@@ -37,9 +36,7 @@ class DocumentCommentsApp(MayanAppConfig):
|
|||||||
SourceColumn(source=Comment, label=_('Date'), attribute='submit_date')
|
SourceColumn(source=Comment, label=_('Date'), attribute='submit_date')
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Comment, label=_('User'),
|
source=Comment, label=_('User'),
|
||||||
attribute=encapsulate(
|
func=lambda context: context['object'].user.get_full_name() if context['object'].user.get_full_name() else context['object'].user
|
||||||
lambda x: x.user.get_full_name() if x.user.get_full_name() else x.user
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
SourceColumn(source=Comment, label=_('Comment'), attribute='comment')
|
SourceColumn(source=Comment, label=_('Comment'), attribute='comment')
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,12 @@ from common import (
|
|||||||
MayanAppConfig, menu_facet, menu_main, menu_object, menu_secondary,
|
MayanAppConfig, menu_facet, menu_main, menu_object, menu_secondary,
|
||||||
menu_setup, menu_tools
|
menu_setup, menu_tools
|
||||||
)
|
)
|
||||||
|
from common.widgets import two_state_template
|
||||||
from documents.models import Document
|
from documents.models import Document
|
||||||
from documents.signals import post_document_created
|
from documents.signals import post_document_created
|
||||||
from mayan.celery import app
|
from mayan.celery import app
|
||||||
from metadata.models import DocumentMetadata
|
from metadata.models import DocumentMetadata
|
||||||
|
from navigation import SourceColumn
|
||||||
from rest_api.classes import APIEndPoint
|
from rest_api.classes import APIEndPoint
|
||||||
|
|
||||||
from .handlers import (
|
from .handlers import (
|
||||||
@@ -27,7 +29,11 @@ from .links import (
|
|||||||
link_template_node_create, link_template_node_delete,
|
link_template_node_create, link_template_node_delete,
|
||||||
link_template_node_edit
|
link_template_node_edit
|
||||||
)
|
)
|
||||||
from .models import Index, IndexTemplateNode
|
from .models import (
|
||||||
|
DocumentIndexInstanceNode, Index, IndexInstance, IndexInstanceNode,
|
||||||
|
IndexTemplateNode
|
||||||
|
)
|
||||||
|
from .widgets import get_breadcrumbs, index_instance_item_link, node_level
|
||||||
|
|
||||||
|
|
||||||
class DocumentIndexingApp(MayanAppConfig):
|
class DocumentIndexingApp(MayanAppConfig):
|
||||||
@@ -41,6 +47,60 @@ class DocumentIndexingApp(MayanAppConfig):
|
|||||||
|
|
||||||
APIEndPoint(app=self, version_string='1')
|
APIEndPoint(app=self, version_string='1')
|
||||||
|
|
||||||
|
SourceColumn(source=Index, label=_('Label'), attribute='label')
|
||||||
|
SourceColumn(source=Index, label=_('Slug'), attribute='slug')
|
||||||
|
SourceColumn(
|
||||||
|
source=Index, label=_('Enabled'),
|
||||||
|
func=lambda context: two_state_template(context['object'].enabled)
|
||||||
|
)
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=IndexInstance, label=_('Items'),
|
||||||
|
func=lambda context: context['object'].get_items_count(
|
||||||
|
user=context['request'].user
|
||||||
|
)
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=IndexInstance, label=_('Document types'), attribute='get_document_types_names'
|
||||||
|
)
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=IndexTemplateNode, label=_('Level'),
|
||||||
|
func=lambda context: node_level(context['object'])
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=IndexTemplateNode, label=_('Enabled'),
|
||||||
|
func=lambda context: two_state_template(context['object'].enabled)
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=IndexTemplateNode, label=_('Has document links?'),
|
||||||
|
func=lambda context: two_state_template(context['object'].link_documents)
|
||||||
|
)
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=IndexInstanceNode, label=_('Node'),
|
||||||
|
func=lambda context: index_instance_item_link(context['object'])
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=IndexInstanceNode, label=_('Items'),
|
||||||
|
func=lambda context: context['object'].get_item_count(
|
||||||
|
user=context['request'].user
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=DocumentIndexInstanceNode, label=_('Node'),
|
||||||
|
func=lambda context: get_breadcrumbs(
|
||||||
|
index_instance_node=context['object'], single_link=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=DocumentIndexInstanceNode, label=_('Items'),
|
||||||
|
func=lambda context: context['object'].get_item_count(
|
||||||
|
user=context['request'].user
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
app.conf.CELERY_QUEUES.append(
|
app.conf.CELERY_QUEUES.append(
|
||||||
Queue('indexing', Exchange('indexing'), routing_key='indexing'),
|
Queue('indexing', Exchange('indexing'), routing_key='indexing'),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
@@ -8,7 +9,10 @@ from django.utils.translation import ugettext, ugettext_lazy as _
|
|||||||
from mptt.fields import TreeForeignKey
|
from mptt.fields import TreeForeignKey
|
||||||
from mptt.models import MPTTModel
|
from mptt.models import MPTTModel
|
||||||
|
|
||||||
|
from acls.models import AccessControlList
|
||||||
from documents.models import Document, DocumentType
|
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 IndexManager, IndexInstanceNodeManager
|
||||||
|
|
||||||
@@ -58,7 +62,10 @@ class Index(models.Model):
|
|||||||
return '#'
|
return '#'
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
"""Automatically create the root index template node"""
|
"""
|
||||||
|
Automatically create the root index template node
|
||||||
|
"""
|
||||||
|
|
||||||
super(Index, self).save(*args, **kwargs)
|
super(Index, self).save(*args, **kwargs)
|
||||||
IndexTemplateNode.objects.get_or_create(parent=None, index=self)
|
IndexTemplateNode.objects.get_or_create(parent=None, index=self)
|
||||||
|
|
||||||
@@ -67,15 +74,28 @@ class Index(models.Model):
|
|||||||
[unicode(document_type) for document_type in self.document_types.all()] or ['None']
|
[unicode(document_type) for document_type in self.document_types.all()] or ['None']
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('Index')
|
||||||
|
verbose_name_plural = _('Indexes')
|
||||||
|
|
||||||
|
|
||||||
|
class IndexInstance(Index):
|
||||||
def get_instance_node_count(self):
|
def get_instance_node_count(self):
|
||||||
try:
|
try:
|
||||||
return self.instance_root.get_descendant_count()
|
return self.instance_root.get_descendant_count()
|
||||||
except IndexInstanceNode.DoesNotExist:
|
except IndexInstanceNode.DoesNotExist:
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
def get_items_count(self, user):
|
||||||
|
try:
|
||||||
|
return self.instance_root.get_item_count(user=user)
|
||||||
|
except IndexInstanceNode.DoesNotExist:
|
||||||
|
return 0
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('Index')
|
proxy = True
|
||||||
verbose_name_plural = _('Indexes')
|
verbose_name = _('Index instance')
|
||||||
|
verbose_name_plural = _('Index instances')
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
@@ -140,9 +160,6 @@ class IndexInstanceNode(MPTTModel):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.value
|
return self.value
|
||||||
|
|
||||||
def index(self):
|
|
||||||
return self.index_template_node.index
|
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('indexing:index_instance_node_view', args=[self.pk])
|
return reverse('indexing:index_instance_node_view', args=[self.pk])
|
||||||
|
|
||||||
@@ -151,6 +168,38 @@ class IndexInstanceNode(MPTTModel):
|
|||||||
# Convenience method for serializer
|
# Convenience method for serializer
|
||||||
return self.get_children()
|
return self.get_children()
|
||||||
|
|
||||||
|
def index(self):
|
||||||
|
return self.index_template_node.index
|
||||||
|
|
||||||
|
def get_item_count(self, user):
|
||||||
|
if self.index_template_node.link_documents:
|
||||||
|
queryset = self.documents
|
||||||
|
|
||||||
|
try:
|
||||||
|
Permission.check_permissions(user, (permission_document_view,))
|
||||||
|
except PermissionDenied:
|
||||||
|
queryset = AccessControlList.objects.filter_by_access(
|
||||||
|
permission_document_view, user, queryset
|
||||||
|
)
|
||||||
|
|
||||||
|
return queryset.count()
|
||||||
|
else:
|
||||||
|
return self.get_children().count()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('Index node instance')
|
verbose_name = _('Index node instance')
|
||||||
verbose_name_plural = _('Indexes node instances')
|
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()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
verbose_name = _('Document index node instance')
|
||||||
|
verbose_name_plural = _('Document indexes node instances')
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ from django.utils.html import mark_safe
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from acls.models import AccessControlList
|
from acls.models import AccessControlList
|
||||||
from common.utils import encapsulate
|
|
||||||
from common.views import (
|
from common.views import (
|
||||||
AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView,
|
AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView,
|
||||||
SingleObjectEditView, SingleObjectListView
|
SingleObjectEditView, SingleObjectListView
|
||||||
@@ -23,7 +22,10 @@ from documents.views import DocumentListView
|
|||||||
from permissions import Permission
|
from permissions import Permission
|
||||||
|
|
||||||
from .forms import IndexTemplateNodeForm
|
from .forms import IndexTemplateNodeForm
|
||||||
from .models import Index, IndexInstanceNode, IndexTemplateNode
|
from .models import (
|
||||||
|
DocumentIndexInstanceNode, Index, IndexInstance, IndexInstanceNode,
|
||||||
|
IndexTemplateNode
|
||||||
|
)
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
permission_document_indexing_create, permission_document_indexing_delete,
|
permission_document_indexing_create, permission_document_indexing_delete,
|
||||||
permission_document_indexing_edit,
|
permission_document_indexing_edit,
|
||||||
@@ -49,17 +51,8 @@ class SetupIndexListView(SingleObjectListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'title': _('Indexes'),
|
|
||||||
'hide_object': True,
|
'hide_object': True,
|
||||||
'extra_columns': [
|
'title': _('Indexes'),
|
||||||
{'name': _('Label'), 'attribute': 'label'},
|
|
||||||
{'name': _('Slug'), 'attribute': 'slug'},
|
|
||||||
{
|
|
||||||
'name': _('Enabled'), 'attribute': encapsulate(
|
|
||||||
lambda x: two_state_template(x.enabled)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -71,8 +64,8 @@ class SetupIndexEditView(SingleObjectEditView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'title': _('Edit index: %s') % self.get_object(),
|
|
||||||
'object': self.get_object(),
|
'object': self.get_object(),
|
||||||
|
'title': _('Edit index: %s') % self.get_object(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -83,8 +76,8 @@ class SetupIndexDeleteView(SingleObjectDeleteView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'title': _('Delete the index: %s?') % self.get_object(),
|
|
||||||
'object': self.get_object(),
|
'object': self.get_object(),
|
||||||
|
'title': _('Delete the index: %s?') % self.get_object(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -99,23 +92,6 @@ class SetupIndexTreeTemplateListView(SingleObjectListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': (
|
|
||||||
{
|
|
||||||
'name': _('Level'), 'attribute': encapsulate(
|
|
||||||
lambda node: node_level(node)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': _('Enabled'), 'attribute': encapsulate(
|
|
||||||
lambda node: two_state_template(node.enabled)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': _('Has document links?'), 'attribute': encapsulate(
|
|
||||||
lambda node: two_state_template(node.link_documents)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
'hide_object': True,
|
'hide_object': True,
|
||||||
'index': self.get_index(),
|
'index': self.get_index(),
|
||||||
'navigation_object_list': ('index',),
|
'navigation_object_list': ('index',),
|
||||||
@@ -276,54 +252,17 @@ def template_node_delete(request, node_pk):
|
|||||||
|
|
||||||
|
|
||||||
class IndexListView(SingleObjectListView):
|
class IndexListView(SingleObjectListView):
|
||||||
@staticmethod
|
|
||||||
def get_items_count(instance):
|
|
||||||
try:
|
|
||||||
if instance.template_root.link_documents:
|
|
||||||
return instance.instance_root.documents.count()
|
|
||||||
else:
|
|
||||||
return instance.instance_root.get_children().count()
|
|
||||||
except IndexInstanceNode.DoesNotExist:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
queryset = Index.objects.filter(enabled=True)
|
|
||||||
object_permission = permission_document_indexing_view
|
object_permission = permission_document_indexing_view
|
||||||
|
queryset = IndexInstance.objects.filter(enabled=True)
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'title': _('Indexes'),
|
|
||||||
'hide_links': True,
|
'hide_links': True,
|
||||||
'extra_columns': [
|
'title': _('Indexes'),
|
||||||
{
|
|
||||||
'name': _('Items'), 'attribute': encapsulate(
|
|
||||||
lambda instance: IndexListView.get_items_count(instance)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': _('Document types'),
|
|
||||||
'attribute': 'get_document_types_names'
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class IndexInstanceNodeView(DocumentListView, SingleObjectListView):
|
class IndexInstanceNodeView(DocumentListView, SingleObjectListView):
|
||||||
@staticmethod
|
|
||||||
def get_item_count(instance, user):
|
|
||||||
if instance.index_template_node.link_documents:
|
|
||||||
queryset = instance.documents
|
|
||||||
|
|
||||||
try:
|
|
||||||
Permission.check_permissions(user, (permission_document_view,))
|
|
||||||
except PermissionDenied:
|
|
||||||
queryset = AccessControlList.objects.filter_by_access(
|
|
||||||
permission_document_view, user, queryset
|
|
||||||
)
|
|
||||||
|
|
||||||
return queryset.count()
|
|
||||||
else:
|
|
||||||
return instance.get_children().count()
|
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
self.index_instance = get_object_or_404(
|
self.index_instance = get_object_or_404(
|
||||||
IndexInstanceNode, pk=self.kwargs['pk']
|
IndexInstanceNode, pk=self.kwargs['pk']
|
||||||
@@ -371,25 +310,7 @@ class IndexInstanceNodeView(DocumentListView, SingleObjectListView):
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.index_instance and not self.index_instance.index_template_node.link_documents:
|
if self.index_instance and not self.index_instance.index_template_node.link_documents:
|
||||||
context.update(
|
context.update({'hide_object': True})
|
||||||
{
|
|
||||||
'extra_columns': [
|
|
||||||
{
|
|
||||||
'name': _('Node'),
|
|
||||||
'attribute': encapsulate(
|
|
||||||
lambda x: index_instance_item_link(x)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': _('Items'),
|
|
||||||
'attribute': encapsulate(
|
|
||||||
lambda instance: IndexInstanceNodeView.get_item_count(instance=instance, user=self.request.user)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
],
|
|
||||||
'hide_object': True,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
@@ -446,16 +367,6 @@ class DocumentIndexNodeListView(SingleObjectListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': (
|
|
||||||
{
|
|
||||||
'name': _('Node'),
|
|
||||||
'attribute': encapsulate(
|
|
||||||
lambda node: get_breadcrumbs(
|
|
||||||
index_instance_node=node, single_link=True, include_count=True
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
'hide_object': True,
|
'hide_object': True,
|
||||||
'object': self.get_document(),
|
'object': self.get_document(),
|
||||||
'title': _(
|
'title': _(
|
||||||
@@ -464,4 +375,4 @@ class DocumentIndexNodeListView(SingleObjectListView):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return self.get_document().node_instances.all()
|
return DocumentIndexInstanceNode.objects.get_for(self.get_document())
|
||||||
|
|||||||
@@ -7,22 +7,6 @@ from django.utils.translation import ugettext
|
|||||||
from .models import IndexInstanceNode
|
from .models import IndexInstanceNode
|
||||||
|
|
||||||
|
|
||||||
def index_instance_item_link(index_instance_item):
|
|
||||||
if isinstance(index_instance_item, IndexInstanceNode):
|
|
||||||
if index_instance_item.index_template_node.link_documents:
|
|
||||||
icon_template = '<i class="fa fa-folder"></i>'
|
|
||||||
else:
|
|
||||||
icon_template = '<i class="fa fa-level-up fa-rotate-90"></i>'
|
|
||||||
else:
|
|
||||||
icon_template = ''
|
|
||||||
|
|
||||||
return mark_safe('%(icon_template)s <a href="%(url)s">%(text)s</a>' % {
|
|
||||||
'url': index_instance_item.get_absolute_url(),
|
|
||||||
'icon_template': icon_template,
|
|
||||||
'text': index_instance_item
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
def get_instance_link(index_instance_node, text=None, simple=False):
|
def get_instance_link(index_instance_node, text=None, simple=False):
|
||||||
"""
|
"""
|
||||||
Return an HTML anchor to an index instance
|
Return an HTML anchor to an index instance
|
||||||
@@ -75,6 +59,22 @@ def get_breadcrumbs(index_instance_node, simple=False, single_link=False, includ
|
|||||||
return mark_safe(' '.join(output))
|
return mark_safe(' '.join(output))
|
||||||
|
|
||||||
|
|
||||||
|
def index_instance_item_link(index_instance_item):
|
||||||
|
if isinstance(index_instance_item, IndexInstanceNode):
|
||||||
|
if index_instance_item.index_template_node.link_documents:
|
||||||
|
icon_template = '<i class="fa fa-folder"></i>'
|
||||||
|
else:
|
||||||
|
icon_template = '<i class="fa fa-level-up fa-rotate-90"></i>'
|
||||||
|
else:
|
||||||
|
icon_template = ''
|
||||||
|
|
||||||
|
return mark_safe('%(icon_template)s <a href="%(url)s">%(text)s</a>' % {
|
||||||
|
'url': index_instance_item.get_absolute_url(),
|
||||||
|
'icon_template': icon_template,
|
||||||
|
'text': index_instance_item
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def node_level(node):
|
def node_level(node):
|
||||||
"""
|
"""
|
||||||
Render an indented tree like output for a specific node
|
Render an indented tree like output for a specific node
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from common import (
|
|||||||
MayanAppConfig, menu_facet, menu_object, menu_secondary, menu_setup,
|
MayanAppConfig, menu_facet, menu_object, menu_secondary, menu_setup,
|
||||||
menu_sidebar
|
menu_sidebar
|
||||||
)
|
)
|
||||||
from common.utils import encapsulate
|
|
||||||
from common.widgets import two_state_template
|
from common.widgets import two_state_template
|
||||||
from documents.models import Document
|
from documents.models import Document
|
||||||
from navigation import SourceColumn
|
from navigation import SourceColumn
|
||||||
@@ -39,9 +38,7 @@ class DocumentStatesApp(MayanAppConfig):
|
|||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Workflow, label=_('Initial state'),
|
source=Workflow, label=_('Initial state'),
|
||||||
attribute=encapsulate(
|
func=lambda context: context['object'].get_initial_state() or _('None')
|
||||||
lambda workflow: workflow.get_initial_state() or _('None')
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
@@ -50,10 +47,8 @@ class DocumentStatesApp(MayanAppConfig):
|
|||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=WorkflowInstance, label=_('User'),
|
source=WorkflowInstance, label=_('User'),
|
||||||
attribute=encapsulate(
|
func=lambda context: getattr(
|
||||||
lambda workflow: getattr(
|
context['object'].get_last_log_entry(), 'user', _('None')
|
||||||
workflow.get_last_log_entry(), 'user', _('None')
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
@@ -62,16 +57,14 @@ class DocumentStatesApp(MayanAppConfig):
|
|||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=WorkflowInstance, label=_('Date and time'),
|
source=WorkflowInstance, label=_('Date and time'),
|
||||||
attribute=encapsulate(
|
func=lambda context: getattr(
|
||||||
lambda workflow: getattr(
|
context['object'].get_last_log_entry(), 'datetime', _('None')
|
||||||
workflow.get_last_log_entry(), 'datetime', _('None')
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=WorkflowInstance, label=_('Completion'),
|
source=WorkflowInstance, label=_('Completion'),
|
||||||
attribute=encapsulate(lambda workflow: getattr(
|
func=lambda context: getattr(
|
||||||
workflow.get_current_state(), 'completion', _('None'))
|
context['object'].get_current_state(), 'completion', _('None')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -93,9 +86,7 @@ class DocumentStatesApp(MayanAppConfig):
|
|||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=WorkflowState, label=_('Is initial state?'),
|
source=WorkflowState, label=_('Is initial state?'),
|
||||||
attribute=encapsulate(
|
func=lambda context: two_state_template(context['object'].initial)
|
||||||
lambda state: two_state_template(state.initial)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=WorkflowState, label=_('Completion'), attribute='completion'
|
source=WorkflowState, label=_('Completion'), attribute='completion'
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ from common import (
|
|||||||
)
|
)
|
||||||
from common.classes import ModelAttribute
|
from common.classes import ModelAttribute
|
||||||
from common.signals import post_initial_setup
|
from common.signals import post_initial_setup
|
||||||
from common.utils import encapsulate
|
from common.widgets import two_state_template
|
||||||
from converter.links import link_transformation_list
|
from converter.links import link_transformation_list
|
||||||
from converter.permissions import (
|
from converter.permissions import (
|
||||||
permission_transformation_create,
|
permission_transformation_create,
|
||||||
@@ -125,17 +125,27 @@ class DocumentsApp(MayanAppConfig):
|
|||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Document, label=_('Thumbnail'),
|
source=Document, label=_('Thumbnail'),
|
||||||
attribute=encapsulate(
|
func=lambda context: document_thumbnail(
|
||||||
lambda document: document_thumbnail(
|
context['object'], gallery_name='documents:document_list',
|
||||||
document, gallery_name='documents:document_list',
|
|
||||||
size=setting_thumbnail_size.value,
|
size=setting_thumbnail_size.value,
|
||||||
title=getattr(document, 'label', None),
|
title=getattr(context['object'], 'label', None),
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Document, label=_('Type'), attribute='document_type'
|
source=Document, label=_('Type'), attribute='document_type'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TODO: make permission aware
|
||||||
|
SourceColumn(
|
||||||
|
source=DocumentType, label=_('Documents'),
|
||||||
|
func=lambda context: context['object'].documents.count()
|
||||||
|
)
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=DocumentTypeFilename, label=_('Enabled'),
|
||||||
|
func=lambda context: two_state_template(context['object'].enabled)
|
||||||
|
)
|
||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=DeletedDocument, label=_('Type'), attribute='document_type'
|
source=DeletedDocument, label=_('Type'), attribute='document_type'
|
||||||
)
|
)
|
||||||
@@ -144,6 +154,23 @@ class DocumentsApp(MayanAppConfig):
|
|||||||
attribute='deleted_date_time'
|
attribute='deleted_date_time'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=DocumentVersion, label=_('Time and date'),
|
||||||
|
attribute='timestamp'
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=DocumentVersion, label=_('MIME type'),
|
||||||
|
attribute='mimetype'
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=DocumentVersion, label=_('Encoding'),
|
||||||
|
attribute='encoding'
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=DocumentVersion, label=_('Comment'),
|
||||||
|
attribute='comment'
|
||||||
|
)
|
||||||
|
|
||||||
app.conf.CELERYBEAT_SCHEDULE.update(
|
app.conf.CELERYBEAT_SCHEDULE.update(
|
||||||
{
|
{
|
||||||
'task_check_delete_periods': {
|
'task_check_delete_periods': {
|
||||||
|
|||||||
@@ -954,9 +954,6 @@ class DocumentTypeListView(SingleObjectListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': [
|
|
||||||
{'name': _('Documents'), 'attribute': encapsulate(lambda document_type: document_type.documents.count())}
|
|
||||||
],
|
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
'title': _('Document types'),
|
'title': _('Document types'),
|
||||||
}
|
}
|
||||||
@@ -1010,12 +1007,6 @@ class DocumentTypeFilenameListView(SingleObjectListView):
|
|||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'document_type': self.get_document_type(),
|
'document_type': self.get_document_type(),
|
||||||
'extra_columns': (
|
|
||||||
{
|
|
||||||
'name': _('Enabled'),
|
|
||||||
'attribute': encapsulate(lambda filename: two_state_template(filename.enabled)),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
'navigation_object_list': ('document_type',),
|
'navigation_object_list': ('document_type',),
|
||||||
'title': _('Filenames for document type: %s') % self.get_document_type(),
|
'title': _('Filenames for document type: %s') % self.get_document_type(),
|
||||||
@@ -1148,12 +1139,7 @@ class DocumentVersionListView(SingleObjectListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': (
|
'hide_object': True, 'object': self.get_document(),
|
||||||
{'name': _('Time and date'), 'attribute': 'timestamp'},
|
|
||||||
{'name': _('MIME type'), 'attribute': 'mimetype'},
|
|
||||||
{'name': _('Encoding'), 'attribute': 'encoding'},
|
|
||||||
{'name': _('Comment'), 'attribute': 'comment'},
|
|
||||||
), 'hide_object': True, 'object': self.get_document(),
|
|
||||||
'title': _('Versions of document: %s') % self.get_document(),
|
'title': _('Versions of document: %s') % self.get_document(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
from actstream.models import Action
|
from actstream.models import Action
|
||||||
|
|
||||||
from common import MayanAppConfig, menu_tools
|
from common import MayanAppConfig, menu_tools
|
||||||
from common.utils import encapsulate
|
|
||||||
from navigation import SourceColumn
|
from navigation import SourceColumn
|
||||||
|
|
||||||
from .links import link_events_list
|
from .links import link_events_list
|
||||||
@@ -21,8 +20,8 @@ class EventsApp(MayanAppConfig):
|
|||||||
|
|
||||||
SourceColumn(source=Action, label=_('Timestamp'), attribute='timestamp')
|
SourceColumn(source=Action, label=_('Timestamp'), attribute='timestamp')
|
||||||
SourceColumn(source=Action, label=_('Actor'), attribute='actor')
|
SourceColumn(source=Action, label=_('Actor'), attribute='actor')
|
||||||
SourceColumn(source=Action, label=_('Verb'), attribute=encapsulate(
|
SourceColumn(source=Action, label=_('Verb'),
|
||||||
lambda entry: event_type_link(entry))
|
func=lambda context: event_type_link(context['object'])
|
||||||
)
|
)
|
||||||
|
|
||||||
menu_tools.bind_links(links=[link_events_list])
|
menu_tools.bind_links(links=[link_events_list])
|
||||||
|
|||||||
@@ -26,14 +26,14 @@ class EventListView(SingleObjectListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': [
|
'extra_columns': (
|
||||||
{
|
{
|
||||||
'name': _('Target'),
|
'name': _('Target'),
|
||||||
'attribute': encapsulate(
|
'attribute': encapsulate(
|
||||||
lambda entry: event_object_link(entry)
|
lambda entry: event_object_link(entry)
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
],
|
),
|
||||||
'hide_object': True,
|
'hide_object': True,
|
||||||
'title': _('Events'),
|
'title': _('Events'),
|
||||||
}
|
}
|
||||||
@@ -85,14 +85,14 @@ class VerbEventListView(SingleObjectListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': [
|
'extra_columns': (
|
||||||
{
|
{
|
||||||
'name': _('Target'),
|
'name': _('Target'),
|
||||||
'attribute': encapsulate(
|
'attribute': encapsulate(
|
||||||
lambda entry: event_object_link(entry)
|
lambda entry: event_object_link(entry)
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
],
|
),
|
||||||
'hide_object': True,
|
'hide_object': True,
|
||||||
'title': _(
|
'title': _(
|
||||||
'Events of type: %s'
|
'Events of type: %s'
|
||||||
|
|||||||
@@ -56,6 +56,12 @@ class FoldersApp(MayanAppConfig):
|
|||||||
source=Folder, label=_('Created'), attribute='datetime_created'
|
source=Folder, label=_('Created'), attribute='datetime_created'
|
||||||
)
|
)
|
||||||
SourceColumn(source=Folder, label=_('User'), attribute='user')
|
SourceColumn(source=Folder, label=_('User'), attribute='user')
|
||||||
|
SourceColumn(
|
||||||
|
source=Folder, label=_('Documents'),
|
||||||
|
func=lambda context: context['object'].get_document_count(
|
||||||
|
user=context['request'].user
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
menu_facet.bind_links(
|
menu_facet.bind_links(
|
||||||
links=(link_document_folder_list,), sources=(Document,)
|
links=(link_document_folder_list,), sources=(Document,)
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from acls.models import AccessControlList
|
||||||
from documents.models import Document
|
from documents.models import Document
|
||||||
|
from documents.permissions import permission_document_view
|
||||||
|
from permissions import Permission
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
@@ -28,6 +32,18 @@ class Folder(models.Model):
|
|||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse('folders:folder_view', args=[self.pk])
|
return reverse('folders:folder_view', args=[self.pk])
|
||||||
|
|
||||||
|
def get_document_count(self, user):
|
||||||
|
queryset = self.documents
|
||||||
|
|
||||||
|
try:
|
||||||
|
Permission.check_permissions(user, (permission_document_view,))
|
||||||
|
except PermissionDenied:
|
||||||
|
queryset = AccessControlList.objects.filter_by_access(
|
||||||
|
permission_document_view, user, queryset
|
||||||
|
)
|
||||||
|
|
||||||
|
return queryset.count()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('label',)
|
ordering = ('label',)
|
||||||
unique_together = ('label', 'user')
|
unique_together = ('label', 'user')
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ from django.template import RequestContext
|
|||||||
from django.utils.translation import ugettext_lazy as _, ungettext
|
from django.utils.translation import ugettext_lazy as _, ungettext
|
||||||
|
|
||||||
from acls.models import AccessControlList
|
from acls.models import AccessControlList
|
||||||
from common.utils import encapsulate
|
|
||||||
from common.views import (
|
from common.views import (
|
||||||
SingleObjectCreateView, SingleObjectEditView, SingleObjectListView
|
SingleObjectCreateView, SingleObjectEditView, SingleObjectListView
|
||||||
)
|
)
|
||||||
@@ -48,31 +47,8 @@ class FolderEditView(SingleObjectEditView):
|
|||||||
class FolderListView(SingleObjectListView):
|
class FolderListView(SingleObjectListView):
|
||||||
object_permission = permission_folder_view
|
object_permission = permission_folder_view
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_document_count(instance, user):
|
|
||||||
queryset = instance.documents
|
|
||||||
|
|
||||||
try:
|
|
||||||
Permission.check_permissions(user, (permission_document_view,))
|
|
||||||
except PermissionDenied:
|
|
||||||
queryset = AccessControlList.objects.filter_by_access(
|
|
||||||
permission_document_view, user, queryset
|
|
||||||
)
|
|
||||||
|
|
||||||
return queryset.count()
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': [
|
|
||||||
{
|
|
||||||
'name': _('Documents'),
|
|
||||||
'attribute': encapsulate(
|
|
||||||
lambda instance: FolderListView.get_document_count(
|
|
||||||
instance=instance, user=self.request.user
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
'title': _('Folders'),
|
'title': _('Folders'),
|
||||||
}
|
}
|
||||||
@@ -253,16 +229,6 @@ class DocumentFolderListView(FolderListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': [
|
|
||||||
{
|
|
||||||
'name': _('Documents'),
|
|
||||||
'attribute': encapsulate(
|
|
||||||
lambda instance: FolderListView.get_document_count(
|
|
||||||
instance=instance, user=self.request.user
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
'object': self.document,
|
'object': self.document,
|
||||||
'title': _('Folders containing document: %s') % self.document,
|
'title': _('Folders containing document: %s') % self.document,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ from __future__ import unicode_literals
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from common import MayanAppConfig, menu_tools, menu_object, menu_secondary
|
from common import MayanAppConfig, menu_tools, menu_object, menu_secondary
|
||||||
from common.utils import encapsulate
|
|
||||||
from navigation import SourceColumn
|
from navigation import SourceColumn
|
||||||
|
|
||||||
from .classes import Property, PropertyNamespace, PIPNotFound, VirtualEnv
|
from .classes import Property, PropertyNamespace, PIPNotFound, VirtualEnv
|
||||||
@@ -24,7 +23,7 @@ class InstallationApp(MayanAppConfig):
|
|||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=PropertyNamespace, label=_('Items'),
|
source=PropertyNamespace, label=_('Items'),
|
||||||
attribute=encapsulate(lambda entry: len(entry.get_properties()))
|
func=lambda context: len(context['object'].get_properties())
|
||||||
)
|
)
|
||||||
|
|
||||||
SourceColumn(source=Property, label=_('Label'), attribute='label')
|
SourceColumn(source=Property, label=_('Label'), attribute='label')
|
||||||
|
|||||||
@@ -9,7 +9,9 @@ from common import (
|
|||||||
MayanAppConfig, menu_facet, menu_object, menu_secondary, menu_setup,
|
MayanAppConfig, menu_facet, menu_object, menu_secondary, menu_setup,
|
||||||
menu_sidebar
|
menu_sidebar
|
||||||
)
|
)
|
||||||
|
from common.widgets import two_state_template
|
||||||
from documents.models import Document
|
from documents.models import Document
|
||||||
|
from navigation import SourceColumn
|
||||||
|
|
||||||
from .links import (
|
from .links import (
|
||||||
link_smart_link_create, link_smart_link_condition_create,
|
link_smart_link_create, link_smart_link_condition_create,
|
||||||
@@ -41,6 +43,26 @@ class LinkingApp(MayanAppConfig):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=ResolvedSmartLink, label=_('Label'),
|
||||||
|
func=lambda context: context['object'].get_dynamic_label(
|
||||||
|
context['resolved_object']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=SmartLink, label=_('Dynamic label'), attribute='dynamic_label'
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=SmartLink, label=_('Enabled'),
|
||||||
|
func=lambda context: two_state_template(context['object'].enabled)
|
||||||
|
)
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=SmartLinkCondition, label=_('Enabled'),
|
||||||
|
func=lambda context: two_state_template(context['object'].enabled)
|
||||||
|
)
|
||||||
|
|
||||||
menu_facet.bind_links(
|
menu_facet.bind_links(
|
||||||
links=(link_smart_link_instances_for_document,),
|
links=(link_smart_link_instances_for_document,),
|
||||||
sources=(Document,)
|
sources=(Document,)
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ from django.template import RequestContext
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from acls.models import AccessControlList
|
from acls.models import AccessControlList
|
||||||
from common.utils import encapsulate
|
|
||||||
from common.generics import (
|
from common.generics import (
|
||||||
AssignRemoveView, SingleObjectCreateView, SingleObjectEditView,
|
AssignRemoveView, SingleObjectCreateView, SingleObjectEditView,
|
||||||
SingleObjectListView
|
SingleObjectListView
|
||||||
@@ -145,14 +144,6 @@ class SmartLinkListView(SingleObjectListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': [
|
|
||||||
{'name': _('Dynamic label'), 'attribute': 'dynamic_label'},
|
|
||||||
{
|
|
||||||
'name': _('Enabled'), 'attribute': encapsulate(
|
|
||||||
lambda instance: two_state_template(instance.enabled)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
'title': _('Smart links'),
|
'title': _('Smart links'),
|
||||||
}
|
}
|
||||||
@@ -183,15 +174,6 @@ class DocumentSmartLinkListView(SmartLinkListView):
|
|||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'document': self.document,
|
'document': self.document,
|
||||||
'extra_columns': (
|
|
||||||
{
|
|
||||||
'name': _('Label'), 'attribute': encapsulate(
|
|
||||||
lambda smart_link: smart_link.get_dynamic_label(
|
|
||||||
self.document
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
'hide_object': True,
|
'hide_object': True,
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
'object': self.document,
|
'object': self.document,
|
||||||
@@ -272,17 +254,9 @@ class SmartLinkConditionListView(SingleObjectListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'title': _('Conditions for smart link: %s') % self.get_smart_link(),
|
|
||||||
'extra_columns': (
|
|
||||||
{
|
|
||||||
'name': _('Enabled'),
|
|
||||||
'attribute': encapsulate(
|
|
||||||
lambda condition: two_state_template(condition.enabled)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
'object': self.get_smart_link(),
|
'object': self.get_smart_link(),
|
||||||
|
'title': _('Conditions for smart link: %s') % self.get_smart_link(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_smart_link(self):
|
def get_smart_link(self):
|
||||||
|
|||||||
@@ -28,15 +28,11 @@ class MailerApp(MayanAppConfig):
|
|||||||
super(MailerApp, self).ready()
|
super(MailerApp, self).ready()
|
||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=LogEntry,
|
source=LogEntry, label=_('Date and time'), attribute='datetime'
|
||||||
label='Date and time',
|
|
||||||
attribute='datetime'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=LogEntry,
|
source=LogEntry, label=_('Message'), attribute='message'
|
||||||
label='Message',
|
|
||||||
attribute='message'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
ModelPermission.register(
|
ModelPermission.register(
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ from common import (
|
|||||||
menu_setup, menu_sidebar, menu_tools
|
menu_setup, menu_sidebar, menu_tools
|
||||||
)
|
)
|
||||||
from common.classes import ModelAttribute
|
from common.classes import ModelAttribute
|
||||||
from common.utils import encapsulate
|
from common.widgets import two_state_template
|
||||||
from documents.models import Document, DocumentType
|
from documents.models import Document, DocumentType
|
||||||
from documents.search import document_search
|
from documents.search import document_search
|
||||||
from documents.signals import post_document_type_change
|
from documents.signals import post_document_type_change
|
||||||
@@ -38,7 +38,7 @@ from .links import (
|
|||||||
link_setup_metadata_type_edit, link_setup_metadata_type_list,
|
link_setup_metadata_type_edit, link_setup_metadata_type_list,
|
||||||
link_documents_missing_required_metadata
|
link_documents_missing_required_metadata
|
||||||
)
|
)
|
||||||
from .models import DocumentTypeMetadataType, MetadataType
|
from .models import DocumentMetadata, DocumentTypeMetadataType, MetadataType
|
||||||
from .permissions import (
|
from .permissions import (
|
||||||
permission_metadata_document_add, permission_metadata_document_edit,
|
permission_metadata_document_add, permission_metadata_document_edit,
|
||||||
permission_metadata_document_remove, permission_metadata_document_view
|
permission_metadata_document_remove, permission_metadata_document_view
|
||||||
@@ -94,9 +94,16 @@ class MetadataApp(MayanAppConfig):
|
|||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Document, label=_('Metadata'),
|
source=Document, label=_('Metadata'),
|
||||||
attribute=encapsulate(
|
func=lambda context: get_metadata_string(context['object'])
|
||||||
lambda document: get_metadata_string(document)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=DocumentMetadata, label=_('Value'),
|
||||||
|
attribute='value'
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=DocumentMetadata, label=_('Required'),
|
||||||
|
func=lambda context: two_state_template(context['object'].is_required)
|
||||||
)
|
)
|
||||||
|
|
||||||
app.conf.CELERY_QUEUES.append(
|
app.conf.CELERY_QUEUES.append(
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ class DocumentMetadata(models.Model):
|
|||||||
|
|
||||||
return super(DocumentMetadata, self).delete(*args, **kwargs)
|
return super(DocumentMetadata, self).delete(*args, **kwargs)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_required(self):
|
||||||
|
return self.metadata_type in self.document.document_type.metadata.filter(required=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('document', 'metadata_type')
|
unique_together = ('document', 'metadata_type')
|
||||||
verbose_name = _('Document metadata')
|
verbose_name = _('Document metadata')
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ from django.utils.http import urlencode
|
|||||||
from django.utils.translation import ugettext_lazy as _, ungettext
|
from django.utils.translation import ugettext_lazy as _, ungettext
|
||||||
|
|
||||||
from acls.models import AccessControlList
|
from acls.models import AccessControlList
|
||||||
from common.utils import encapsulate
|
|
||||||
from common.generics import (
|
from common.generics import (
|
||||||
AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView,
|
AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView,
|
||||||
SingleObjectEditView, SingleObjectListView
|
SingleObjectEditView, SingleObjectListView
|
||||||
@@ -495,18 +494,9 @@ class DocumentMetadataListView(SingleObjectListView):
|
|||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
document = self.get_document()
|
document = self.get_document()
|
||||||
return {
|
return {
|
||||||
'title': _('Metadata for document: %s') % document,
|
|
||||||
'extra_columns': (
|
|
||||||
{'name': _('Value'), 'attribute': 'value'},
|
|
||||||
{
|
|
||||||
'name': _('Required'),
|
|
||||||
'attribute': encapsulate(
|
|
||||||
lambda metadata: metadata.metadata_type in document.document_type.metadata.filter(required=True)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
),
|
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
'object': document,
|
'object': document,
|
||||||
|
'title': _('Metadata for document: %s') % document,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
|||||||
@@ -281,11 +281,13 @@ class SourceColumn(object):
|
|||||||
# unhashable type: list
|
# unhashable type: list
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
def __init__(self, source, label, attribute):
|
def __init__(self, source, label, attribute=None, func=None):
|
||||||
|
self.source = source
|
||||||
|
self.label = label
|
||||||
|
self.attribute = attribute
|
||||||
|
self.func = func
|
||||||
self.__class__._registry.setdefault(source, [])
|
self.__class__._registry.setdefault(source, [])
|
||||||
self.__class__._registry[source].append(
|
self.__class__._registry[source].append(self)
|
||||||
{'label': label, 'attribute': attribute}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class CombinedSource(object):
|
class CombinedSource(object):
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.template import Library
|
from django.template import Library
|
||||||
|
|
||||||
|
from common.utils import return_attrib
|
||||||
|
|
||||||
from ..classes import Menu, SourceColumn
|
from ..classes import Menu, SourceColumn
|
||||||
from ..forms import MultiItemForm
|
from ..forms import MultiItemForm
|
||||||
|
|
||||||
@@ -58,3 +60,11 @@ def get_source_columns(source):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
return SourceColumn.get_for_source(source)
|
return SourceColumn.get_for_source(source)
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag(takes_context=True)
|
||||||
|
def source_column_resolve(context, column):
|
||||||
|
if column.attribute:
|
||||||
|
return return_attrib(context['object'], column.attribute)
|
||||||
|
elif column.func:
|
||||||
|
return column.func(context=context)
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ from common import (
|
|||||||
MayanAppConfig, menu_facet, menu_multi_item, menu_object, menu_secondary,
|
MayanAppConfig, menu_facet, menu_multi_item, menu_object, menu_secondary,
|
||||||
menu_tools
|
menu_tools
|
||||||
)
|
)
|
||||||
from common.utils import encapsulate
|
|
||||||
from documents.models import Document, DocumentType, DocumentVersion
|
from documents.models import Document, DocumentType, DocumentVersion
|
||||||
from documents.search import document_search
|
from documents.search import document_search
|
||||||
from documents.signals import post_version_upload
|
from documents.signals import post_version_upload
|
||||||
@@ -70,9 +69,7 @@ class OCRApp(MayanAppConfig):
|
|||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=DocumentVersionOCRError, label=_('Document'),
|
source=DocumentVersionOCRError, label=_('Document'),
|
||||||
attribute=encapsulate(
|
func=lambda context: document_link(context['object'].document_version.document)
|
||||||
lambda entry: document_link(entry.document_version.document)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=DocumentVersionOCRError, label=_('Added'),
|
source=DocumentVersionOCRError, label=_('Added'),
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from django.apps import apps
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from common import MayanAppConfig, menu_setup, menu_object
|
from common import MayanAppConfig, menu_setup, menu_object
|
||||||
from common.utils import encapsulate
|
|
||||||
from common.widgets import exists_widget
|
from common.widgets import exists_widget
|
||||||
from navigation import SourceColumn
|
from navigation import SourceColumn
|
||||||
|
|
||||||
@@ -29,20 +28,20 @@ class SmartSettingsApp(MayanAppConfig):
|
|||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Namespace, label=_('Setting count'),
|
source=Namespace, label=_('Setting count'),
|
||||||
attribute=encapsulate(lambda instance: len(instance.settings))
|
func=lambda context: len(context['object'].settings)
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Setting, label=_('Name'),
|
source=Setting, label=_('Name'),
|
||||||
attribute=encapsulate(lambda instance: setting_widget(instance))
|
func=lambda context: setting_widget(context['object'])
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Setting, label=_('Value'), attribute='serialized_value'
|
source=Setting, label=_('Value'), attribute='serialized_value'
|
||||||
)
|
)
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Setting, label=_('Found in path'),
|
source=Setting, label=_('Found in path'),
|
||||||
attribute=encapsulate(
|
func=lambda context: exists_widget(
|
||||||
lambda instance: exists_widget(instance.value) if instance.is_path else _('n/a')
|
context['object'].value
|
||||||
)
|
) if context['object'].is_path else _('n/a')
|
||||||
)
|
)
|
||||||
|
|
||||||
menu_object.bind_links(
|
menu_object.bind_links(
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ from common import (
|
|||||||
menu_sidebar, menu_setup
|
menu_sidebar, menu_setup
|
||||||
)
|
)
|
||||||
from common.signals import post_initial_setup, post_upgrade
|
from common.signals import post_initial_setup, post_upgrade
|
||||||
from common.utils import encapsulate
|
|
||||||
from converter.links import link_transformation_list
|
from converter.links import link_transformation_list
|
||||||
from documents.models import Document
|
from documents.models import Document
|
||||||
from documents.signals import post_version_upload
|
from documents.signals import post_version_upload
|
||||||
@@ -32,8 +31,8 @@ from .links import (
|
|||||||
link_upload_version
|
link_upload_version
|
||||||
)
|
)
|
||||||
from .models import (
|
from .models import (
|
||||||
POP3Email, IMAPEmail, Source, StagingFolderSource, WatchFolderSource,
|
POP3Email, IMAPEmail, Source, SourceLog, StagingFolderSource,
|
||||||
WebFormSource
|
WatchFolderSource, WebFormSource
|
||||||
)
|
)
|
||||||
from .widgets import staging_file_thumbnail
|
from .widgets import staging_file_thumbnail
|
||||||
|
|
||||||
@@ -61,13 +60,22 @@ class SourcesApp(MayanAppConfig):
|
|||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=StagingFile,
|
source=StagingFile,
|
||||||
label=_('Thumbnail'),
|
label=_('Thumbnail'),
|
||||||
attribute=encapsulate(
|
func=lambda context: staging_file_thumbnail(
|
||||||
lambda staging_file: staging_file_thumbnail(
|
context['object'],
|
||||||
staging_file,
|
|
||||||
gallery_name='sources:staging_list',
|
gallery_name='sources:staging_list',
|
||||||
title=staging_file.filename, size='100'
|
title=context['object'].filename, size='100'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=SourceLog,
|
||||||
|
label=_('Date time'),
|
||||||
|
func=lambda context: context['object'].datetime
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=SourceLog,
|
||||||
|
label=_('Message'),
|
||||||
|
func=lambda context: context['object'].message
|
||||||
)
|
)
|
||||||
|
|
||||||
app.conf.CELERY_QUEUES.extend(
|
app.conf.CELERY_QUEUES.extend(
|
||||||
|
|||||||
@@ -58,16 +58,6 @@ class SourceLogListView(SingleObjectListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': (
|
|
||||||
{
|
|
||||||
'name': _('Date time'),
|
|
||||||
'attribute': encapsulate(lambda entry: entry.datetime)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': _('Message'),
|
|
||||||
'attribute': encapsulate(lambda entry: entry.message)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
'hide_object': True,
|
'hide_object': True,
|
||||||
'object': self.get_source(),
|
'object': self.get_source(),
|
||||||
'title': _('Log entries for source: %s') % self.get_source(),
|
'title': _('Log entries for source: %s') % self.get_source(),
|
||||||
@@ -494,7 +484,7 @@ class SetupSourceListView(SingleObjectListView):
|
|||||||
queryset = Source.objects.select_subclasses()
|
queryset = Source.objects.select_subclasses()
|
||||||
|
|
||||||
extra_context = {
|
extra_context = {
|
||||||
'extra_columns': [
|
'extra_columns': (
|
||||||
{
|
{
|
||||||
'name': _('Type'),
|
'name': _('Type'),
|
||||||
'attribute': encapsulate(lambda entry: entry.class_fullname())
|
'attribute': encapsulate(lambda entry: entry.class_fullname())
|
||||||
@@ -505,7 +495,7 @@ class SetupSourceListView(SingleObjectListView):
|
|||||||
lambda entry: two_state_template(entry.enabled)
|
lambda entry: two_state_template(entry.enabled)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
],
|
),
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
'title': _('Sources'),
|
'title': _('Sources'),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ from common import (
|
|||||||
MayanAppConfig, menu_facet, menu_secondary, menu_object, menu_main,
|
MayanAppConfig, menu_facet, menu_secondary, menu_object, menu_main,
|
||||||
menu_multi_item, menu_sidebar
|
menu_multi_item, menu_sidebar
|
||||||
)
|
)
|
||||||
from common.utils import encapsulate
|
|
||||||
from documents.models import Document
|
from documents.models import Document
|
||||||
from documents.search import document_search
|
from documents.search import document_search
|
||||||
from navigation import CombinedSource, SourceColumn
|
from navigation import CombinedSource, SourceColumn
|
||||||
@@ -55,14 +54,18 @@ class TagsApp(MayanAppConfig):
|
|||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Document, label=_('Tags'),
|
source=Document, label=_('Tags'),
|
||||||
attribute=encapsulate(
|
func=lambda context: widget_inline_tags(context['object'])
|
||||||
lambda document: widget_inline_tags(document)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
SourceColumn(
|
SourceColumn(
|
||||||
source=Tag, label=_('Preview'),
|
source=Tag, label=_('Preview'),
|
||||||
attribute=encapsulate(lambda tag: widget_single_tag(tag))
|
func=lambda context: widget_single_tag(context['object'])
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=Tag, label=_('Documents'),
|
||||||
|
func=lambda context: context['object'].get_document_count(
|
||||||
|
user=context['request'].user
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
document_search.add_model_field(field='tags__label', label=_('Tags'))
|
document_search.add_model_field(field='tags__label', label=_('Tags'))
|
||||||
|
|||||||
@@ -1,12 +1,16 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from colorful.fields import RGBColorField
|
from colorful.fields import RGBColorField
|
||||||
|
|
||||||
|
from acls.models import AccessControlList
|
||||||
from documents.models import Document
|
from documents.models import Document
|
||||||
|
from documents.permissions import permission_document_view
|
||||||
|
from permissions import Permission
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
@@ -25,3 +29,15 @@ class Tag(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.label
|
return self.label
|
||||||
|
|
||||||
|
def get_document_count(self, user):
|
||||||
|
queryset = self.documents
|
||||||
|
|
||||||
|
try:
|
||||||
|
Permission.check_permissions(user, (permission_document_view,))
|
||||||
|
except PermissionDenied:
|
||||||
|
queryset = AccessControlList.objects.filter_by_access(
|
||||||
|
permission_document_view, user, queryset
|
||||||
|
)
|
||||||
|
|
||||||
|
return queryset.count()
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ from django.template import RequestContext
|
|||||||
from django.utils.translation import ugettext_lazy as _, ungettext
|
from django.utils.translation import ugettext_lazy as _, ungettext
|
||||||
|
|
||||||
from acls.models import AccessControlList
|
from acls.models import AccessControlList
|
||||||
from common.utils import encapsulate
|
|
||||||
from common.views import (
|
from common.views import (
|
||||||
SingleObjectCreateView, SingleObjectEditView, SingleObjectListView
|
SingleObjectCreateView, SingleObjectEditView, SingleObjectListView
|
||||||
)
|
)
|
||||||
@@ -126,33 +125,9 @@ def tag_multiple_attach(request):
|
|||||||
class TagListView(SingleObjectListView):
|
class TagListView(SingleObjectListView):
|
||||||
object_permission = permission_tag_view
|
object_permission = permission_tag_view
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_document_count(instance, user):
|
|
||||||
queryset = instance.documents
|
|
||||||
|
|
||||||
try:
|
|
||||||
Permission.check_permissions(user, (permission_document_view,))
|
|
||||||
except PermissionDenied:
|
|
||||||
queryset = AccessControlList.objects.filter_by_access(
|
|
||||||
permission_document_view, user, queryset
|
|
||||||
)
|
|
||||||
|
|
||||||
return queryset.count()
|
|
||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': (
|
|
||||||
{
|
|
||||||
'name': _('Documents'),
|
|
||||||
'attribute': encapsulate(
|
|
||||||
lambda instance: TagListView.get_document_count(
|
|
||||||
instance=instance, user=self.request.user
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
|
|
||||||
'title': _('Tags'),
|
'title': _('Tags'),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,16 +257,6 @@ class DocumentTagListView(TagListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': [
|
|
||||||
{
|
|
||||||
'name': _('Documents'),
|
|
||||||
'attribute': encapsulate(
|
|
||||||
lambda instance: TagListView.get_document_count(
|
|
||||||
instance=instance, user=self.request.user
|
|
||||||
)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
'object': self.document,
|
'object': self.document,
|
||||||
'title': _('Tags for document: %s') % self.document,
|
'title': _('Tags for document: %s') % self.document,
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ from actstream import registry
|
|||||||
|
|
||||||
from common import menu_multi_item, menu_object, menu_secondary, menu_setup
|
from common import menu_multi_item, menu_object, menu_secondary, menu_setup
|
||||||
from common.apps import MayanAppConfig
|
from common.apps import MayanAppConfig
|
||||||
|
from common.widgets import two_state_template
|
||||||
from metadata import MetadataLookup
|
from metadata import MetadataLookup
|
||||||
|
from navigation import SourceColumn
|
||||||
from rest_api.classes import APIEndPoint
|
from rest_api.classes import APIEndPoint
|
||||||
|
|
||||||
from .links import (
|
from .links import (
|
||||||
@@ -33,6 +35,25 @@ class UserManagementApp(MayanAppConfig):
|
|||||||
MetadataLookup(description=_('All the groups.'), name='group', value=Group.objects.all())
|
MetadataLookup(description=_('All the groups.'), name='group', value=Group.objects.all())
|
||||||
MetadataLookup(description=_('All the users.'), name='users', value=get_user_model().objects.all())
|
MetadataLookup(description=_('All the users.'), name='users', value=get_user_model().objects.all())
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=Group, label=_('Members'), attribute='user_set.count'
|
||||||
|
)
|
||||||
|
|
||||||
|
SourceColumn(
|
||||||
|
source=User, label=_('Full name'), attribute='get_full_name'
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=User, label=_('Email'), attribute='email'
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=User, label=_('Active'),
|
||||||
|
func=lambda context: two_state_template(context['object'].is_active)
|
||||||
|
)
|
||||||
|
SourceColumn(
|
||||||
|
source=User, label=_('Has usable password?'),
|
||||||
|
func=lambda context: two_state_template(context['object'].has_usable_password())
|
||||||
|
)
|
||||||
|
|
||||||
menu_multi_item.bind_links(
|
menu_multi_item.bind_links(
|
||||||
links=(link_group_multiple_delete,),
|
links=(link_group_multiple_delete,),
|
||||||
sources=('user_management:group_list',)
|
sources=('user_management:group_list',)
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ from django.shortcuts import get_object_or_404, render_to_response
|
|||||||
from django.template import RequestContext
|
from django.template import RequestContext
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from common.utils import encapsulate
|
|
||||||
from common.views import (
|
from common.views import (
|
||||||
AssignRemoveView, SingleObjectCreateView, SingleObjectEditView,
|
AssignRemoveView, SingleObjectCreateView, SingleObjectEditView,
|
||||||
SingleObjectListView
|
SingleObjectListView
|
||||||
@@ -31,30 +30,6 @@ class UserListView(SingleObjectListView):
|
|||||||
|
|
||||||
def get_extra_context(self):
|
def get_extra_context(self):
|
||||||
return {
|
return {
|
||||||
'extra_columns': (
|
|
||||||
{
|
|
||||||
'name': _('Full name'),
|
|
||||||
'attribute': 'get_full_name'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': _('Email'),
|
|
||||||
'attribute': 'email'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': _('Active'),
|
|
||||||
'attribute': encapsulate(
|
|
||||||
lambda user: two_state_template(user.is_active)
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'name': _('Has usable password?'),
|
|
||||||
'attribute': encapsulate(
|
|
||||||
lambda user: two_state_template(
|
|
||||||
user.has_usable_password()
|
|
||||||
)
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
'title': _('Users'),
|
'title': _('Users'),
|
||||||
}
|
}
|
||||||
@@ -301,8 +276,8 @@ class GroupEditView(SingleObjectEditView):
|
|||||||
|
|
||||||
class GroupListView(SingleObjectListView):
|
class GroupListView(SingleObjectListView):
|
||||||
extra_context = {
|
extra_context = {
|
||||||
'title': _('Groups'),
|
|
||||||
'hide_link': True,
|
'hide_link': True,
|
||||||
|
'title': _('Groups'),
|
||||||
'extra_columns': [
|
'extra_columns': [
|
||||||
{
|
{
|
||||||
'name': _('Members'),
|
'name': _('Members'),
|
||||||
|
|||||||
Reference in New Issue
Block a user