diff --git a/HISTORY.rst b/HISTORY.rst index 4fa0d17202..7f064833e2 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -135,6 +135,11 @@ source columns. * Add support for source column object or attribute absolute URLs. +* Add sortable columns to all apps. +* Remove permission list display from the ACL list view. + Reduces clutter and unpredictable column size. +* Remove the full name from the user list. +* Add the first name and last name to the user list. 3.1.11 (2019-04-XX) =================== diff --git a/docs/releases/3.2.rst b/docs/releases/3.2.rst index 392914c683..d4418023ef 100644 --- a/docs/releases/3.2.rst +++ b/docs/releases/3.2.rst @@ -167,6 +167,11 @@ Other changes source columns. * Add support for source column object or attribute absolute URLs. +* Add sortable columns to all apps. +* Remove permission list display from the ACL list view. + Reduces clutter and unpredictable column size. +* Remove the full name from the user list. +* Add the first name and last name to the user list. Removals -------- diff --git a/mayan/apps/acls/apps.py b/mayan/apps/acls/apps.py index eeb60bfcda..a35278d1c1 100644 --- a/mayan/apps/acls/apps.py +++ b/mayan/apps/acls/apps.py @@ -23,11 +23,7 @@ class ACLsApp(MayanAppConfig): AccessControlList = self.get_model('AccessControlList') SourceColumn( - source=AccessControlList, label=_('Role'), attribute='role' - ) - SourceColumn( - source=AccessControlList, label=_('Permissions'), - attribute='get_permission_titles' + attribute='role', is_sortable=True, source=AccessControlList, ) menu_object.bind_links( diff --git a/mayan/apps/acls/models.py b/mayan/apps/acls/models.py index 933e4a422c..a39886d279 100644 --- a/mayan/apps/acls/models.py +++ b/mayan/apps/acls/models.py @@ -6,7 +6,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.db import models from django.urls import reverse -from django.utils.encoding import force_text, python_2_unicode_compatible +from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ from mayan.apps.permissions.models import Role, StoredPermission @@ -58,11 +58,10 @@ class AccessControlList(models.Model): def __str__(self): return _( - 'Permissions "%(permissions)s" to role "%(role)s" for "%(object)s"' + 'Role "%(role)s" permission\'s for "%(object)s"' ) % { - 'permissions': self.get_permission_titles(), 'object': self.content_object, - 'role': self.role + 'role': self.role, } def get_absolute_url(self): @@ -74,13 +73,3 @@ class AccessControlList(models.Model): return AccessControlList.objects.get_inherited_permissions( role=self.role, obj=self.content_object ) - - def get_permission_titles(self): - """ - Returns the descriptibe labels for the permissions. - """ - result = ', '.join( - [force_text(permission) for permission in self.permissions.all()] - ) - - return result or _('None') diff --git a/mayan/apps/cabinets/apps.py b/mayan/apps/cabinets/apps.py index cef65c4776..32c8f8fc84 100644 --- a/mayan/apps/cabinets/apps.py +++ b/mayan/apps/cabinets/apps.py @@ -76,6 +76,11 @@ class CabinetsApp(MayanAppConfig): model=Cabinet, related='get_root', ) + SourceColumn( + attribute='label', is_identifier=True, is_sortable=True, + source=Cabinet + ) + SourceColumn( source=Document, label=_('Cabinets'), func=lambda context: widget_document_cabinets( diff --git a/mayan/apps/cabinets/views.py b/mayan/apps/cabinets/views.py index a66c76c8e5..393366957a 100644 --- a/mayan/apps/cabinets/views.py +++ b/mayan/apps/cabinets/views.py @@ -168,6 +168,7 @@ class CabinetListView(SingleObjectListView): def get_extra_context(self): return { 'hide_link': True, + 'hide_object': True, 'title': _('Cabinets'), 'no_results_icon': icon_cabinet, 'no_results_main_link': link_cabinet_create.resolve( diff --git a/mayan/apps/document_indexing/apps.py b/mayan/apps/document_indexing/apps.py index 142b8e4451..3c2a1d56bf 100644 --- a/mayan/apps/document_indexing/apps.py +++ b/mayan/apps/document_indexing/apps.py @@ -83,10 +83,15 @@ class DocumentIndexingApp(MayanAppConfig): ) ) - SourceColumn(source=Index, label=_('Label'), attribute='label') - SourceColumn(source=Index, label=_('Slug'), attribute='slug') SourceColumn( - attribute='enabled', label=_('Enabled'), source=Index, + attribute='label', is_identifier=True, is_sortable=True, + source=Index + ) + SourceColumn( + attribute='slug', is_sortable=True, source=Index + ) + SourceColumn( + attribute='enabled', is_sortable=True, source=Index, widget=TwoStateWidget ) @@ -110,12 +115,12 @@ class DocumentIndexingApp(MayanAppConfig): func=lambda context: node_level(context['object']) ) SourceColumn( - attribute='enabled', label=_('Enabled'), source=IndexTemplateNode, + attribute='enabled', is_sortable=True, source=IndexTemplateNode, widget=TwoStateWidget ) SourceColumn( - attribute='enabled', label=_('Has document links?'), - source=IndexTemplateNode, widget=TwoStateWidget + attribute='enabled', is_sortable=True, source=IndexTemplateNode, + widget=TwoStateWidget ) SourceColumn( source=IndexInstanceNode, label=_('Level'), @@ -135,10 +140,10 @@ class DocumentIndexingApp(MayanAppConfig): ) SourceColumn( - source=DocumentIndexInstanceNode, label=_('Level'), + label=_('Level'), func=lambda context: get_instance_link( index_instance_node=context['object'], - ) + ), source=DocumentIndexInstanceNode, ) SourceColumn( source=DocumentIndexInstanceNode, label=_('Levels'), diff --git a/mayan/apps/document_parsing/apps.py b/mayan/apps/document_parsing/apps.py index 02c92ba682..0193881331 100644 --- a/mayan/apps/document_parsing/apps.py +++ b/mayan/apps/document_parsing/apps.py @@ -107,12 +107,13 @@ class DocumentParsingApp(MayanAppConfig): ) SourceColumn( - source=DocumentVersionParseError, label=_('Document'), - func=lambda context: document_link(context['object'].document_version.document) + attribute='document_version__document', + is_attribute_absolute_url=True, is_identifier=True, is_sortable=True, + source=DocumentVersionParseError ) SourceColumn( - source=DocumentVersionParseError, label=_('Added'), - attribute='datetime_submitted' + attribute='datetime_submitted', is_sortable=True, + source=DocumentVersionParseError ) SourceColumn( source=DocumentVersionParseError, label=_('Result'), diff --git a/mayan/apps/documents/apps.py b/mayan/apps/documents/apps.py index 5b60f58df7..ad684e2d18 100644 --- a/mayan/apps/documents/apps.py +++ b/mayan/apps/documents/apps.py @@ -240,6 +240,10 @@ class DocumentsApp(MayanAppConfig): document_page_thumbnail_widget = DocumentPageThumbnailWidget() # Document + SourceColumn( + attribute='label', is_object_absolute_url=True, is_identifier=True, + is_sortable=True, source=Document + ) SourceColumn( source=Document, label=_('Thumbnail'), func=lambda context: document_page_thumbnail_widget.render( @@ -247,7 +251,7 @@ class DocumentsApp(MayanAppConfig): ) ) SourceColumn( - source=Document, attribute='document_type' + attribute='document_type', is_sortable=True, source=Document, ) SourceColumn( source=Document, label=_('Pages'), @@ -255,6 +259,16 @@ class DocumentsApp(MayanAppConfig): document=context['object'] ) ) + SourceColumn( + attribute='date_added', include_label=True, is_sortable=True, + source=Document, views=('documents:document_list_recent_added',) + ) + SourceColumn( + func=lambda context: DuplicatedDocument.objects.get( + document=context['object'] + ).documents.count(), include_label=True, label=_('Duplicates'), + source=Document, views=('documents:duplicated_document_list',) + ) # DocumentPage SourceColumn( @@ -277,6 +291,11 @@ class DocumentsApp(MayanAppConfig): ) # DocumentType + SourceColumn( + attribute='label', is_identifier=True, is_sortable=True, + source=DocumentType + ) + SourceColumn( source=DocumentType, label=_('Documents'), func=lambda context: context['object'].get_document_count( @@ -285,20 +304,27 @@ class DocumentsApp(MayanAppConfig): ) SourceColumn( - attribute='enabled', label=_('Enabled'), - source=DocumentTypeFilename, widget=TwoStateWidget + attribute='filename', is_identifier=True, is_sortable=True, + source=DocumentTypeFilename + ) + SourceColumn( + attribute='enabled', is_sortable=True, source=DocumentTypeFilename, + widget=TwoStateWidget ) # DeletedDocument + SourceColumn( + attribute='label', is_identifier=True, is_sortable=True, + source=DeletedDocument + ) SourceColumn( source=DeletedDocument, label=_('Thumbnail'), func=lambda context: document_page_thumbnail_widget.render( instance=context['object'] ) ) - SourceColumn( - source=DeletedDocument, attribute='document_type' + attribute='document_type', is_sortable=True, source=DeletedDocument ) SourceColumn( source=DeletedDocument, attribute='deleted_date_time' @@ -307,7 +333,7 @@ class DocumentsApp(MayanAppConfig): # DocumentVersion SourceColumn( source=DocumentVersion, attribute='timestamp', is_identifier=True, - is_absolute_url=True + is_object_absolute_url=True ) SourceColumn( source=DocumentVersion, label=_('Thumbnail'), @@ -322,25 +348,13 @@ class DocumentsApp(MayanAppConfig): ) ) SourceColumn( - source=DocumentVersion, attribute='mimetype' + attribute='mimetype', is_sortable=True, source=DocumentVersion ) SourceColumn( - source=DocumentVersion, attribute='encoding' + attribute='encoding', is_sortable=True, source=DocumentVersion ) SourceColumn( - source=DocumentVersion, attribute='comment' - ) - - # DuplicatedDocument - SourceColumn( - source=DuplicatedDocument, label=_('Thumbnail'), - func=lambda context: document_page_thumbnail_widget.render( - instance=context['object'].document - ) - ) - SourceColumn( - source=DuplicatedDocument, label=_('Duplicates'), - func=lambda context: context['object'].documents.count() + attribute='comment', is_sortable=True, source=DocumentVersion ) Template( diff --git a/mayan/apps/documents/links.py b/mayan/apps/documents/links.py index be4efb1a1f..186701c893 100644 --- a/mayan/apps/documents/links.py +++ b/mayan/apps/documents/links.py @@ -383,25 +383,33 @@ link_document_type_edit = Link( view='documents:document_type_edit', ) link_document_type_filename_create = Link( - args='document_type.id', icon_class=icon_document_type_filename_create, + args='document_type.id', + icon_class_path='mayan.apps.documents.icons.icon_document_type_filename_create', permissions=(permission_document_type_edit,), text=_('Add quick label to document type'), view='documents:document_type_filename_create', ) link_document_type_filename_delete = Link( - args='resolved_object.id', permissions=(permission_document_type_edit,), + args='resolved_object.id', + icon_class_path='mayan.apps.documents.icons.icon_document_type_filename_delete', + permissions=(permission_document_type_edit,), tags='dangerous', text=_('Delete'), view='documents:document_type_filename_delete', ) link_document_type_filename_edit = Link( - args='resolved_object.id', permissions=(permission_document_type_edit,), + args='resolved_object.id', + icon_class_path='mayan.apps.documents.icons.icon_document_type_filename_edit', + permissions=(permission_document_type_edit,), text=_('Edit'), view='documents:document_type_filename_edit', ) link_document_type_filename_list = Link( - args='resolved_object.id', permissions=(permission_document_type_view,), + args='resolved_object.id', + icon_class_path='mayan.apps.documents.icons.icon_document_type_filename_list', + permissions=(permission_document_type_view,), text=_('Quick labels'), view='documents:document_type_filename_list', ) link_document_type_list = Link( + icon_class_path='mayan.apps.documents.icons.icon_document_type_list', permissions=(permission_document_type_view,), text=_('Document types'), view='documents:document_type_list' ) diff --git a/mayan/apps/documents/views/document_type_views.py b/mayan/apps/documents/views/document_type_views.py index 56c2f7f10e..79ee912b50 100644 --- a/mayan/apps/documents/views/document_type_views.py +++ b/mayan/apps/documents/views/document_type_views.py @@ -62,6 +62,7 @@ class DocumentTypeListView(SingleObjectListView): def get_extra_context(self): return { 'hide_link': True, + 'hide_object': True, 'no_results_icon': icon_document_type_setup, 'no_results_main_link': link_document_type_create.resolve( context=RequestContext(request=self.request) @@ -225,6 +226,7 @@ class DocumentTypeFilenameListView(SingleObjectListView): return { 'document_type': self.get_document_type(), 'hide_link': True, + 'hide_object': True, 'navigation_object_list': ('document_type',), 'no_results_icon': icon_document_type_filename, 'no_results_main_link': link_document_type_filename_create.resolve( diff --git a/mayan/apps/documents/views/document_views.py b/mayan/apps/documents/views/document_views.py index 1254217a6d..d34a8163e8 100644 --- a/mayan/apps/documents/views/document_views.py +++ b/mayan/apps/documents/views/document_views.py @@ -84,6 +84,7 @@ class DocumentListView(SingleObjectListView): def get_extra_context(self): return { 'hide_links': True, + 'hide_object': True, 'list_as_items': True, 'no_results_icon': icon_document_list, 'no_results_text': _( @@ -669,16 +670,16 @@ class DuplicatedDocumentListView(DocumentListView): context = super(DuplicatedDocumentListView, self).get_extra_context() context.update( { - 'extra_columns': ( - { - 'name': _('Duplicates'), - 'attribute': encapsulate( - lambda document: DuplicatedDocument.objects.get( - document=document - ).documents.count() - ) - }, - ), + #'extra_columns': ( + # { + # 'name': _('Duplicates'), + # 'attribute': encapsulate( + # lambda document: DuplicatedDocument.objects.get( + # document=document + # ).documents.count() + # ) + # }, + #), 'no_results_icon': icon_duplicated_document_list, 'no_results_text': _( 'Duplicates are documents that are composed of the exact ' diff --git a/mayan/apps/events/apps.py b/mayan/apps/events/apps.py index 21346a9dee..0fad6b1bde 100644 --- a/mayan/apps/events/apps.py +++ b/mayan/apps/events/apps.py @@ -36,7 +36,8 @@ class EventsApp(MayanAppConfig): StoredEventType = self.get_model(model_name='StoredEventType') SourceColumn( - source=Action, label=_('Timestamp'), attribute='timestamp' + attribute='timestamp', is_identifier=True, + is_sortable=True, label=_('Date and time'), source=Action ) SourceColumn( func=widget_event_actor_link, label=_('Actor'), source=Action @@ -61,10 +62,9 @@ class EventsApp(MayanAppConfig): ) SourceColumn( - source=Notification, label=_('Timestamp'), - attribute='action.timestamp' + attribute='action__timestamp', is_identifier=True, + is_sortable=True, label=_('Date and time'), source=Notification ) - SourceColumn( func=widget_event_actor_link, label=_('Actor'), kwargs={'attribute': 'action'}, source=Notification @@ -79,8 +79,8 @@ class EventsApp(MayanAppConfig): ) SourceColumn( - attribute='read', label=_('Seen'), source=Notification, - widget=TwoStateWidget + attribute='read', is_sortable=True, label=_('Seen'), + source=Notification, widget=TwoStateWidget ) menu_main.bind_links( diff --git a/mayan/apps/metadata/apps.py b/mayan/apps/metadata/apps.py index 0a7969c55f..6c94638372 100644 --- a/mayan/apps/metadata/apps.py +++ b/mayan/apps/metadata/apps.py @@ -162,14 +162,25 @@ class MetadataApp(MayanAppConfig): ) SourceColumn( - source=DocumentMetadata, label=_('Value'), - attribute='value' + attribute='metadata_type', is_identifier=True, + is_sortable=True, source=DocumentMetadata ) SourceColumn( - attribute='is_required', label=_('Required'), - source=DocumentMetadata, widget=TwoStateWidget + attribute='value', is_sortable=True, source=DocumentMetadata ) + SourceColumn( + attribute='is_required', source=DocumentMetadata, + widget=TwoStateWidget + ) + + SourceColumn( + attribute='label', is_identifier=True, is_sortable=True, + source=MetadataType + ) + SourceColumn(attribute='name', is_sortable=True, source=MetadataType) + + app.conf.CELERY_QUEUES.append( Queue('metadata', Exchange('metadata'), routing_key='metadata'), ) diff --git a/mayan/apps/metadata/views.py b/mayan/apps/metadata/views.py index 09490b6948..a704c6f074 100644 --- a/mayan/apps/metadata/views.py +++ b/mayan/apps/metadata/views.py @@ -412,6 +412,7 @@ class DocumentMetadataListView(SingleObjectListView): document = self.get_document() return { 'hide_link': True, + 'hide_object': True, 'object': document, 'no_results_icon': icon_metadata, 'no_results_main_link': link_metadata_add.resolve( @@ -637,13 +638,8 @@ class MetadataTypeListView(SingleObjectListView): def get_extra_context(self): return { - 'extra_columns': ( - { - 'name': _('Internal name'), - 'attribute': 'name', - }, - ), 'hide_link': True, + 'hide_object': True, 'no_results_icon': icon_metadata, 'no_results_main_link': link_setup_metadata_type_create.resolve( context=RequestContext(request=self.request) diff --git a/mayan/apps/motd/apps.py b/mayan/apps/motd/apps.py index 782480feff..c0c14d1a81 100644 --- a/mayan/apps/motd/apps.py +++ b/mayan/apps/motd/apps.py @@ -8,6 +8,7 @@ from mayan.apps.acls.classes import ModelPermission from mayan.apps.acls.links import link_acl_list from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view from mayan.apps.common.apps import MayanAppConfig +from mayan.apps.common.html_widgets import TwoStateWidget from mayan.apps.common.menus import ( menu_list_facet, menu_object, menu_secondary, menu_setup ) @@ -45,15 +46,20 @@ class MOTDApp(MayanAppConfig): ) ) SourceColumn( - source=Message, label=_('Enabled'), attribute='enabled' + attribute='label', is_identifier=True, is_sortable=True, + source=Message ) SourceColumn( - source=Message, label=_('Start date time'), - func=lambda context: context['object'].start_datetime or _('None') + attribute='enabled', include_label=True, is_sortable=True, + source=Message, widget=TwoStateWidget ) SourceColumn( - source=Message, label=_('End date time'), - func=lambda context: context['object'].end_datetime or _('None') + attribute='start_datetime', empty_value=_('None'), + include_label=True, is_sortable=True, source=Message + ) + SourceColumn( + attribute='end_datetime', empty_value=_('None'), + include_label=True, is_sortable=True, source=Message ) menu_list_facet.bind_links( diff --git a/mayan/apps/motd/links.py b/mayan/apps/motd/links.py index b0a8133baa..665a696a1a 100644 --- a/mayan/apps/motd/links.py +++ b/mayan/apps/motd/links.py @@ -4,23 +4,26 @@ from django.utils.translation import ugettext_lazy as _ from mayan.apps.navigation import Link, get_cascade_condition -from .icons import icon_message_create, icon_message_list from .permissions import ( permission_message_create, permission_message_delete, permission_message_edit, permission_message_view ) - link_message_create = Link( - icon_class=icon_message_create, permissions=(permission_message_create,), + icon_class_path='mayan.apps.motd.icons.icon_message_create', + permissions=(permission_message_create,), text=_('Create message'), view='motd:message_create' ) link_message_delete = Link( - args='object.pk', permissions=(permission_message_delete,), + args='object.pk', + icon_class_path='mayan.apps.motd.icons.icon_message_delete', + permissions=(permission_message_delete,), tags='dangerous', text=_('Delete'), view='motd:message_delete' ) link_message_edit = Link( - args='object.pk', permissions=(permission_message_edit,), text=_('Edit'), + args='object.pk', + icon_class_path='mayan.apps.motd.icons.icon_message_edit', + permissions=(permission_message_edit,), text=_('Edit'), view='motd:message_edit' ) link_message_list = Link( @@ -28,6 +31,7 @@ link_message_list = Link( app_label='motd', model_name='Message', object_permission=permission_message_view, view_permission=permission_message_create, - ), icon_class=icon_message_list, text=_('Message of the day'), + ), icon_class_path='mayan.apps.motd.icons.icon_message_list', + text=_('Message of the day'), view='motd:message_list' ) diff --git a/mayan/apps/motd/views.py b/mayan/apps/motd/views.py index 7899db6bf8..9ca6582486 100644 --- a/mayan/apps/motd/views.py +++ b/mayan/apps/motd/views.py @@ -66,6 +66,7 @@ class MessageListView(SingleObjectListView): def get_extra_context(self): return { 'hide_link': True, + 'hide_object': True, 'no_results_icon': icon_message_list, 'no_results_main_link': link_message_create.resolve( context=RequestContext(request=self.request) diff --git a/mayan/apps/ocr/apps.py b/mayan/apps/ocr/apps.py index 98316e85eb..d41fc734d9 100644 --- a/mayan/apps/ocr/apps.py +++ b/mayan/apps/ocr/apps.py @@ -103,12 +103,12 @@ class OCRApp(MayanAppConfig): ) SourceColumn( - source=DocumentVersionOCRError, label=_('Document'), - func=lambda context: document_link(context['object'].document_version.document) + attribute='document_version__document', is_attribute_absolute_url=True, + is_identifier=True, is_sortable=True, source=DocumentVersionOCRError ) SourceColumn( - source=DocumentVersionOCRError, label=_('Added'), - attribute='datetime_submitted' + attribute='datetime_submitted', is_sortable=True, + label=_('Date and time'), source=DocumentVersionOCRError ) SourceColumn( source=DocumentVersionOCRError, label=_('Result'), diff --git a/mayan/apps/permissions/apps.py b/mayan/apps/permissions/apps.py index c7b7f4bec7..fb2ccb630c 100644 --- a/mayan/apps/permissions/apps.py +++ b/mayan/apps/permissions/apps.py @@ -15,9 +15,8 @@ from mayan.apps.common.signals import perform_upgrade from .handlers import purge_permissions from .links import ( - link_group_roles, link_permission_grant, link_permission_revoke, - link_role_create, link_role_delete, link_role_edit, link_role_groups, - link_role_list, link_role_permissions + link_group_roles, link_role_create, link_role_delete, link_role_edit, + link_role_groups, link_role_list, link_role_permissions ) from .permissions import ( permission_role_delete, permission_role_edit, permission_role_view @@ -60,10 +59,6 @@ class PermissionsApp(MayanAppConfig): link_role_delete, link_role_edit ), sources=(Role,) ) - menu_multi_item.bind_links( - links=(link_permission_grant, link_permission_revoke), - sources=('permissions:role_permissions',) - ) menu_secondary.bind_links( links=(link_role_list, link_role_create), sources=(Role, 'permissions:role_create', 'permissions:role_list') diff --git a/mayan/apps/permissions/links.py b/mayan/apps/permissions/links.py index 98851874ca..613493a047 100644 --- a/mayan/apps/permissions/links.py +++ b/mayan/apps/permissions/links.py @@ -5,46 +5,49 @@ from django.utils.translation import ugettext_lazy as _ from mayan.apps.navigation import Link from mayan.apps.user_management.permissions import permission_group_edit -from .icons import icon_role_create, icon_role_list from .permissions import ( permission_role_create, permission_role_delete, permission_role_edit, permission_role_view ) link_group_roles = Link( - args='object.id', permissions=(permission_group_edit,), text=_('Roles'), + args='object.id', + icon_class_path='mayan.apps.permissions.icons.icon_group_roles', + permissions=(permission_group_edit,), text=_('Roles'), view='permissions:group_roles', ) -link_permission_grant = Link( - permissions=(permission_role_edit,), text=_('Grant'), - view='permissions:permission_multiple_grant' -) -link_permission_revoke = Link( - permissions=(permission_role_edit,), text=_('Revoke'), - view='permissions:permission_multiple_revoke' -) + link_role_create = Link( - icon_class=icon_role_create, permissions=(permission_role_create,), + icon_class_path='mayan.apps.permissions.icons.icon_role_create', + permissions=(permission_role_create,), text=_('Create new role'), view='permissions:role_create' ) link_role_delete = Link( - args='object.id', permissions=(permission_role_delete,), tags='dangerous', + args='object.id', + icon_class_path='mayan.apps.permissions.icons.icon_role_delete', + permissions=(permission_role_delete,), tags='dangerous', text=_('Delete'), view='permissions:role_delete', ) link_role_edit = Link( - args='object.id', permissions=(permission_role_edit,), text=_('Edit'), + args='object.id', + icon_class_path='mayan.apps.permissions.icons.icon_role_edit', + permissions=(permission_role_edit,), text=_('Edit'), view='permissions:role_edit', ) link_role_list = Link( - icon_class=icon_role_list, permissions=(permission_role_view,), + icon_class_path='mayan.apps.permissions.icons.icon_role_list', + permissions=(permission_role_view,), text=_('Roles'), view='permissions:role_list' ) link_role_groups = Link( - args='object.id', permissions=(permission_role_edit,), text=_('Groups'), + args='object.id', + icon_class_path='mayan.apps.permissions.icons.icon_role_groups', + permissions=(permission_role_edit,), text=_('Groups'), view='permissions:role_groups', ) link_role_permissions = Link( args='object.id', + icon_class_path='mayan.apps.permissions.icons.icon_role_permissions', permissions=(permission_role_edit,), text=_('Role permissions'), view='permissions:role_permissions', ) diff --git a/mayan/apps/sources/apps.py b/mayan/apps/sources/apps.py index ebfc58e358..676b6b7a74 100644 --- a/mayan/apps/sources/apps.py +++ b/mayan/apps/sources/apps.py @@ -67,17 +67,12 @@ class SourcesApp(MayanAppConfig): ) SourceColumn( - attribute='label', is_identifier=True, + attribute='label', is_identifier=True, is_sortable=True, source=Source ) SourceColumn( attribute='class_fullname', label=_('Type'), source=Source ) - SourceColumn( - attribute='enabled', source=Source, - widget=TwoStateWidget - ) - SourceColumn( attribute='enabled', is_sortable=True, source=Source, widget=TwoStateWidget diff --git a/mayan/apps/tags/apps.py b/mayan/apps/tags/apps.py index 591a1ebad1..14e18ace68 100644 --- a/mayan/apps/tags/apps.py +++ b/mayan/apps/tags/apps.py @@ -102,7 +102,8 @@ class TagsApp(MayanAppConfig): ) SourceColumn( - source=DocumentTag, attribute='label' + attribute='label', is_identifier=True, is_sortable=True, + source=DocumentTag ) SourceColumn( source=DocumentTag, attribute='get_preview_widget' @@ -124,7 +125,8 @@ class TagsApp(MayanAppConfig): ) SourceColumn( - source=Tag, attribute='label' + attribute='label', is_identifier=True, is_sortable=True, + source=Tag ) SourceColumn( source=Tag, attribute='get_preview_widget' diff --git a/mayan/apps/tags/urls.py b/mayan/apps/tags/urls.py index 27604e5837..61fb5d1e3c 100644 --- a/mayan/apps/tags/urls.py +++ b/mayan/apps/tags/urls.py @@ -9,7 +9,7 @@ from .api_views import ( from .views import ( DocumentTagListView, TagAttachActionView, TagCreateView, TagDeleteActionView, TagEditView, TagListView, TagRemoveActionView, - TagTaggedItemListView + TagDocumentListView ) urlpatterns = [ @@ -24,7 +24,7 @@ urlpatterns = [ name='tag_edit' ), url( - regex=r'^(?P\d+)/documents/$', view=TagTaggedItemListView.as_view(), + regex=r'^(?P\d+)/documents/$', view=TagDocumentListView.as_view(), name='tag_document_list' ), url( diff --git a/mayan/apps/tags/views.py b/mayan/apps/tags/views.py index be503d40da..45b8c4110f 100644 --- a/mayan/apps/tags/views.py +++ b/mayan/apps/tags/views.py @@ -225,7 +225,7 @@ class TagListView(SingleObjectListView): return Tag.objects.all() -class TagTaggedItemListView(DocumentListView): +class TagDocumentListView(DocumentListView): def get_tag(self): return get_object_or_404(klass=Tag, pk=self.kwargs['pk']) @@ -233,7 +233,7 @@ class TagTaggedItemListView(DocumentListView): return self.get_tag().documents.all() def get_extra_context(self): - context = super(TagTaggedItemListView, self).get_extra_context() + context = super(TagDocumentListView, self).get_extra_context() context.update( { 'column_class': 'col-xs-12 col-sm-6 col-md-4 col-lg-3', diff --git a/mayan/apps/user_management/apps.py b/mayan/apps/user_management/apps.py index 6898a3c3ef..35c2a33cf6 100644 --- a/mayan/apps/user_management/apps.py +++ b/mayan/apps/user_management/apps.py @@ -29,9 +29,9 @@ from .events import ( from .handlers import handler_initialize_new_user_options from .links import ( link_current_user_details, link_current_user_edit, link_group_create, - link_group_delete, link_group_edit, link_group_list, link_group_members, + link_group_delete, link_group_edit, link_group_list, link_group_user_list, link_group_setup, link_user_create, link_user_delete, link_user_edit, - link_user_groups, link_user_list, link_user_multiple_delete, + link_user_group_list, link_user_list, link_user_multiple_delete, link_user_multiple_set_password, link_user_set_options, link_user_set_password, link_user_setup, separator_user_label, text_user_label @@ -120,25 +120,39 @@ class UserManagementApp(MayanAppConfig): permission_user_view ) ) + SourceColumn( - source=Group, label=_('Users'), attribute='user_set.count' + attribute='name', is_identifier=True, is_sortable=True, + label=_('Name'), source=Group + ) + SourceColumn( + attribute='user_set.count', label=_('Users'), source=Group ) SourceColumn( - source=User, label=_('Full name'), attribute='get_full_name' + attribute='username', is_object_absolute_url=True, + is_identifier=True, is_sortable=True, label=_('Username'), + source=User ) SourceColumn( - source=User, label=_('Email'), attribute='email' + attribute='first_name', is_sortable=True, label=_('First name'), + source=User ) SourceColumn( - attribute='is_active', label=_('Active'), source=User, - widget=TwoStateWidget + attribute='last_name', is_sortable=True, label=_('Last name'), + source=User + ) + SourceColumn( + attribute='email', is_sortable=True, label=_('Email'), source=User + ) + SourceColumn( + attribute='is_active', is_sortable=True, label=_('Active'), + source=User, widget=TwoStateWidget ) SourceColumn( attribute='has_usable_password', label=_('Has usable password?'), source=User, widget=TwoStateWidget ) - # Silence UnorderedObjectListWarning # "Pagination may yield inconsistent result" # TODO: Remove on Django 2.x @@ -153,14 +167,14 @@ class UserManagementApp(MayanAppConfig): links=( link_acl_list, link_events_for_object, link_object_event_types_user_subcriptions_list, - link_group_members, + link_group_user_list, ), sources=(Group,) ) menu_list_facet.bind_links( links=( link_acl_list, link_events_for_object, link_object_event_types_user_subcriptions_list, - link_user_groups, link_user_set_options + link_user_group_list, link_user_set_options ), sources=(User,) ) menu_multi_item.bind_links( diff --git a/mayan/apps/user_management/links.py b/mayan/apps/user_management/links.py index a86eab688b..503133165f 100644 --- a/mayan/apps/user_management/links.py +++ b/mayan/apps/user_management/links.py @@ -4,10 +4,6 @@ from django.utils.translation import ugettext_lazy as _ from mayan.apps.navigation.classes import Link, Separator, Text -from .icons import ( - icon_current_user_details, icon_current_user_edit, icon_group_create, - icon_group_setup, icon_user_create, icon_user_setup -) from .permissions import ( permission_group_create, permission_group_delete, permission_group_edit, permission_group_view, permission_user_create, permission_user_delete, @@ -16,76 +12,100 @@ from .permissions import ( from .utils import get_user_label_text link_current_user_details = Link( - icon_class=icon_current_user_details, text=_('User details'), - view='user_management:current_user_details' + icon_class_path='mayan.apps.user_management.icons.icon_current_user_details', + text=_('User details'), view='user_management:current_user_details' ) link_current_user_edit = Link( - icon_class=icon_current_user_edit, text=_('Edit details'), - view='user_management:current_user_edit' + icon_class_path='mayan.apps.user_management.icons.icon_current_user_edit', + text=_('Edit details'), view='user_management:current_user_edit' ) link_group_create = Link( - icon_class=icon_group_create, permissions=(permission_group_create,), - text=_('Create new group'), view='user_management:group_create' + icon_class_path='mayan.apps.user_management.icons.icon_group_create', + permissions=(permission_group_create,), text=_('Create new group'), + view='user_management:group_create' ) link_group_delete = Link( - args='object.id', permissions=(permission_group_delete,), tags='dangerous', + args='object.id', + icon_class_path='mayan.apps.user_management.icons.icon_group_delete', + permissions=(permission_group_delete,), tags='dangerous', text=_('Delete'), view='user_management:group_delete', ) link_group_edit = Link( - args='object.id', permissions=(permission_group_edit,), text=_('Edit'), + args='object.id', + icon_class_path='mayan.apps.user_management.icons.icon_group_edit', + permissions=(permission_group_edit,), text=_('Edit'), view='user_management:group_edit', ) link_group_list = Link( + icon_class_path='mayan.apps.user_management.icons.icon_group_list', permissions=(permission_group_view,), text=_('Groups'), view='user_management:group_list' ) -link_group_members = Link( - args='object.id', permissions=(permission_group_edit,), text=_('Users'), +link_group_user_list = Link( + args='object.id', + icon_class_path='mayan.apps.user_management.icons.icon_group_user_list', + permissions=(permission_group_edit,), text=_('Users'), view='user_management:group_members', ) link_group_setup = Link( - icon_class=icon_group_setup, permissions=(permission_group_view,), - text=_('Groups'), view='user_management:group_list' + icon_class_path='mayan.apps.user_management.icons.icon_group_setup', + permissions=(permission_group_view,), text=_('Groups'), + view='user_management:group_list' ) link_user_create = Link( - icon_class=icon_user_create, permissions=(permission_user_create,), - text=_('Create new user'), view='user_management:user_create' + icon_class_path='mayan.apps.user_management.icons.icon_user_create', + permissions=(permission_user_create,), text=_('Create new user'), + view='user_management:user_create' ) link_user_delete = Link( - args='object.id', permissions=(permission_user_delete,), tags='dangerous', + args='object.id', + icon_class_path='mayan.apps.user_management.icons.icon_user_delete', + permissions=(permission_user_delete,), tags='dangerous', text=_('Delete'), view='user_management:user_delete', ) link_user_edit = Link( - args='object.id', permissions=(permission_user_edit,), text=_('Edit'), + args='object.id', + icon_class_path='mayan.apps.user_management.icons.icon_user_edit', + permissions=(permission_user_edit,), text=_('Edit'), view='user_management:user_edit', ) -link_user_groups = Link( - args='object.id', permissions=(permission_user_edit,), text=_('Groups'), +link_user_group_list = Link( + args='object.id', + icon_class_path='mayan.apps.user_management.icons.icon_user_group_list', + permissions=(permission_user_edit,), text=_('Groups'), view='user_management:user_groups', ) link_user_list = Link( + icon_class_path='mayan.apps.user_management.icons.icon_user_list', permissions=(permission_user_view,), text=_('Users'), view='user_management:user_list' ) link_user_multiple_delete = Link( + icon_class_path='mayan.apps.user_management.icons.icon_user_delete', permissions=(permission_user_delete,), tags='dangerous', text=_('Delete'), view='user_management:user_multiple_delete' ) link_user_multiple_set_password = Link( + icon_class_path='mayan.apps.user_management.icons.icon_user_set_password', permissions=(permission_user_edit,), text=_('Set password'), view='user_management:user_multiple_set_password' ) link_user_set_options = Link( - args='object.id', permissions=(permission_user_edit,), + args='object.id', + icon_class_path='mayan.apps.user_management.icons.icon_user_set_options', + permissions=(permission_user_edit,), text=_('User options'), view='user_management:user_options', ) link_user_set_password = Link( - args='object.id', permissions=(permission_user_edit,), + args='object.id', + icon_class_path='mayan.apps.user_management.icons.icon_user_set_password', + permissions=(permission_user_edit,), text=_('Set password'), view='user_management:user_set_password', ) link_user_setup = Link( - icon_class=icon_user_setup, permissions=(permission_user_view,), - text=_('Users'), view='user_management:user_list' + icon_class_path='mayan.apps.user_management.icons.icon_user_setup', + permissions=(permission_user_view,), text=_('Users'), + view='user_management:user_list' ) separator_user_label = Separator() text_user_label = Text(text=get_user_label_text) diff --git a/mayan/apps/user_management/views.py b/mayan/apps/user_management/views.py index 2c23a46384..56bb4b4dff 100644 --- a/mayan/apps/user_management/views.py +++ b/mayan/apps/user_management/views.py @@ -89,6 +89,7 @@ class GroupListView(SingleObjectListView): def get_extra_context(self): return { 'hide_link': True, + 'hide_object': True, 'no_results_icon': icon_group_setup, 'no_results_main_link': link_group_create.resolve( context=RequestContext(request=self.request) @@ -339,6 +340,7 @@ class UserListView(SingleObjectListView): def get_extra_context(self): return { 'hide_link': True, + 'hide_object': True, 'no_results_icon': icon_user_setup, 'no_results_main_link': link_user_create.resolve( context=RequestContext(request=self.request)