diff --git a/mayan/apps/document_states/forms.py b/mayan/apps/document_states/forms.py index cc7c76953b..971b17bd2d 100644 --- a/mayan/apps/document_states/forms.py +++ b/mayan/apps/document_states/forms.py @@ -178,7 +178,12 @@ class WorkflowInstanceTransitionForm(forms.Form): label=_('Transition'), queryset=WorkflowTransition.objects.none() ) comment = forms.CharField( - label=_('Comment'), required=False, widget=forms.widgets.Textarea() + help_text=_('Optional comment to attach to the transition.'), + label=_('Comment'), required=False, widget=forms.widgets.Textarea( + attrs={ + 'rows': 3 + } + ) ) diff --git a/mayan/apps/document_states/models.py b/mayan/apps/document_states/models.py index ccfeec72a0..d718fd7b5f 100644 --- a/mayan/apps/document_states/models.py +++ b/mayan/apps/document_states/models.py @@ -101,6 +101,7 @@ class Workflow(models.Model): }, format='png' ) + action_cache = {} state_cache = {} transition_cache = [] @@ -112,6 +113,14 @@ class Workflow(models.Model): 'connections': {'origin': 0, 'destination': 0} } + for action in state.actions.all(): + action_cache['a{}'.format(action.pk)] = { + 'name': 'a{}'.format(action.pk), + 'label': action.label, + 'state': 's{}'.format(state.pk), + 'when': action.when, + } + for transition in self.transitions.all(): transition_cache.append( { @@ -128,12 +137,33 @@ class Workflow(models.Model): 'name': value['name'], 'label': value['label'], 'shape': 'doublecircle' if value['connections']['origin'] == 0 or value['connections']['destination'] == 0 or value['initial'] else 'circle', + 'style': 'filled' if value['initial'] else '', + 'fillcolor': '#eeeeee', } diagram.node(**kwargs) for transition in transition_cache: diagram.edge(**transition) + for key, value in action_cache.items(): + kwargs = { + 'name': value['name'], + 'label': value['label'], + 'shape': 'box', + } + diagram.node(**kwargs) + diagram.edge( + **{ + 'head_name': '{}'.format(value['name']), + 'tail_name': '{}'.format(value['state']), + 'label': 'On entry' if value['when'] == WORKFLOW_ACTION_ON_ENTRY else 'On exit', + 'arrowhead': 'dot', + 'dir': 'both', + 'arrowtail': 'dot', + 'style': 'dashed', + } + ) + return diagram.pipe() def save(self, *args, **kwargs): diff --git a/mayan/apps/permissions/apps.py b/mayan/apps/permissions/apps.py index 9bdf738bdb..c1c7392966 100644 --- a/mayan/apps/permissions/apps.py +++ b/mayan/apps/permissions/apps.py @@ -12,6 +12,7 @@ from mayan.apps.common.menus import ( menu_list_facet, menu_object, menu_secondary, menu_setup ) from mayan.apps.common.signals import perform_upgrade +from mayan.apps.dashboards.dashboards import dashboard_main from mayan.apps.events.classes import ModelEventType from mayan.apps.events.links import ( link_events_for_object, link_object_event_types_user_subcriptions_list @@ -19,6 +20,7 @@ from mayan.apps.events.links import ( from mayan.apps.events.permissions import permission_events_view from mayan.apps.navigation.classes import SourceColumn +from .dashboard_widgets import DashboardWidgetRoleTotal from .events import event_role_created, event_role_edited from .handlers import handler_purge_permissions from .links import ( @@ -66,6 +68,10 @@ class PermissionsApp(MayanAppConfig): attribute='label', is_identifier=True, is_sortable=True, source=Role ) + dashboard_main.add_widget( + widget=DashboardWidgetRoleTotal, order=99 + ) + menu_list_facet.bind_links( links=( link_acl_list, link_events_for_object, diff --git a/mayan/apps/permissions/dashboard_widgets.py b/mayan/apps/permissions/dashboard_widgets.py new file mode 100644 index 0000000000..b06990a753 --- /dev/null +++ b/mayan/apps/permissions/dashboard_widgets.py @@ -0,0 +1,30 @@ +from __future__ import absolute_import, unicode_literals + +from django.apps import apps +from django.urls import reverse_lazy +from django.utils.translation import ugettext_lazy as _ + +from mayan.apps.dashboards.classes import DashboardWidgetNumeric + +from .icons import icon_role_list +from .permissions import permission_role_view + + +class DashboardWidgetRoleTotal(DashboardWidgetNumeric): + icon_class = icon_role_list + label = _('Total roles') + link = reverse_lazy(viewname='permissions:role_list') + + def render(self, request): + AccessControlList = apps.get_model( + app_label='acls', model_name='AccessControlList' + ) + Role = apps.get_model( + app_label='permissions', model_name='Role' + ) + + self.count = AccessControlList.objects.restrict_queryset( + permission=permission_role_view, user=request.user, + queryset=Role.objects.all() + ).count() + return super(DashboardWidgetRoleTotal, self).render(request) diff --git a/mayan/apps/user_management/apps.py b/mayan/apps/user_management/apps.py index 9415f0e44b..22ac437887 100644 --- a/mayan/apps/user_management/apps.py +++ b/mayan/apps/user_management/apps.py @@ -16,6 +16,7 @@ from mayan.apps.common.menus import ( menu_list_facet, menu_multi_item, menu_object, menu_secondary, menu_setup, menu_user ) +from mayan.apps.dashboards.dashboards import dashboard_main from mayan.apps.events.classes import ModelEventType from mayan.apps.events.links import ( link_events_for_object, link_object_event_types_user_subcriptions_list @@ -25,6 +26,9 @@ from mayan.apps.metadata.classes import MetadataLookup from mayan.apps.navigation.classes import SourceColumn from mayan.apps.rest_api.fields import DynamicSerializerField +from .dashboard_widgets import ( + DashboardWidgetGroupTotal, DashboardWidgetUserTotal +) from .events import ( event_group_created, event_group_edited, event_user_created, event_user_edited @@ -206,6 +210,13 @@ class UserManagementApp(MayanAppConfig): ) User.add_to_class(name='save', value=get_method_user_save()) + dashboard_main.add_widget( + widget=DashboardWidgetUserTotal, order=99 + ) + dashboard_main.add_widget( + widget=DashboardWidgetGroupTotal, order=99 + ) + menu_list_facet.bind_links( links=( link_acl_list, link_events_for_object, diff --git a/mayan/apps/user_management/dashboard_widgets.py b/mayan/apps/user_management/dashboard_widgets.py new file mode 100644 index 0000000000..29d96bab49 --- /dev/null +++ b/mayan/apps/user_management/dashboard_widgets.py @@ -0,0 +1,46 @@ +from __future__ import absolute_import, unicode_literals + +from django.apps import apps +from django.contrib.auth import get_user_model +from django.urls import reverse_lazy +from django.utils.translation import ugettext_lazy as _ + +from mayan.apps.dashboards.classes import DashboardWidgetNumeric + +from .icons import icon_group_list, icon_user_list +from .permissions import permission_group_view, permission_user_view + + +class DashboardWidgetUserTotal(DashboardWidgetNumeric): + icon_class = icon_user_list + label = _('Total users') + link = reverse_lazy(viewname='user_management:user_list') + + def render(self, request): + AccessControlList = apps.get_model( + app_label='acls', model_name='AccessControlList' + ) + self.count = AccessControlList.objects.restrict_queryset( + permission=permission_user_view, user=request.user, + queryset=get_user_model().objects.all() + ).count() + return super(DashboardWidgetUserTotal, self).render(request) + + +class DashboardWidgetGroupTotal(DashboardWidgetNumeric): + icon_class = icon_group_list + label = _('Total groups') + link = reverse_lazy(viewname='user_management:group_list') + + def render(self, request): + AccessControlList = apps.get_model( + app_label='acls', model_name='AccessControlList' + ) + Group = apps.get_model( + app_label='auth', model_name='Group' + ) + self.count = AccessControlList.objects.restrict_queryset( + permission=permission_group_view, user=request.user, + queryset=Group.objects.all() + ).count() + return super(DashboardWidgetGroupTotal, self).render(request)