Add sortable columns to all apps

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
Roberto Rosario
2019-04-24 04:20:50 -04:00
parent 2619777d41
commit 296c580a5e
28 changed files with 248 additions and 167 deletions

View File

@@ -135,6 +135,11 @@
source columns. source columns.
* Add support for source column object or attribute * Add support for source column object or attribute
absolute URLs. 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) 3.1.11 (2019-04-XX)
=================== ===================

View File

@@ -167,6 +167,11 @@ Other changes
source columns. source columns.
* Add support for source column object or attribute * Add support for source column object or attribute
absolute URLs. 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 Removals
-------- --------

View File

@@ -23,11 +23,7 @@ class ACLsApp(MayanAppConfig):
AccessControlList = self.get_model('AccessControlList') AccessControlList = self.get_model('AccessControlList')
SourceColumn( SourceColumn(
source=AccessControlList, label=_('Role'), attribute='role' attribute='role', is_sortable=True, source=AccessControlList,
)
SourceColumn(
source=AccessControlList, label=_('Permissions'),
attribute='get_permission_titles'
) )
menu_object.bind_links( menu_object.bind_links(

View File

@@ -6,7 +6,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.urls import reverse 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 django.utils.translation import ugettext_lazy as _
from mayan.apps.permissions.models import Role, StoredPermission from mayan.apps.permissions.models import Role, StoredPermission
@@ -58,11 +58,10 @@ class AccessControlList(models.Model):
def __str__(self): def __str__(self):
return _( 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, 'object': self.content_object,
'role': self.role 'role': self.role,
} }
def get_absolute_url(self): def get_absolute_url(self):
@@ -74,13 +73,3 @@ class AccessControlList(models.Model):
return AccessControlList.objects.get_inherited_permissions( return AccessControlList.objects.get_inherited_permissions(
role=self.role, obj=self.content_object 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')

View File

@@ -76,6 +76,11 @@ class CabinetsApp(MayanAppConfig):
model=Cabinet, related='get_root', model=Cabinet, related='get_root',
) )
SourceColumn(
attribute='label', is_identifier=True, is_sortable=True,
source=Cabinet
)
SourceColumn( SourceColumn(
source=Document, label=_('Cabinets'), source=Document, label=_('Cabinets'),
func=lambda context: widget_document_cabinets( func=lambda context: widget_document_cabinets(

View File

@@ -168,6 +168,7 @@ class CabinetListView(SingleObjectListView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'hide_link': True, 'hide_link': True,
'hide_object': True,
'title': _('Cabinets'), 'title': _('Cabinets'),
'no_results_icon': icon_cabinet, 'no_results_icon': icon_cabinet,
'no_results_main_link': link_cabinet_create.resolve( 'no_results_main_link': link_cabinet_create.resolve(

View File

@@ -83,10 +83,15 @@ class DocumentIndexingApp(MayanAppConfig):
) )
) )
SourceColumn(source=Index, label=_('Label'), attribute='label')
SourceColumn(source=Index, label=_('Slug'), attribute='slug')
SourceColumn( 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 widget=TwoStateWidget
) )
@@ -110,12 +115,12 @@ class DocumentIndexingApp(MayanAppConfig):
func=lambda context: node_level(context['object']) func=lambda context: node_level(context['object'])
) )
SourceColumn( SourceColumn(
attribute='enabled', label=_('Enabled'), source=IndexTemplateNode, attribute='enabled', is_sortable=True, source=IndexTemplateNode,
widget=TwoStateWidget widget=TwoStateWidget
) )
SourceColumn( SourceColumn(
attribute='enabled', label=_('Has document links?'), attribute='enabled', is_sortable=True, source=IndexTemplateNode,
source=IndexTemplateNode, widget=TwoStateWidget widget=TwoStateWidget
) )
SourceColumn( SourceColumn(
source=IndexInstanceNode, label=_('Level'), source=IndexInstanceNode, label=_('Level'),
@@ -135,10 +140,10 @@ class DocumentIndexingApp(MayanAppConfig):
) )
SourceColumn( SourceColumn(
source=DocumentIndexInstanceNode, label=_('Level'), label=_('Level'),
func=lambda context: get_instance_link( func=lambda context: get_instance_link(
index_instance_node=context['object'], index_instance_node=context['object'],
) ), source=DocumentIndexInstanceNode,
) )
SourceColumn( SourceColumn(
source=DocumentIndexInstanceNode, label=_('Levels'), source=DocumentIndexInstanceNode, label=_('Levels'),

View File

@@ -107,12 +107,13 @@ class DocumentParsingApp(MayanAppConfig):
) )
SourceColumn( SourceColumn(
source=DocumentVersionParseError, label=_('Document'), attribute='document_version__document',
func=lambda context: document_link(context['object'].document_version.document) is_attribute_absolute_url=True, is_identifier=True, is_sortable=True,
source=DocumentVersionParseError
) )
SourceColumn( SourceColumn(
source=DocumentVersionParseError, label=_('Added'), attribute='datetime_submitted', is_sortable=True,
attribute='datetime_submitted' source=DocumentVersionParseError
) )
SourceColumn( SourceColumn(
source=DocumentVersionParseError, label=_('Result'), source=DocumentVersionParseError, label=_('Result'),

View File

@@ -240,6 +240,10 @@ class DocumentsApp(MayanAppConfig):
document_page_thumbnail_widget = DocumentPageThumbnailWidget() document_page_thumbnail_widget = DocumentPageThumbnailWidget()
# Document # Document
SourceColumn(
attribute='label', is_object_absolute_url=True, is_identifier=True,
is_sortable=True, source=Document
)
SourceColumn( SourceColumn(
source=Document, label=_('Thumbnail'), source=Document, label=_('Thumbnail'),
func=lambda context: document_page_thumbnail_widget.render( func=lambda context: document_page_thumbnail_widget.render(
@@ -247,7 +251,7 @@ class DocumentsApp(MayanAppConfig):
) )
) )
SourceColumn( SourceColumn(
source=Document, attribute='document_type' attribute='document_type', is_sortable=True, source=Document,
) )
SourceColumn( SourceColumn(
source=Document, label=_('Pages'), source=Document, label=_('Pages'),
@@ -255,6 +259,16 @@ class DocumentsApp(MayanAppConfig):
document=context['object'] 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 # DocumentPage
SourceColumn( SourceColumn(
@@ -277,6 +291,11 @@ class DocumentsApp(MayanAppConfig):
) )
# DocumentType # DocumentType
SourceColumn(
attribute='label', is_identifier=True, is_sortable=True,
source=DocumentType
)
SourceColumn( SourceColumn(
source=DocumentType, label=_('Documents'), source=DocumentType, label=_('Documents'),
func=lambda context: context['object'].get_document_count( func=lambda context: context['object'].get_document_count(
@@ -285,20 +304,27 @@ class DocumentsApp(MayanAppConfig):
) )
SourceColumn( SourceColumn(
attribute='enabled', label=_('Enabled'), attribute='filename', is_identifier=True, is_sortable=True,
source=DocumentTypeFilename, widget=TwoStateWidget source=DocumentTypeFilename
)
SourceColumn(
attribute='enabled', is_sortable=True, source=DocumentTypeFilename,
widget=TwoStateWidget
) )
# DeletedDocument # DeletedDocument
SourceColumn(
attribute='label', is_identifier=True, is_sortable=True,
source=DeletedDocument
)
SourceColumn( SourceColumn(
source=DeletedDocument, label=_('Thumbnail'), source=DeletedDocument, label=_('Thumbnail'),
func=lambda context: document_page_thumbnail_widget.render( func=lambda context: document_page_thumbnail_widget.render(
instance=context['object'] instance=context['object']
) )
) )
SourceColumn( SourceColumn(
source=DeletedDocument, attribute='document_type' attribute='document_type', is_sortable=True, source=DeletedDocument
) )
SourceColumn( SourceColumn(
source=DeletedDocument, attribute='deleted_date_time' source=DeletedDocument, attribute='deleted_date_time'
@@ -307,7 +333,7 @@ class DocumentsApp(MayanAppConfig):
# DocumentVersion # DocumentVersion
SourceColumn( SourceColumn(
source=DocumentVersion, attribute='timestamp', is_identifier=True, source=DocumentVersion, attribute='timestamp', is_identifier=True,
is_absolute_url=True is_object_absolute_url=True
) )
SourceColumn( SourceColumn(
source=DocumentVersion, label=_('Thumbnail'), source=DocumentVersion, label=_('Thumbnail'),
@@ -322,25 +348,13 @@ class DocumentsApp(MayanAppConfig):
) )
) )
SourceColumn( SourceColumn(
source=DocumentVersion, attribute='mimetype' attribute='mimetype', is_sortable=True, source=DocumentVersion
) )
SourceColumn( SourceColumn(
source=DocumentVersion, attribute='encoding' attribute='encoding', is_sortable=True, source=DocumentVersion
) )
SourceColumn( SourceColumn(
source=DocumentVersion, attribute='comment' attribute='comment', is_sortable=True, source=DocumentVersion
)
# 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()
) )
Template( Template(

View File

@@ -383,25 +383,33 @@ link_document_type_edit = Link(
view='documents:document_type_edit', view='documents:document_type_edit',
) )
link_document_type_filename_create = Link( 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,), permissions=(permission_document_type_edit,),
text=_('Add quick label to document type'), text=_('Add quick label to document type'),
view='documents:document_type_filename_create', view='documents:document_type_filename_create',
) )
link_document_type_filename_delete = Link( 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'), tags='dangerous', text=_('Delete'),
view='documents:document_type_filename_delete', view='documents:document_type_filename_delete',
) )
link_document_type_filename_edit = Link( 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', text=_('Edit'), view='documents:document_type_filename_edit',
) )
link_document_type_filename_list = Link( 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', text=_('Quick labels'), view='documents:document_type_filename_list',
) )
link_document_type_list = Link( link_document_type_list = Link(
icon_class_path='mayan.apps.documents.icons.icon_document_type_list',
permissions=(permission_document_type_view,), text=_('Document types'), permissions=(permission_document_type_view,), text=_('Document types'),
view='documents:document_type_list' view='documents:document_type_list'
) )

View File

@@ -62,6 +62,7 @@ class DocumentTypeListView(SingleObjectListView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'hide_link': True, 'hide_link': True,
'hide_object': True,
'no_results_icon': icon_document_type_setup, 'no_results_icon': icon_document_type_setup,
'no_results_main_link': link_document_type_create.resolve( 'no_results_main_link': link_document_type_create.resolve(
context=RequestContext(request=self.request) context=RequestContext(request=self.request)
@@ -225,6 +226,7 @@ class DocumentTypeFilenameListView(SingleObjectListView):
return { return {
'document_type': self.get_document_type(), 'document_type': self.get_document_type(),
'hide_link': True, 'hide_link': True,
'hide_object': True,
'navigation_object_list': ('document_type',), 'navigation_object_list': ('document_type',),
'no_results_icon': icon_document_type_filename, 'no_results_icon': icon_document_type_filename,
'no_results_main_link': link_document_type_filename_create.resolve( 'no_results_main_link': link_document_type_filename_create.resolve(

View File

@@ -84,6 +84,7 @@ class DocumentListView(SingleObjectListView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'hide_links': True, 'hide_links': True,
'hide_object': True,
'list_as_items': True, 'list_as_items': True,
'no_results_icon': icon_document_list, 'no_results_icon': icon_document_list,
'no_results_text': _( 'no_results_text': _(
@@ -669,16 +670,16 @@ class DuplicatedDocumentListView(DocumentListView):
context = super(DuplicatedDocumentListView, self).get_extra_context() context = super(DuplicatedDocumentListView, self).get_extra_context()
context.update( context.update(
{ {
'extra_columns': ( #'extra_columns': (
{ # {
'name': _('Duplicates'), # 'name': _('Duplicates'),
'attribute': encapsulate( # 'attribute': encapsulate(
lambda document: DuplicatedDocument.objects.get( # lambda document: DuplicatedDocument.objects.get(
document=document # document=document
).documents.count() # ).documents.count()
) # )
}, # },
), #),
'no_results_icon': icon_duplicated_document_list, 'no_results_icon': icon_duplicated_document_list,
'no_results_text': _( 'no_results_text': _(
'Duplicates are documents that are composed of the exact ' 'Duplicates are documents that are composed of the exact '

View File

@@ -36,7 +36,8 @@ class EventsApp(MayanAppConfig):
StoredEventType = self.get_model(model_name='StoredEventType') StoredEventType = self.get_model(model_name='StoredEventType')
SourceColumn( SourceColumn(
source=Action, label=_('Timestamp'), attribute='timestamp' attribute='timestamp', is_identifier=True,
is_sortable=True, label=_('Date and time'), source=Action
) )
SourceColumn( SourceColumn(
func=widget_event_actor_link, label=_('Actor'), source=Action func=widget_event_actor_link, label=_('Actor'), source=Action
@@ -61,10 +62,9 @@ class EventsApp(MayanAppConfig):
) )
SourceColumn( SourceColumn(
source=Notification, label=_('Timestamp'), attribute='action__timestamp', is_identifier=True,
attribute='action.timestamp' is_sortable=True, label=_('Date and time'), source=Notification
) )
SourceColumn( SourceColumn(
func=widget_event_actor_link, label=_('Actor'), func=widget_event_actor_link, label=_('Actor'),
kwargs={'attribute': 'action'}, source=Notification kwargs={'attribute': 'action'}, source=Notification
@@ -79,8 +79,8 @@ class EventsApp(MayanAppConfig):
) )
SourceColumn( SourceColumn(
attribute='read', label=_('Seen'), source=Notification, attribute='read', is_sortable=True, label=_('Seen'),
widget=TwoStateWidget source=Notification, widget=TwoStateWidget
) )
menu_main.bind_links( menu_main.bind_links(

View File

@@ -162,14 +162,25 @@ class MetadataApp(MayanAppConfig):
) )
SourceColumn( SourceColumn(
source=DocumentMetadata, label=_('Value'), attribute='metadata_type', is_identifier=True,
attribute='value' is_sortable=True, source=DocumentMetadata
) )
SourceColumn( SourceColumn(
attribute='is_required', label=_('Required'), attribute='value', is_sortable=True, source=DocumentMetadata
source=DocumentMetadata, widget=TwoStateWidget
) )
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( app.conf.CELERY_QUEUES.append(
Queue('metadata', Exchange('metadata'), routing_key='metadata'), Queue('metadata', Exchange('metadata'), routing_key='metadata'),
) )

View File

@@ -412,6 +412,7 @@ class DocumentMetadataListView(SingleObjectListView):
document = self.get_document() document = self.get_document()
return { return {
'hide_link': True, 'hide_link': True,
'hide_object': True,
'object': document, 'object': document,
'no_results_icon': icon_metadata, 'no_results_icon': icon_metadata,
'no_results_main_link': link_metadata_add.resolve( 'no_results_main_link': link_metadata_add.resolve(
@@ -637,13 +638,8 @@ class MetadataTypeListView(SingleObjectListView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'extra_columns': (
{
'name': _('Internal name'),
'attribute': 'name',
},
),
'hide_link': True, 'hide_link': True,
'hide_object': True,
'no_results_icon': icon_metadata, 'no_results_icon': icon_metadata,
'no_results_main_link': link_setup_metadata_type_create.resolve( 'no_results_main_link': link_setup_metadata_type_create.resolve(
context=RequestContext(request=self.request) context=RequestContext(request=self.request)

View File

@@ -8,6 +8,7 @@ from mayan.apps.acls.classes import ModelPermission
from mayan.apps.acls.links import link_acl_list from mayan.apps.acls.links import link_acl_list
from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view from mayan.apps.acls.permissions import permission_acl_edit, permission_acl_view
from mayan.apps.common.apps import MayanAppConfig from mayan.apps.common.apps import MayanAppConfig
from mayan.apps.common.html_widgets import TwoStateWidget
from mayan.apps.common.menus import ( from mayan.apps.common.menus import (
menu_list_facet, menu_object, menu_secondary, menu_setup menu_list_facet, menu_object, menu_secondary, menu_setup
) )
@@ -45,15 +46,20 @@ class MOTDApp(MayanAppConfig):
) )
) )
SourceColumn( SourceColumn(
source=Message, label=_('Enabled'), attribute='enabled' attribute='label', is_identifier=True, is_sortable=True,
source=Message
) )
SourceColumn( SourceColumn(
source=Message, label=_('Start date time'), attribute='enabled', include_label=True, is_sortable=True,
func=lambda context: context['object'].start_datetime or _('None') source=Message, widget=TwoStateWidget
) )
SourceColumn( SourceColumn(
source=Message, label=_('End date time'), attribute='start_datetime', empty_value=_('None'),
func=lambda context: context['object'].end_datetime or _('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( menu_list_facet.bind_links(

View File

@@ -4,23 +4,26 @@ from django.utils.translation import ugettext_lazy as _
from mayan.apps.navigation import Link, get_cascade_condition from mayan.apps.navigation import Link, get_cascade_condition
from .icons import icon_message_create, icon_message_list
from .permissions import ( from .permissions import (
permission_message_create, permission_message_delete, permission_message_create, permission_message_delete,
permission_message_edit, permission_message_view permission_message_edit, permission_message_view
) )
link_message_create = Link( 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' text=_('Create message'), view='motd:message_create'
) )
link_message_delete = Link( 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' tags='dangerous', text=_('Delete'), view='motd:message_delete'
) )
link_message_edit = Link( 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' view='motd:message_edit'
) )
link_message_list = Link( link_message_list = Link(
@@ -28,6 +31,7 @@ link_message_list = Link(
app_label='motd', model_name='Message', app_label='motd', model_name='Message',
object_permission=permission_message_view, object_permission=permission_message_view,
view_permission=permission_message_create, 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' view='motd:message_list'
) )

View File

@@ -66,6 +66,7 @@ class MessageListView(SingleObjectListView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'hide_link': True, 'hide_link': True,
'hide_object': True,
'no_results_icon': icon_message_list, 'no_results_icon': icon_message_list,
'no_results_main_link': link_message_create.resolve( 'no_results_main_link': link_message_create.resolve(
context=RequestContext(request=self.request) context=RequestContext(request=self.request)

View File

@@ -103,12 +103,12 @@ class OCRApp(MayanAppConfig):
) )
SourceColumn( SourceColumn(
source=DocumentVersionOCRError, label=_('Document'), attribute='document_version__document', is_attribute_absolute_url=True,
func=lambda context: document_link(context['object'].document_version.document) is_identifier=True, is_sortable=True, source=DocumentVersionOCRError
) )
SourceColumn( SourceColumn(
source=DocumentVersionOCRError, label=_('Added'), attribute='datetime_submitted', is_sortable=True,
attribute='datetime_submitted' label=_('Date and time'), source=DocumentVersionOCRError
) )
SourceColumn( SourceColumn(
source=DocumentVersionOCRError, label=_('Result'), source=DocumentVersionOCRError, label=_('Result'),

View File

@@ -15,9 +15,8 @@ from mayan.apps.common.signals import perform_upgrade
from .handlers import purge_permissions from .handlers import purge_permissions
from .links import ( from .links import (
link_group_roles, link_permission_grant, link_permission_revoke, link_group_roles, link_role_create, link_role_delete, link_role_edit,
link_role_create, link_role_delete, link_role_edit, link_role_groups, link_role_groups, link_role_list, link_role_permissions
link_role_list, link_role_permissions
) )
from .permissions import ( from .permissions import (
permission_role_delete, permission_role_edit, permission_role_view permission_role_delete, permission_role_edit, permission_role_view
@@ -60,10 +59,6 @@ class PermissionsApp(MayanAppConfig):
link_role_delete, link_role_edit link_role_delete, link_role_edit
), sources=(Role,) ), sources=(Role,)
) )
menu_multi_item.bind_links(
links=(link_permission_grant, link_permission_revoke),
sources=('permissions:role_permissions',)
)
menu_secondary.bind_links( menu_secondary.bind_links(
links=(link_role_list, link_role_create), links=(link_role_list, link_role_create),
sources=(Role, 'permissions:role_create', 'permissions:role_list') sources=(Role, 'permissions:role_create', 'permissions:role_list')

View File

@@ -5,46 +5,49 @@ from django.utils.translation import ugettext_lazy as _
from mayan.apps.navigation import Link from mayan.apps.navigation import Link
from mayan.apps.user_management.permissions import permission_group_edit from mayan.apps.user_management.permissions import permission_group_edit
from .icons import icon_role_create, icon_role_list
from .permissions import ( from .permissions import (
permission_role_create, permission_role_delete, permission_role_edit, permission_role_create, permission_role_delete, permission_role_edit,
permission_role_view permission_role_view
) )
link_group_roles = Link( 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', 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( 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' text=_('Create new role'), view='permissions:role_create'
) )
link_role_delete = Link( 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', text=_('Delete'), view='permissions:role_delete',
) )
link_role_edit = Link( 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', view='permissions:role_edit',
) )
link_role_list = Link( 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' text=_('Roles'), view='permissions:role_list'
) )
link_role_groups = Link( 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', view='permissions:role_groups',
) )
link_role_permissions = Link( link_role_permissions = Link(
args='object.id', args='object.id',
icon_class_path='mayan.apps.permissions.icons.icon_role_permissions',
permissions=(permission_role_edit,), permissions=(permission_role_edit,),
text=_('Role permissions'), view='permissions:role_permissions', text=_('Role permissions'), view='permissions:role_permissions',
) )

View File

@@ -67,17 +67,12 @@ class SourcesApp(MayanAppConfig):
) )
SourceColumn( SourceColumn(
attribute='label', is_identifier=True, attribute='label', is_identifier=True, is_sortable=True,
source=Source source=Source
) )
SourceColumn( SourceColumn(
attribute='class_fullname', label=_('Type'), source=Source attribute='class_fullname', label=_('Type'), source=Source
) )
SourceColumn(
attribute='enabled', source=Source,
widget=TwoStateWidget
)
SourceColumn( SourceColumn(
attribute='enabled', is_sortable=True, source=Source, attribute='enabled', is_sortable=True, source=Source,
widget=TwoStateWidget widget=TwoStateWidget

View File

@@ -102,7 +102,8 @@ class TagsApp(MayanAppConfig):
) )
SourceColumn( SourceColumn(
source=DocumentTag, attribute='label' attribute='label', is_identifier=True, is_sortable=True,
source=DocumentTag
) )
SourceColumn( SourceColumn(
source=DocumentTag, attribute='get_preview_widget' source=DocumentTag, attribute='get_preview_widget'
@@ -124,7 +125,8 @@ class TagsApp(MayanAppConfig):
) )
SourceColumn( SourceColumn(
source=Tag, attribute='label' attribute='label', is_identifier=True, is_sortable=True,
source=Tag
) )
SourceColumn( SourceColumn(
source=Tag, attribute='get_preview_widget' source=Tag, attribute='get_preview_widget'

View File

@@ -9,7 +9,7 @@ from .api_views import (
from .views import ( from .views import (
DocumentTagListView, TagAttachActionView, TagCreateView, DocumentTagListView, TagAttachActionView, TagCreateView,
TagDeleteActionView, TagEditView, TagListView, TagRemoveActionView, TagDeleteActionView, TagEditView, TagListView, TagRemoveActionView,
TagTaggedItemListView TagDocumentListView
) )
urlpatterns = [ urlpatterns = [
@@ -24,7 +24,7 @@ urlpatterns = [
name='tag_edit' name='tag_edit'
), ),
url( url(
regex=r'^(?P<pk>\d+)/documents/$', view=TagTaggedItemListView.as_view(), regex=r'^(?P<pk>\d+)/documents/$', view=TagDocumentListView.as_view(),
name='tag_document_list' name='tag_document_list'
), ),
url( url(

View File

@@ -225,7 +225,7 @@ class TagListView(SingleObjectListView):
return Tag.objects.all() return Tag.objects.all()
class TagTaggedItemListView(DocumentListView): class TagDocumentListView(DocumentListView):
def get_tag(self): def get_tag(self):
return get_object_or_404(klass=Tag, pk=self.kwargs['pk']) return get_object_or_404(klass=Tag, pk=self.kwargs['pk'])
@@ -233,7 +233,7 @@ class TagTaggedItemListView(DocumentListView):
return self.get_tag().documents.all() return self.get_tag().documents.all()
def get_extra_context(self): def get_extra_context(self):
context = super(TagTaggedItemListView, self).get_extra_context() context = super(TagDocumentListView, self).get_extra_context()
context.update( context.update(
{ {
'column_class': 'col-xs-12 col-sm-6 col-md-4 col-lg-3', 'column_class': 'col-xs-12 col-sm-6 col-md-4 col-lg-3',

View File

@@ -29,9 +29,9 @@ from .events import (
from .handlers import handler_initialize_new_user_options from .handlers import handler_initialize_new_user_options
from .links import ( from .links import (
link_current_user_details, link_current_user_edit, link_group_create, 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_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_multiple_set_password, link_user_set_options,
link_user_set_password, link_user_setup, separator_user_label, link_user_set_password, link_user_setup, separator_user_label,
text_user_label text_user_label
@@ -120,25 +120,39 @@ class UserManagementApp(MayanAppConfig):
permission_user_view permission_user_view
) )
) )
SourceColumn( 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( 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( SourceColumn(
source=User, label=_('Email'), attribute='email' attribute='first_name', is_sortable=True, label=_('First name'),
source=User
) )
SourceColumn( SourceColumn(
attribute='is_active', label=_('Active'), source=User, attribute='last_name', is_sortable=True, label=_('Last name'),
widget=TwoStateWidget 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( SourceColumn(
attribute='has_usable_password', label=_('Has usable password?'), attribute='has_usable_password', label=_('Has usable password?'),
source=User, widget=TwoStateWidget source=User, widget=TwoStateWidget
) )
# Silence UnorderedObjectListWarning # Silence UnorderedObjectListWarning
# "Pagination may yield inconsistent result" # "Pagination may yield inconsistent result"
# TODO: Remove on Django 2.x # TODO: Remove on Django 2.x
@@ -153,14 +167,14 @@ class UserManagementApp(MayanAppConfig):
links=( links=(
link_acl_list, link_events_for_object, link_acl_list, link_events_for_object,
link_object_event_types_user_subcriptions_list, link_object_event_types_user_subcriptions_list,
link_group_members, link_group_user_list,
), sources=(Group,) ), sources=(Group,)
) )
menu_list_facet.bind_links( menu_list_facet.bind_links(
links=( links=(
link_acl_list, link_events_for_object, link_acl_list, link_events_for_object,
link_object_event_types_user_subcriptions_list, link_object_event_types_user_subcriptions_list,
link_user_groups, link_user_set_options link_user_group_list, link_user_set_options
), sources=(User,) ), sources=(User,)
) )
menu_multi_item.bind_links( menu_multi_item.bind_links(

View File

@@ -4,10 +4,6 @@ from django.utils.translation import ugettext_lazy as _
from mayan.apps.navigation.classes import Link, Separator, Text 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 ( from .permissions import (
permission_group_create, permission_group_delete, permission_group_edit, permission_group_create, permission_group_delete, permission_group_edit,
permission_group_view, permission_user_create, permission_user_delete, permission_group_view, permission_user_create, permission_user_delete,
@@ -16,76 +12,100 @@ from .permissions import (
from .utils import get_user_label_text from .utils import get_user_label_text
link_current_user_details = Link( link_current_user_details = Link(
icon_class=icon_current_user_details, text=_('User details'), icon_class_path='mayan.apps.user_management.icons.icon_current_user_details',
view='user_management:current_user_details' text=_('User details'), view='user_management:current_user_details'
) )
link_current_user_edit = Link( link_current_user_edit = Link(
icon_class=icon_current_user_edit, text=_('Edit details'), icon_class_path='mayan.apps.user_management.icons.icon_current_user_edit',
view='user_management:current_user_edit' text=_('Edit details'), view='user_management:current_user_edit'
) )
link_group_create = Link( link_group_create = Link(
icon_class=icon_group_create, permissions=(permission_group_create,), icon_class_path='mayan.apps.user_management.icons.icon_group_create',
text=_('Create new group'), view='user_management:group_create' permissions=(permission_group_create,), text=_('Create new group'),
view='user_management:group_create'
) )
link_group_delete = Link( 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', text=_('Delete'), view='user_management:group_delete',
) )
link_group_edit = Link( 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', view='user_management:group_edit',
) )
link_group_list = Link( link_group_list = Link(
icon_class_path='mayan.apps.user_management.icons.icon_group_list',
permissions=(permission_group_view,), text=_('Groups'), permissions=(permission_group_view,), text=_('Groups'),
view='user_management:group_list' view='user_management:group_list'
) )
link_group_members = Link( link_group_user_list = Link(
args='object.id', permissions=(permission_group_edit,), text=_('Users'), 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', view='user_management:group_members',
) )
link_group_setup = Link( link_group_setup = Link(
icon_class=icon_group_setup, permissions=(permission_group_view,), icon_class_path='mayan.apps.user_management.icons.icon_group_setup',
text=_('Groups'), view='user_management:group_list' permissions=(permission_group_view,), text=_('Groups'),
view='user_management:group_list'
) )
link_user_create = Link( link_user_create = Link(
icon_class=icon_user_create, permissions=(permission_user_create,), icon_class_path='mayan.apps.user_management.icons.icon_user_create',
text=_('Create new user'), view='user_management:user_create' permissions=(permission_user_create,), text=_('Create new user'),
view='user_management:user_create'
) )
link_user_delete = Link( 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', text=_('Delete'), view='user_management:user_delete',
) )
link_user_edit = Link( 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', view='user_management:user_edit',
) )
link_user_groups = Link( link_user_group_list = Link(
args='object.id', permissions=(permission_user_edit,), text=_('Groups'), 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', view='user_management:user_groups',
) )
link_user_list = Link( link_user_list = Link(
icon_class_path='mayan.apps.user_management.icons.icon_user_list',
permissions=(permission_user_view,), text=_('Users'), permissions=(permission_user_view,), text=_('Users'),
view='user_management:user_list' view='user_management:user_list'
) )
link_user_multiple_delete = Link( link_user_multiple_delete = Link(
icon_class_path='mayan.apps.user_management.icons.icon_user_delete',
permissions=(permission_user_delete,), tags='dangerous', text=_('Delete'), permissions=(permission_user_delete,), tags='dangerous', text=_('Delete'),
view='user_management:user_multiple_delete' view='user_management:user_multiple_delete'
) )
link_user_multiple_set_password = Link( 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'), permissions=(permission_user_edit,), text=_('Set password'),
view='user_management:user_multiple_set_password' view='user_management:user_multiple_set_password'
) )
link_user_set_options = Link( 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', text=_('User options'), view='user_management:user_options',
) )
link_user_set_password = Link( 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', text=_('Set password'), view='user_management:user_set_password',
) )
link_user_setup = Link( link_user_setup = Link(
icon_class=icon_user_setup, permissions=(permission_user_view,), icon_class_path='mayan.apps.user_management.icons.icon_user_setup',
text=_('Users'), view='user_management:user_list' permissions=(permission_user_view,), text=_('Users'),
view='user_management:user_list'
) )
separator_user_label = Separator() separator_user_label = Separator()
text_user_label = Text(text=get_user_label_text) text_user_label = Text(text=get_user_label_text)

View File

@@ -89,6 +89,7 @@ class GroupListView(SingleObjectListView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'hide_link': True, 'hide_link': True,
'hide_object': True,
'no_results_icon': icon_group_setup, 'no_results_icon': icon_group_setup,
'no_results_main_link': link_group_create.resolve( 'no_results_main_link': link_group_create.resolve(
context=RequestContext(request=self.request) context=RequestContext(request=self.request)
@@ -339,6 +340,7 @@ class UserListView(SingleObjectListView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'hide_link': True, 'hide_link': True,
'hide_object': True,
'no_results_icon': icon_user_setup, 'no_results_icon': icon_user_setup,
'no_results_main_link': link_user_create.resolve( 'no_results_main_link': link_user_create.resolve(
context=RequestContext(request=self.request) context=RequestContext(request=self.request)