Add workflows per document type view

Make workflows, workflows states, workflow transitions column
sortable. Show completion and intial state in the workflow
proxy instance menu list.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
Roberto Rosario
2019-05-04 21:26:12 -04:00
parent c9b5d2794e
commit 99b180f269
9 changed files with 148 additions and 31 deletions

View File

@@ -227,6 +227,12 @@
the new AddRemove view.
* Add the workflow created and edited events.
* Remove AssignRemove View.
* Add view to setup workflows per document type
from the document type side.
* Make workflows, workflows states, workflow
transitions column sortable.
* Show completion and intial state in the
workflow proxy instance menu list.
3.1.11 (2019-04-XX)
===================

View File

@@ -260,6 +260,12 @@ Other changes
the new AddRemove view.
* Add the workflow created and edited events.
* Remove AssignRemove View.
* Add view to setup workflows per document type
from the document type side.
* Make workflows, workflows states, workflow
transitions column sortable.
* Show completion and intial state in the
workflow proxy instance menu list.
Removals
--------

View File

@@ -31,10 +31,11 @@ from .handlers import (
handler_index_document, handler_launch_workflow, handler_trigger_transition
)
from .links import (
link_document_workflow_instance_list, link_setup_workflow_document_types,
link_setup_workflow_create, link_setup_workflow_delete,
link_setup_workflow_edit, link_setup_workflow_list,
link_setup_workflow_states, link_setup_workflow_state_action_delete,
link_document_workflow_instance_list, link_setup_document_type_workflows,
link_setup_workflow_document_types, link_setup_workflow_create,
link_setup_workflow_delete, link_setup_workflow_edit,
link_setup_workflow_list, link_setup_workflow_states,
link_setup_workflow_state_action_delete,
link_setup_workflow_state_action_edit,
link_setup_workflow_state_action_list,
link_setup_workflow_state_action_selection,
@@ -74,6 +75,9 @@ class DocumentStatesApp(MayanAppConfig):
Document = apps.get_model(
app_label='documents', model_name='Document'
)
DocumentType = apps.get_model(
app_label='documents', model_name='DocumentType'
)
ErrorLogEntry = apps.get_model(
app_label='common', model_name='ErrorLogEntry'
)
@@ -158,15 +162,14 @@ class DocumentStatesApp(MayanAppConfig):
)
SourceColumn(
source=Workflow, label=_('Label'), attribute='label'
attribute='label', is_sortable=True, source=Workflow
)
SourceColumn(
source=Workflow, label=_('Internal name'),
attribute='internal_name'
attribute='internal_name', is_sortable=True, source=Workflow
)
SourceColumn(
source=Workflow, label=_('Initial state'),
func=lambda context: context['object'].get_initial_state() or _('None')
attribute='get_initial_state', empty_value=_('None'),
source=Workflow
)
SourceColumn(
@@ -213,36 +216,42 @@ class DocumentStatesApp(MayanAppConfig):
)
SourceColumn(
attribute='initial', label=_('Is initial state?'),
source=WorkflowState, widget=TwoStateWidget
attribute='label', is_sortable=True, source=WorkflowState
)
SourceColumn(
source=WorkflowState, label=_('Completion'), attribute='completion'
attribute='initial', is_sortable=True, source=WorkflowState,
widget=TwoStateWidget
)
SourceColumn(
attribute='completion', source=WorkflowState, is_sortable=True,
)
SourceColumn(
source=WorkflowStateAction, label=_('Label'), attribute='label'
attribute='label', is_sortable=True, source=WorkflowStateAction
)
SourceColumn(
attribute='enabled', label=_('Enabled?'),
source=WorkflowStateAction, widget=TwoStateWidget
attribute='enabled', is_sortable=True, source=WorkflowStateAction,
widget=TwoStateWidget
)
SourceColumn(
source=WorkflowStateAction, label=_('When?'),
attribute='get_when_display'
attribute='get_when_display', label=_('When?'),
source=WorkflowStateAction
)
SourceColumn(
source=WorkflowStateAction, label=_('Action type'),
attribute='get_class_label'
attribute='get_class_label', label=_('Action type'),
source=WorkflowStateAction
)
SourceColumn(
source=WorkflowTransition, label=_('Origin state'),
attribute='origin_state'
attribute='label', is_sortable=True, source=WorkflowTransition,
)
SourceColumn(
source=WorkflowTransition, label=_('Destination state'),
attribute='destination_state'
attribute='origin_state', is_sortable=True,
source=WorkflowTransition
)
SourceColumn(
attribute='destination_state', is_sortable=True,
source=WorkflowTransition
)
SourceColumn(
source=WorkflowTransition, label=_('Triggers'),
@@ -271,6 +280,7 @@ class DocumentStatesApp(MayanAppConfig):
menu_facet.bind_links(
links=(link_document_workflow_instance_list,), sources=(Document,)
)
menu_list_facet.bind_links(
links=(
link_acl_list, link_events_for_object,
@@ -280,6 +290,12 @@ class DocumentStatesApp(MayanAppConfig):
link_workflow_preview
), sources=(Workflow,)
)
menu_list_facet.bind_links(
links=(
link_setup_document_type_workflows,
), sources=(DocumentType,)
)
menu_main.bind_links(links=(link_workflow_runtime_proxy_list,), position=10)
menu_object.bind_links(
links=(

View File

@@ -3,6 +3,11 @@ from __future__ import absolute_import, unicode_literals
from mayan.apps.appearance.classes import Icon
from mayan.apps.documents.icons import icon_document_type
icon_workflow = Icon(driver_name='fontawesome', symbol='sitemap')
icon_document_type_workflow_list = icon_workflow
icon_document_workflow_instance_list = Icon(
driver_name='fontawesome', symbol='sitemap'
)

View File

@@ -2,6 +2,7 @@ from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy as _
from mayan.apps.documents.permissions import permission_document_type_edit
from mayan.apps.navigation.classes import Link
from .permissions import (
@@ -10,6 +11,12 @@ from .permissions import (
permission_workflow_view,
)
link_setup_document_type_workflows = Link(
args='resolved_object.pk',
icon_class_path='mayan.apps.document_states.icons.icon_document_type_workflow_list',
permissions=(permission_document_type_edit,), text=_('Workflows'),
view='document_states:document_type_workflows',
)
link_setup_workflow_create = Link(
icon_class_path='mayan.apps.document_states.icons.icon_workflow_create',
permissions=(permission_workflow_create,),
@@ -67,17 +74,21 @@ link_setup_workflow_state_action_selection = Link(
)
link_setup_workflow_state_create = Link(
args='resolved_object.pk',
icon_class_path='mayan.apps.document_states.icons.icon_workflow_state',
icon_class_path='mayan.apps.document_states.icons.icon_workflow_state_create',
permissions=(permission_workflow_edit,), text=_('Create state'),
view='document_states:setup_workflow_state_create',
)
link_setup_workflow_state_delete = Link(
args='object.pk', permissions=(permission_workflow_edit,),
args='object.pk',
icon_class_path='mayan.apps.document_states.icons.icon_workflow_state_delete',
permissions=(permission_workflow_edit,),
tags='dangerous', text=_('Delete'),
view='document_states:setup_workflow_state_delete',
)
link_setup_workflow_state_edit = Link(
args='resolved_object.pk', permissions=(permission_workflow_edit,),
args='resolved_object.pk',
icon_class_path='mayan.apps.document_states.icons.icon_workflow_state_edit',
permissions=(permission_workflow_edit,),
text=_('Edit'), view='document_states:setup_workflow_state_edit',
)
link_setup_workflow_states = Link(
@@ -88,17 +99,21 @@ link_setup_workflow_states = Link(
)
link_setup_workflow_transition_create = Link(
args='resolved_object.pk',
icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition',
icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition_create',
permissions=(permission_workflow_edit,), text=_('Create transition'),
view='document_states:setup_workflow_transition_create',
)
link_setup_workflow_transition_delete = Link(
args='resolved_object.pk', permissions=(permission_workflow_edit,),
args='resolved_object.pk',
icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition_delete',
permissions=(permission_workflow_edit,),
tags='dangerous', text=_('Delete'),
view='document_states:setup_workflow_transition_delete',
)
link_setup_workflow_transition_edit = Link(
args='resolved_object.pk', permissions=(permission_workflow_edit,),
args='resolved_object.pk',
icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition_edit',
permissions=(permission_workflow_edit,),
text=_('Edit'), view='document_states:setup_workflow_transition_edit',
)
link_setup_workflow_transitions = Link(
@@ -108,7 +123,9 @@ link_setup_workflow_transitions = Link(
view='document_states:setup_workflow_transition_list',
)
link_workflow_transition_events = Link(
args='resolved_object.pk', permissions=(permission_workflow_edit,),
args='resolved_object.pk',
icon_class_path='mayan.apps.document_states.icons.icon_workflow_transition_triggers',
permissions=(permission_workflow_edit,),
text=_('Transition triggers'),
view='document_states:setup_workflow_transition_events'
)

View File

@@ -71,6 +71,7 @@ class Workflow(models.Model):
return self.states.get(initial=True)
except self.states.model.DoesNotExist:
return None
get_initial_state.short_description = _('Initial state')
def launch_for(self, document):
try:

View File

@@ -25,6 +25,15 @@ from .views import (
WorkflowImageView, WorkflowInstanceTransitionView, WorkflowListView,
WorkflowPreviewView, WorkflowStateDocumentListView, WorkflowStateListView,
)
from .views.workflow_views import SetupDocumentTypeWorkflowsView
urlpatterns_workflows = [
url(
regex=r'^document_type/(?P<pk>\d+)/workflows/$',
view=SetupDocumentTypeWorkflowsView.as_view(),
name='document_type_workflows'
),
]
urlpatterns = [
url(
@@ -174,6 +183,7 @@ urlpatterns = [
name='workflow_state_document_list'
),
]
urlpatterns.extend(urlpatterns_workflows)
api_urls = [
url(

View File

@@ -131,8 +131,8 @@ class WorkflowStateListView(SingleObjectListView):
def get_extra_context(self):
return {
'hide_columns': True,
'hide_link': True,
'hide_object': True,
'no_results_main_link': link_setup_workflow_state_create.resolve(
context=RequestContext(
request=self.request, dict_={'object': self.get_workflow()}

View File

@@ -64,6 +64,60 @@ __all__ = (
)
class SetupDocumentTypeWorkflowsView(AddRemoveView):
main_object_permission = permission_document_type_edit
main_object_model = DocumentType
main_object_pk_url_kwarg = 'pk'
secondary_object_model = Workflow
secondary_object_permission = permission_workflow_edit
list_available_title = _('Available workflows')
list_added_title = _('Workflows assigned this document type')
related_field = 'workflows'
def get_actions_extra_kwargs(self):
return {'_user': self.request.user}
def get_extra_context(self):
return {
'object': self.main_object,
'subtitle': _(
'Removing a workflow from a document type will also '
'remove all running instances of that workflow.'
),
'title': _(
'Workflows assigned the document type: %s'
) % self.main_object,
}
def action_add(self, queryset, _user):
with transaction.atomic():
event_document_type_edited.commit(
actor=_user, target=self.main_object
)
for obj in queryset:
self.main_object.workflows.add(obj)
event_workflow_edited.commit(
action_object=self.main_object, actor=_user, target=obj
)
def action_remove(self, queryset, _user):
with transaction.atomic():
event_document_type_edited.commit(
actor=_user, target=self.main_object
)
for obj in queryset:
self.main_object.workflows.remove(obj)
event_workflow_edited.commit(
action_object=self.main_object, actor=_user,
target=obj
)
obj.instances.filter(
document__document_type=self.main_object
).delete()
class SetupWorkflowListView(SingleObjectListView):
model = Workflow
object_permission = permission_workflow_view
@@ -449,6 +503,7 @@ class SetupWorkflowStateListView(SingleObjectListView):
def get_extra_context(self):
return {
'hide_link': True,
'hide_object': True,
'no_results_icon': icon_workflow_state,
'no_results_main_link': link_setup_workflow_state_create.resolve(
context=RequestContext(
@@ -577,6 +632,7 @@ class SetupWorkflowTransitionListView(SingleObjectListView):
def get_extra_context(self):
return {
'hide_link': True,
'hide_object': True,
'no_results_icon': icon_workflow_transition,
'no_results_main_link': link_setup_workflow_transition_create.resolve(
context=RequestContext(