Add field type selection
Signed-off-by: Roberto Rosario <roberto.rosario@mayan-edms.com>
This commit is contained in:
@@ -157,6 +157,9 @@ class DocumentStatesApp(MayanAppConfig):
|
||||
ModelPermission.register_inheritance(
|
||||
model=WorkflowTransition, related='workflow',
|
||||
)
|
||||
ModelPermission.register_inheritance(
|
||||
model=WorkflowTransitionField, related='transition',
|
||||
)
|
||||
ModelPermission.register_inheritance(
|
||||
model=WorkflowTransitionTriggerEvent,
|
||||
related='transition__workflow',
|
||||
@@ -206,16 +209,20 @@ class DocumentStatesApp(MayanAppConfig):
|
||||
attribute='datetime'
|
||||
)
|
||||
SourceColumn(
|
||||
source=WorkflowInstanceLogEntry, label=_('User'), attribute='user'
|
||||
source=WorkflowInstanceLogEntry, attribute='user'
|
||||
)
|
||||
SourceColumn(
|
||||
source=WorkflowInstanceLogEntry, label=_('Transition'),
|
||||
source=WorkflowInstanceLogEntry,
|
||||
attribute='transition'
|
||||
)
|
||||
SourceColumn(
|
||||
source=WorkflowInstanceLogEntry, label=_('Comment'),
|
||||
source=WorkflowInstanceLogEntry,
|
||||
attribute='comment'
|
||||
)
|
||||
SourceColumn(
|
||||
source=WorkflowInstanceLogEntry,
|
||||
attribute='extra_data'
|
||||
)
|
||||
|
||||
SourceColumn(
|
||||
attribute='label', is_sortable=True, source=WorkflowState
|
||||
@@ -269,6 +276,10 @@ class DocumentStatesApp(MayanAppConfig):
|
||||
SourceColumn(
|
||||
attribute='label', is_sortable=True, source=WorkflowTransitionField
|
||||
)
|
||||
SourceColumn(
|
||||
attribute='get_field_type_display', label=_('Type'),
|
||||
source=WorkflowTransitionField
|
||||
)
|
||||
SourceColumn(
|
||||
attribute='required', is_sortable=True, source=WorkflowTransitionField,
|
||||
widget=TwoStateWidget
|
||||
|
||||
@@ -175,6 +175,7 @@ class WorkflowInstanceTransitionSelectForm(forms.Form):
|
||||
].queryset = workflow_instance.get_transition_choices(_user=user)
|
||||
|
||||
transition = forms.ModelChoiceField(
|
||||
help_text=_('Select a transition to execute in the next step.'),
|
||||
label=_('Transition'), queryset=WorkflowTransition.objects.none()
|
||||
)
|
||||
|
||||
|
||||
@@ -26,7 +26,9 @@ icon_workflow_list = Icon(driver_name='fontawesome', symbol='sitemap')
|
||||
icon_workflow_preview = Icon(driver_name='fontawesome', symbol='eye')
|
||||
|
||||
|
||||
icon_workflow_instance_detail = Icon(driver_name='fontawesome', symbol='sitemap')
|
||||
icon_workflow_instance_detail = Icon(
|
||||
driver_name='fontawesome', symbol='sitemap'
|
||||
)
|
||||
icon_workflow_instance_transition = Icon(
|
||||
driver_name='fontawesome', symbol='arrows-alt-h'
|
||||
)
|
||||
@@ -58,8 +60,12 @@ icon_workflow_state_delete = Icon(driver_name='fontawesome', symbol='times')
|
||||
icon_workflow_state_edit = Icon(driver_name='fontawesome', symbol='pencil-alt')
|
||||
|
||||
icon_workflow_state_action = Icon(driver_name='fontawesome', symbol='code')
|
||||
icon_workflow_state_action_delete = Icon(driver_name='fontawesome', symbol='times')
|
||||
icon_workflow_state_action_edit = Icon(driver_name='fontawesome', symbol='pencil-alt')
|
||||
icon_workflow_state_action_delete = Icon(
|
||||
driver_name='fontawesome', symbol='times'
|
||||
)
|
||||
icon_workflow_state_action_edit = Icon(
|
||||
driver_name='fontawesome', symbol='pencil-alt'
|
||||
)
|
||||
icon_workflow_state_action_selection = Icon(
|
||||
driver_name='fontawesome-dual', primary_symbol='code',
|
||||
secondary_symbol='plus'
|
||||
@@ -72,19 +78,27 @@ icon_workflow_transition_create = Icon(
|
||||
driver_name='fontawesome-dual', primary_symbol='arrows-alt-h',
|
||||
secondary_symbol='plus'
|
||||
)
|
||||
icon_workflow_transition_delete = Icon(driver_name='fontawesome', symbol='times')
|
||||
icon_workflow_transition_delete = Icon(
|
||||
driver_name='fontawesome', symbol='times'
|
||||
)
|
||||
icon_workflow_transition_edit = Icon(
|
||||
driver_name='fontawesome', symbol='pencil-alt'
|
||||
)
|
||||
|
||||
icon_workflow_transition_field = Icon(driver_name='fontawesome', symbol='code')
|
||||
icon_workflow_transition_field_delete = Icon(driver_name='fontawesome', symbol='times')
|
||||
icon_workflow_transition_field_edit = Icon(driver_name='fontawesome', symbol='pencil-alt')
|
||||
icon_workflow_transition_field = Icon(driver_name='fontawesome', symbol='table')
|
||||
icon_workflow_transition_field_delete = Icon(
|
||||
driver_name='fontawesome', symbol='times'
|
||||
)
|
||||
icon_workflow_transition_field_edit = Icon(
|
||||
driver_name='fontawesome', symbol='pencil-alt'
|
||||
)
|
||||
icon_workflow_transition_field_create = Icon(
|
||||
driver_name='fontawesome-dual', primary_symbol='code',
|
||||
driver_name='fontawesome-dual', primary_symbol='table',
|
||||
secondary_symbol='plus'
|
||||
)
|
||||
icon_workflow_transition_field_list = Icon(driver_name='fontawesome', symbol='code')
|
||||
icon_workflow_transition_field_list = Icon(
|
||||
driver_name='fontawesome', symbol='table'
|
||||
)
|
||||
|
||||
icon_workflow_transition_triggers = Icon(
|
||||
driver_name='fontawesome', symbol='bolt'
|
||||
|
||||
@@ -9,3 +9,15 @@ WORKFLOW_ACTION_WHEN_CHOICES = (
|
||||
(WORKFLOW_ACTION_ON_ENTRY, _('On entry')),
|
||||
(WORKFLOW_ACTION_ON_EXIT, _('On exit')),
|
||||
)
|
||||
|
||||
FIELD_TYPE_CHOICE_CHAR = 1
|
||||
FIELD_TYPE_CHOICE_INTEGER = 2
|
||||
FIELD_TYPE_CHOICES = (
|
||||
(FIELD_TYPE_CHOICE_CHAR, _('Character')),
|
||||
(FIELD_TYPE_CHOICE_INTEGER, _('Number (Integer)')),
|
||||
)
|
||||
|
||||
FIELD_TYPE_MAPPING = {
|
||||
FIELD_TYPE_CHOICE_CHAR: 'django.forms.CharField',
|
||||
FIELD_TYPE_CHOICE_INTEGER: 'django.forms.IntegerField',
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.20 on 2019-06-30 13:31
|
||||
# Generated by Django 1.11.20 on 2019-07-01 04:54
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
@@ -17,10 +17,11 @@ class Migration(migrations.Migration):
|
||||
name='WorkflowTransitionField',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=128, verbose_name='Internal name')),
|
||||
('label', models.CharField(max_length=128, verbose_name='Label')),
|
||||
('help_text', models.TextField(blank=True, verbose_name='Help text')),
|
||||
('required', models.BooleanField(default=False, verbose_name='Required')),
|
||||
('field_type', models.PositiveIntegerField(choices=[(1, 'Character'), (2, 'Number (Integer)')], verbose_name='Type')),
|
||||
('name', models.CharField(help_text='The name that will be used to identify this field in other parts of the workflow system.', max_length=128, verbose_name='Internal name')),
|
||||
('label', models.CharField(help_text='The field name that will be shown on the user interface.', max_length=128, verbose_name='Label')),
|
||||
('help_text', models.TextField(blank=True, help_text='An optional message that will help users better understand the purpose of the field and data to provide.', verbose_name='Help text')),
|
||||
('required', models.BooleanField(default=False, help_text='Whether this fields needs to be filled out or not to proceed.', verbose_name='Required')),
|
||||
('transition', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='fields', to='document_states.WorkflowTransition', verbose_name='Transition')),
|
||||
],
|
||||
options={
|
||||
@@ -33,6 +34,11 @@ class Migration(migrations.Migration):
|
||||
name='context',
|
||||
field=models.TextField(blank=True, verbose_name='Backend data'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowinstancelogentry',
|
||||
name='extra_data',
|
||||
field=models.TextField(blank=True, verbose_name='Extra data'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='workflowtransitionfield',
|
||||
unique_together=set([('transition', 'name')]),
|
||||
@@ -23,8 +23,8 @@ from mayan.apps.events.models import StoredEventType
|
||||
from .error_logs import error_log_state_actions
|
||||
from .events import event_workflow_created, event_workflow_edited
|
||||
from .literals import (
|
||||
WORKFLOW_ACTION_WHEN_CHOICES, WORKFLOW_ACTION_ON_ENTRY,
|
||||
WORKFLOW_ACTION_ON_EXIT
|
||||
FIELD_TYPE_CHOICES, WORKFLOW_ACTION_WHEN_CHOICES,
|
||||
WORKFLOW_ACTION_ON_ENTRY, WORKFLOW_ACTION_ON_EXIT
|
||||
)
|
||||
from .managers import WorkflowManager
|
||||
from .permissions import permission_workflow_transition
|
||||
@@ -369,6 +369,9 @@ class WorkflowTransitionField(models.Model):
|
||||
on_delete=models.CASCADE, related_name='fields',
|
||||
to=WorkflowTransition, verbose_name=_('Transition')
|
||||
)
|
||||
field_type = models.PositiveIntegerField(
|
||||
choices=FIELD_TYPE_CHOICES, verbose_name=_('Type')
|
||||
)
|
||||
name = models.CharField(
|
||||
help_text=_(
|
||||
'The name that will be used to identify this field in other parts '
|
||||
@@ -390,7 +393,6 @@ class WorkflowTransitionField(models.Model):
|
||||
'Whether this fields needs to be filled out or not to proceed.'
|
||||
), verbose_name=_('Required')
|
||||
)
|
||||
#TODO: widget, widget kwargs
|
||||
|
||||
class Meta:
|
||||
unique_together = ('transition', 'name')
|
||||
@@ -431,7 +433,7 @@ class WorkflowInstance(models.Model):
|
||||
verbose_name=_('Document')
|
||||
)
|
||||
context = models.TextField(
|
||||
blank=True, verbose_name=_('Backend data')
|
||||
blank=True, verbose_name=_('Context')
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -447,25 +449,25 @@ class WorkflowInstance(models.Model):
|
||||
with transaction.atomic():
|
||||
try:
|
||||
if transition in self.get_current_state().origin_transitions.all():
|
||||
self.log_entries.create(
|
||||
comment=comment or '', transition=transition, user=user
|
||||
)
|
||||
if extra_data:
|
||||
data = self.loads()
|
||||
data.update(extra_data)
|
||||
self.dumps(data=data)
|
||||
context = self.loads()
|
||||
context.update(extra_data)
|
||||
self.dumps(context=context)
|
||||
|
||||
self.log_entries.create(
|
||||
comment=comment or '',
|
||||
extra_data=json.dumps(extra_data or {}),
|
||||
transition=transition, user=user
|
||||
)
|
||||
except AttributeError:
|
||||
# No initial state has been set for this workflow
|
||||
pass
|
||||
|
||||
# TODO: execute transition event target = document,
|
||||
# action_object = self
|
||||
|
||||
def dumps(self, data):
|
||||
def dumps(self, context):
|
||||
"""
|
||||
Serialize the context data.
|
||||
"""
|
||||
self.context = json.dumps(data)
|
||||
self.context = json.dumps(context)
|
||||
self.save()
|
||||
|
||||
def get_absolute_url(self):
|
||||
@@ -579,6 +581,7 @@ class WorkflowInstanceLogEntry(models.Model):
|
||||
to=settings.AUTH_USER_MODEL, verbose_name=_('User')
|
||||
)
|
||||
comment = models.TextField(blank=True, verbose_name=_('Comment'))
|
||||
extra_data = models.TextField(blank=True, verbose_name=_('Extra data'))
|
||||
|
||||
class Meta:
|
||||
ordering = ('datetime',)
|
||||
@@ -592,6 +595,12 @@ class WorkflowInstanceLogEntry(models.Model):
|
||||
if self.transition not in self.workflow_instance.get_transition_choices(_user=self.user):
|
||||
raise ValidationError(_('Not a valid transition choice.'))
|
||||
|
||||
def loads(self):
|
||||
"""
|
||||
Deserialize the context data.
|
||||
"""
|
||||
return json.loads(self.extra_data or '{}')
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
with transaction.atomic():
|
||||
result = super(WorkflowInstanceLogEntry, self).save(*args, **kwargs)
|
||||
|
||||
@@ -16,6 +16,10 @@ from .mixins import (
|
||||
WorkflowTestMixin, WorkflowViewTestMixin, WorkflowTransitionViewTestMixin
|
||||
)
|
||||
|
||||
TEST_WORKFLOW_TRANSITION_FIELD_NAME = 'test_workflow_transition_field'
|
||||
TEST_WORKFLOW_TRANSITION_FIELD_LABEL = 'test workflow transition field'
|
||||
TEST_WORKFLOW_TRANSITION_FIELD_HELP_TEXT = 'test workflow transition field help test'
|
||||
|
||||
|
||||
class WorkflowTransitionViewTestCase(
|
||||
WorkflowTestMixin, WorkflowViewTestMixin, WorkflowTransitionViewTestMixin,
|
||||
@@ -232,3 +236,123 @@ class WorkflowTransitionEventViewTestCase(
|
||||
|
||||
response = self._request_test_workflow_transition_event_list_view()
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
class WorkflowTransitionFieldViewTestCase(
|
||||
WorkflowTestMixin, WorkflowTransitionViewTestMixin, GenericViewTestCase
|
||||
):
|
||||
def setUp(self):
|
||||
super(WorkflowTransitionFieldViewTestCase, self).setUp()
|
||||
self._create_test_workflow()
|
||||
self._create_test_workflow_states()
|
||||
self._create_test_workflow_transition()
|
||||
|
||||
def _create_test_workflow_transition_field(self):
|
||||
self.test_workflow_transition_field = self.test_workflow_transition.fields.create(
|
||||
name=TEST_WORKFLOW_TRANSITION_FIELD_NAME,
|
||||
label=TEST_WORKFLOW_TRANSITION_FIELD_LABEL,
|
||||
help_text=TEST_WORKFLOW_TRANSITION_FIELD_HELP_TEXT
|
||||
)
|
||||
|
||||
def _request_test_workflow_transition_field_list_view(self):
|
||||
return self.get(
|
||||
viewname='document_states:setup_workflow_transition_field_list',
|
||||
kwargs={'pk': self.test_workflow_transition.pk}
|
||||
)
|
||||
|
||||
def test_workflow_transition_field_list_view_no_permission(self):
|
||||
self._create_test_workflow_transition_field()
|
||||
|
||||
response = self._request_test_workflow_transition_field_list_view()
|
||||
self.assertNotContains(
|
||||
response=response,
|
||||
text=self.test_workflow_transition_field.label,
|
||||
status_code=404
|
||||
)
|
||||
|
||||
def test_workflow_transition_field_list_view_with_access(self):
|
||||
self._create_test_workflow_transition_field()
|
||||
|
||||
self.grant_access(
|
||||
obj=self.test_workflow, permission=permission_workflow_edit
|
||||
)
|
||||
|
||||
response = self._request_test_workflow_transition_field_list_view()
|
||||
self.assertContains(
|
||||
response=response,
|
||||
text=self.test_workflow_transition_field.label,
|
||||
status_code=200
|
||||
)
|
||||
|
||||
def _request_workflow_transition_field_create_view(self):
|
||||
return self.post(
|
||||
viewname='document_states:setup_workflow_transition_field_create',
|
||||
kwargs={'pk': self.test_workflow_transition.pk},
|
||||
data={
|
||||
'name': TEST_WORKFLOW_TRANSITION_FIELD_NAME,
|
||||
'label': TEST_WORKFLOW_TRANSITION_FIELD_LABEL,
|
||||
'help_text': TEST_WORKFLOW_TRANSITION_FIELD_HELP_TEXT
|
||||
}
|
||||
)
|
||||
|
||||
def test_workflow_transition_field_create_view_no_permission(self):
|
||||
workflow_transition_field_count = self.test_workflow_transition.fields.count()
|
||||
|
||||
response = self._request_workflow_transition_field_create_view()
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
self.assertEqual(
|
||||
self.test_workflow_transition.fields.count(),
|
||||
workflow_transition_field_count
|
||||
)
|
||||
|
||||
def test_workflow_transition_field_create_view_with_access(self):
|
||||
workflow_transition_field_count = self.test_workflow_transition.fields.count()
|
||||
|
||||
self.grant_access(
|
||||
obj=self.test_workflow, permission=permission_workflow_edit
|
||||
)
|
||||
|
||||
response = self._request_workflow_transition_field_create_view()
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
self.assertEqual(
|
||||
self.test_workflow_transition.fields.count(),
|
||||
workflow_transition_field_count + 1
|
||||
)
|
||||
|
||||
def _request_workflow_transition_field_delete_view(self):
|
||||
return self.post(
|
||||
viewname='document_states:setup_workflow_transition_field_delete',
|
||||
kwargs={'pk': self.test_workflow_transition_field.pk},
|
||||
)
|
||||
|
||||
def test_workflow_transition_field_delete_view_no_permission(self):
|
||||
self._create_test_workflow_transition_field()
|
||||
|
||||
workflow_transition_field_count = self.test_workflow_transition.fields.count()
|
||||
|
||||
response = self._request_workflow_transition_field_delete_view()
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
self.assertEqual(
|
||||
self.test_workflow_transition.fields.count(),
|
||||
workflow_transition_field_count
|
||||
)
|
||||
|
||||
def test_workflow_transition_field_delete_view_with_access(self):
|
||||
self._create_test_workflow_transition_field()
|
||||
|
||||
workflow_transition_field_count = self.test_workflow_transition.fields.count()
|
||||
|
||||
self.grant_access(
|
||||
obj=self.test_workflow, permission=permission_workflow_edit
|
||||
)
|
||||
|
||||
response = self._request_workflow_transition_field_delete_view()
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
||||
self.assertEqual(
|
||||
self.test_workflow_transition.fields.count(),
|
||||
workflow_transition_field_count - 1
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ from django.contrib import messages
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.template import RequestContext
|
||||
from django.urls import reverse, reverse_lazy
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from mayan.apps.acls.models import AccessControlList
|
||||
@@ -16,6 +16,7 @@ from mayan.apps.documents.models import Document
|
||||
from ..forms import WorkflowInstanceTransitionSelectForm
|
||||
from ..icons import icon_workflow_instance_detail, icon_workflow_list
|
||||
from ..links import link_workflow_instance_transition
|
||||
from ..literals import FIELD_TYPE_MAPPING
|
||||
from ..models import WorkflowInstance
|
||||
from ..permissions import permission_workflow_view
|
||||
|
||||
@@ -165,7 +166,7 @@ class WorkflowInstanceTransitionExecuteView(FormView):
|
||||
for field in self.get_workflow_transition().fields.all():
|
||||
schema['fields'][field.name] = {
|
||||
'label': field.label,
|
||||
'class': 'django.forms.CharField', 'kwargs': {
|
||||
'class': FIELD_TYPE_MAPPING[field.field_type], 'kwargs': {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,6 +220,3 @@ class WorkflowInstanceTransitionSelectView(ExternalObjectMixin, FormView):
|
||||
'user': self.request.user,
|
||||
'workflow_instance': self.external_object
|
||||
}
|
||||
|
||||
#def get_workflow_instance(self):
|
||||
# return get_object_or_404(klass=WorkflowInstance, pk=self.kwargs['pk'])
|
||||
|
||||
@@ -31,12 +31,13 @@ from ..forms import (
|
||||
)
|
||||
from ..icons import (
|
||||
icon_workflow_list, icon_workflow_state, icon_workflow_state_action,
|
||||
icon_workflow_transition
|
||||
icon_workflow_transition, icon_workflow_transition_field
|
||||
)
|
||||
from ..links import (
|
||||
link_setup_workflow_create, link_setup_workflow_state_create,
|
||||
link_setup_workflow_state_action_selection,
|
||||
link_setup_workflow_transition_create
|
||||
link_setup_workflow_transition_create,
|
||||
link_setup_workflow_transition_field_create,
|
||||
)
|
||||
from ..models import (
|
||||
Workflow, WorkflowState, WorkflowStateAction, WorkflowTransition,
|
||||
@@ -738,8 +739,7 @@ class SetupWorkflowTransitionTriggerEventListView(ExternalObjectMixin, FormView)
|
||||
class SetupWorkflowTransitionFieldCreateView(ExternalObjectMixin, SingleObjectCreateView):
|
||||
external_object_class = WorkflowTransition
|
||||
external_object_permission = permission_workflow_edit
|
||||
fields = ('name', 'label', 'help_text', 'required')
|
||||
#object_permission = permission_workflow_edit
|
||||
fields = ('name', 'label', 'field_type', 'help_text', 'required')
|
||||
|
||||
def get_extra_context(self):
|
||||
return {
|
||||
@@ -789,7 +789,7 @@ class SetupWorkflowTransitionFieldDeleteView(SingleObjectDeleteView):
|
||||
|
||||
|
||||
class SetupWorkflowTransitionFieldEditView(SingleObjectEditView):
|
||||
fields = ('name', 'label', 'help_text', 'required',)
|
||||
fields = ('name', 'label', 'field_type', 'help_text', 'required',)
|
||||
model = WorkflowTransitionField
|
||||
object_permission = permission_workflow_edit
|
||||
|
||||
@@ -819,21 +819,23 @@ class SetupWorkflowTransitionFieldListView(ExternalObjectMixin, SingleObjectList
|
||||
return {
|
||||
'hide_object': True,
|
||||
'navigation_object_list': ('object', 'workflow'),
|
||||
#'no_results_icon': icon_workflow_transition_action,
|
||||
#'no_results_main_link': link_setup_workflow_transition_action_selection.resolve(
|
||||
# context=RequestContext(
|
||||
# request=self.request, dict_={
|
||||
# 'object': self.get_workflow_transition()
|
||||
# }
|
||||
# )
|
||||
#),
|
||||
#'no_results_text': _(
|
||||
# 'Workflow state actions are macros that get executed when '
|
||||
# 'documents enters or leaves the state in which they reside.'
|
||||
#),
|
||||
#'no_results_title': _(
|
||||
# 'There are no actions for this workflow state'
|
||||
#),
|
||||
'no_results_icon': icon_workflow_transition_field,
|
||||
'no_results_main_link': link_setup_workflow_transition_field_create.resolve(
|
||||
context=RequestContext(
|
||||
request=self.request, dict_={
|
||||
'object': self.external_object
|
||||
}
|
||||
)
|
||||
),
|
||||
'no_results_text': _(
|
||||
'Workflow transition fields allow adding data to the '
|
||||
'workflow\'s context. This additional context data can then '
|
||||
'be used by other elements of the workflow system like the '
|
||||
'workflow state actions.'
|
||||
),
|
||||
'no_results_title': _(
|
||||
'There are no fields for this workflow transition'
|
||||
),
|
||||
'object': self.external_object,
|
||||
'title': _(
|
||||
'Fields for workflow transition: %s'
|
||||
|
||||
Reference in New Issue
Block a user