diff --git a/mayan/apps/common/widgets.py b/mayan/apps/common/widgets.py index 3a7e111233..d0ed880e73 100644 --- a/mayan/apps/common/widgets.py +++ b/mayan/apps/common/widgets.py @@ -1,6 +1,7 @@ from __future__ import unicode_literals from django import forms +from django.template import Context, Template from django.utils.encoding import force_text from django.utils.html import format_html from django.utils.safestring import mark_safe @@ -64,6 +65,32 @@ class EmailInput(forms.widgets.Input): return super(EmailInput, self).render(name, value, attrs=attrs) +class ObjectLinkWidget(object): + template_string = '{{ object_type }}{{ label }}' + + def __init__(self): + self.template = Template(template_string=self.template_string) + + def render(self, name=None, value=None): + label = '' + object_type = '' + url = None + + if value: + label = force_text(value) + object_type = '{}: '.format(value._meta.verbose_name) + try: + url = value.get_absolute_url() + except AttributeError: + url = None + + return self.template.render( + context=Context( + {'label': label, 'object_type': object_type, 'url': url or '#'} + ) + ) + + class PlainWidget(forms.widgets.Widget): """ Class to define a form widget that effectively nulls the htmls of a diff --git a/mayan/apps/events/apps.py b/mayan/apps/events/apps.py index f166678c41..f729268503 100644 --- a/mayan/apps/events/apps.py +++ b/mayan/apps/events/apps.py @@ -7,7 +7,7 @@ from mayan.apps.common import ( MayanAppConfig, menu_object, menu_secondary, menu_tools, menu_topbar, menu_user ) -from mayan.apps.common.widgets import TwoStateWidget +from mayan.apps.common.widgets import ObjectLinkWidget, TwoStateWidget from mayan.apps.navigation import SourceColumn from .licenses import * # NOQA @@ -17,7 +17,7 @@ from .links import ( link_notification_mark_read_all, link_user_notifications_list ) from .widgets import ( - widget_event_object_link, widget_event_type_link, widget_event_user_link + widget_event_actor_link, widget_event_type_link ) @@ -40,18 +40,19 @@ class EventsApp(MayanAppConfig): is_sortable=True, label=_('Date and time'), source=Action ) SourceColumn( - func=widget_event_user_link, label=_('Actor'), source=Action + func=widget_event_actor_link, label=_('Actor'), source=Action ) SourceColumn( func=widget_event_type_link, label=_('Event'), source=Action ) SourceColumn( - func=widget_event_object_link, kwargs={ - 'attribute': 'action_object' - }, label=_('Action object'), source=Action + attribute='action_object', label=_('Action object'), source=Action, + widget=ObjectLinkWidget ) + SourceColumn( - func=widget_event_object_link, label=_('Target'), source=Action + attribute='target', label=_('Target'), source=Action, + widget=ObjectLinkWidget ) SourceColumn( @@ -66,7 +67,7 @@ class EventsApp(MayanAppConfig): is_sortable=True, label=_('Date and time'), source=Notification ) SourceColumn( - func=widget_event_user_link, kwargs={'attribute': 'action'}, + func=widget_event_actor_link, kwargs={'attribute': 'action'}, label=_('Actor'), source=Notification ) SourceColumn( @@ -74,10 +75,10 @@ class EventsApp(MayanAppConfig): label=_('Event'), source=Notification ) SourceColumn( - func=widget_event_object_link, kwargs={ - 'attribute': 'action.target' - }, label=_('Target'), source=Notification + attribute='action.target', label=_('Target'), source=Notification, + widget=ObjectLinkWidget ) + SourceColumn( attribute='read', is_sortable=True, label=_('Seen'), source=Notification, widget=TwoStateWidget @@ -97,5 +98,5 @@ class EventsApp(MayanAppConfig): menu_user.bind_links( links=( link_event_types_subscriptions_list, link_current_user_events - ) + ), position=50 ) diff --git a/mayan/apps/events/urls.py b/mayan/apps/events/urls.py index 30910dc16e..e60cb1cc71 100644 --- a/mayan/apps/events/urls.py +++ b/mayan/apps/events/urls.py @@ -11,7 +11,7 @@ from .views import ( CurrentUserEventListView, EventListView, EventTypeSubscriptionListView, NotificationListView, NotificationMarkRead, NotificationMarkReadAll, ObjectEventListView, ObjectEventTypeSubscriptionListView, - UserEventListView, VerbEventListView + VerbEventListView ) urlpatterns = [ @@ -41,10 +41,6 @@ urlpatterns = [ r'^user/$', CurrentUserEventListView.as_view(), name='current_user_events' ), - url( - r'^user/(?P\d+)/$', UserEventListView.as_view(), - name='user_events' - ), url( r'^user/event_types/subscriptions/$', EventTypeSubscriptionListView.as_view(), diff --git a/mayan/apps/events/views.py b/mayan/apps/events/views.py index 9c084f0699..8b42157733 100644 --- a/mayan/apps/events/views.py +++ b/mayan/apps/events/views.py @@ -256,26 +256,7 @@ class ObjectEventTypeSubscriptionListView(FormView): return ModelEventType.get_for_instance(instance=self.get_object()) -class UserEventListView(ObjectEventListView): - def get_extra_context(self): - context = super(UserEventListView, self).get_extra_context() - context.update( - { - 'no_results_text': _( - 'Events are actions that have been performed to this ' - 'user account or by this user account.' - ), - 'no_results_title': _('There are no events for this user'), - 'object': self.get_object(), - 'title': _( - 'Events for user: %s' - ) % self.get_object(), - } - ) - return context - - -class CurrentUserEventListView(UserEventListView): +class CurrentUserEventListView(ObjectEventListView): def get_object(self): return self.request.user diff --git a/mayan/apps/events/widgets.py b/mayan/apps/events/widgets.py index 0563992c22..4d8109480b 100644 --- a/mayan/apps/events/widgets.py +++ b/mayan/apps/events/widgets.py @@ -1,5 +1,7 @@ from __future__ import unicode_literals +from django.apps import apps +from django.template import Context, Template from django.urls import reverse from django.utils.encoding import force_text from django.utils.safestring import mark_safe @@ -10,26 +12,37 @@ from mayan.apps.common.utils import resolve_attribute from .classes import EventType -def widget_event_object_link(context, attribute='target'): +def widget_event_actor_link(context, attribute=None): entry = context['object'] - label = '' - url = '#' - obj_type = '' - obj = resolve_attribute(obj=entry, attribute=attribute) - - if obj: - obj_type = '{}: '.format(obj._meta.verbose_name) - if hasattr(obj, 'get_absolute_url'): - url = obj.get_absolute_url() - label = force_text(obj) - - return mark_safe( - '%(obj_type)s%(label)s' % { - 'url': url, 'label': label, 'obj_type': obj_type - } + ContentType = apps.get_model( + app_label='contenttypes', model_name='ContentType' ) + if attribute: + entry = getattr(entry, attribute) + + if entry.actor == entry.target: + label = _('System') + url = None + else: + label = entry.actor + content_type = ContentType.objects.get_for_model(model=entry.actor) + + url = reverse( + viewname='events:events_for_object', kwargs={ + 'app_label': content_type.app_label, 'model': content_type.model, + 'object_id': entry.actor.pk + } + ) + + if url: + return Template( + template_string='{{ label }}' + ).render(context=Context({'label': entry.actor, 'url': url})) + else: + return label + def widget_event_type_link(context, attribute=None): entry = context['object'] @@ -43,20 +56,3 @@ def widget_event_type_link(context, attribute=None): 'label': EventType.get(name=entry.verb) } ) - - -def widget_event_user_link(context, attribute=None): - entry = context['object'] - - if attribute: - entry = getattr(entry, attribute) - - if entry.actor == entry.target: - return _('System') - else: - return mark_safe( - '%(label)s' % { - 'url': reverse('events:user_events', kwargs={'pk': entry.actor.pk}), - 'label': entry.actor - } - )