backoffice: add option for a "user visible status" column (#38167) #1007
|
@ -2812,7 +2812,7 @@ def test_api_geojson_formdata(pub, local_user):
|
|||
resp = get_app(pub).get(sign_uri('/api/forms/test/geojson?full=on', user=local_user))
|
||||
assert len(resp.json['features']) == 10
|
||||
display_fields = resp.json['features'][0]['properties']['display_fields']
|
||||
assert len(display_fields) == 9
|
||||
assert len(display_fields) == 10
|
||||
field_varnames = [f['varname'] for f in display_fields]
|
||||
assert 'foobar' in field_varnames
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ from wcs.carddef import CardDef
|
|||
from wcs.formdef import FormDef
|
||||
from wcs.qommon.http_request import HTTPRequest
|
||||
from wcs.qommon.upload_storage import PicklableUpload
|
||||
from wcs.workflows import Workflow
|
||||
|
||||
from ..utilities import clean_temporary_pub, create_temporary_pub, get_app, login
|
||||
from .test_all import create_superuser
|
||||
|
@ -531,6 +532,7 @@ def test_backoffice_block_columns(pub):
|
|||
'Block',
|
||||
'Block / Test',
|
||||
'Block / card field',
|
||||
'Status (for user)',
|
||||
'Anonymised',
|
||||
]
|
||||
# enable columns for subfields
|
||||
|
@ -566,6 +568,7 @@ def test_backoffice_block_columns(pub):
|
|||
'Block',
|
||||
'Block / Test',
|
||||
'Block / card field',
|
||||
'Status (for user)',
|
||||
'Anonymised',
|
||||
]
|
||||
resp.forms['listing-settings']['8-123'].checked = True
|
||||
|
@ -633,6 +636,7 @@ def test_backoffice_block_email_column(pub):
|
|||
'Channel',
|
||||
'Block',
|
||||
'Block / Test',
|
||||
'Status (for user)',
|
||||
'Anonymised',
|
||||
]
|
||||
resp.forms['listing-settings']['8-123'].checked = True
|
||||
|
@ -698,6 +702,7 @@ def test_backoffice_block_bool_column(pub):
|
|||
'Channel',
|
||||
'Block',
|
||||
'Block / Test',
|
||||
'Status (for user)',
|
||||
'Anonymised',
|
||||
]
|
||||
resp.forms['listing-settings']['8-123'].checked = True
|
||||
|
@ -759,6 +764,7 @@ def test_backoffice_block_date_column(pub):
|
|||
'Channel',
|
||||
'Block',
|
||||
'Block / Test',
|
||||
'Status (for user)',
|
||||
'Anonymised',
|
||||
]
|
||||
resp.forms['listing-settings']['8-123'].checked = True
|
||||
|
@ -825,6 +831,7 @@ def test_backoffice_block_file_column(pub):
|
|||
'Channel',
|
||||
'Block',
|
||||
'Block / Test',
|
||||
'Status (for user)',
|
||||
'Anonymised',
|
||||
]
|
||||
resp.forms['listing-settings']['8-123'].checked = True
|
||||
|
@ -887,6 +894,7 @@ def test_backoffice_block_text_column(pub):
|
|||
'Channel',
|
||||
'Block',
|
||||
'Block / Test',
|
||||
'Status (for user)',
|
||||
'Anonymised',
|
||||
]
|
||||
resp.forms['listing-settings']['8-123'].checked = True
|
||||
|
@ -952,6 +960,7 @@ def test_backoffice_block_column_position(pub):
|
|||
'Block',
|
||||
'Block / Test',
|
||||
'Block / Bar',
|
||||
'Status (for user)',
|
||||
'Anonymised',
|
||||
]
|
||||
resp.forms['listing-settings']['time'].checked = False
|
||||
|
@ -1103,6 +1112,7 @@ def test_backoffice_digest_column(pub):
|
|||
'Digest',
|
||||
'Channel',
|
||||
'field',
|
||||
'Status (for user)',
|
||||
'Anonymised',
|
||||
]
|
||||
assert {x.text for x in resp.pyquery('.cell-status + td')} == {'form foo', 'form bar'}
|
||||
|
@ -1142,3 +1152,63 @@ def test_backoffice_unknown_status_column(pub):
|
|||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/management/form-title/?filter=all')
|
||||
assert resp.pyquery('tbody td.cell-status').text() == 'Unknown'
|
||||
|
||||
|
||||
def test_backoffice_user_visible_status_column(pub):
|
||||
pub.user_class.wipe()
|
||||
create_superuser(pub)
|
||||
pub.role_class.wipe()
|
||||
role = pub.role_class(name='test')
|
||||
role.store()
|
||||
|
||||
Workflow.wipe()
|
||||
workflow = Workflow(name='test user visible column')
|
||||
st1 = workflow.add_status('st1')
|
||||
st2 = workflow.add_status('st2')
|
||||
st2.visibility = ['_receiver']
|
||||
jump = st1.add_action('jump')
|
||||
jump.status = str(st2.id)
|
||||
workflow.store()
|
||||
|
||||
FormDef.wipe()
|
||||
formdef = FormDef()
|
||||
formdef.name = 'form-title'
|
||||
formdef.fields = [
|
||||
fields.StringField(
|
||||
id='1',
|
||||
label='field',
|
||||
varname='foo',
|
||||
)
|
||||
]
|
||||
formdef.workflow_roles = {'_receiver': role.id}
|
||||
formdef.workflow = workflow
|
||||
formdef.store()
|
||||
|
||||
data_class = formdef.data_class()
|
||||
data_class.wipe()
|
||||
|
||||
formdata = data_class()
|
||||
formdata.data = {'1': 'foo'}
|
||||
formdata.just_created()
|
||||
formdata.store()
|
||||
formdata.perform_workflow()
|
||||
formdata.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/management/form-title/')
|
||||
resp = app.get('/backoffice/management/form-title/')
|
||||
resp.forms['listing-settings']['filter'] = 'all'
|
||||
resp.forms['listing-settings']['user-visible-status'].checked = True
|
||||
resp = resp.forms['listing-settings'].submit()
|
||||
assert [x.text_content() for x in resp.pyquery('#columns-filter label')] == [
|
||||
'Number',
|
||||
'Created',
|
||||
'Last Modified',
|
||||
'User Label',
|
||||
'Status',
|
||||
'Status (for user)',
|
||||
'Channel',
|
||||
'field',
|
||||
'Anonymised',
|
||||
]
|
||||
assert '<td class="cell-status">st2</td><td>st1</td>' in resp.text
|
||||
|
|
|
@ -1851,6 +1851,13 @@ class FormPage(Directory, TempfileDirectoryMixin):
|
|||
yield RelatedField(carddef, card_field, field)
|
||||
|
||||
yield FakeField('status', 'status', _('Status'), include_in_statistics=True)
|
||||
if any(x.get_visibility_mode() != 'all' for x in self.formdef.workflow.possible_status):
|
||||
yield FakeField(
|
||||
'user-visible-status',
|
||||
'user-visible-status',
|
||||
_('Status (for user)'),
|
||||
geojson_label=_('Status'),
|
||||
)
|
||||
yield FakeField('anonymised', 'anonymised', _('Anonymised'))
|
||||
|
||||
def get_default_columns(self):
|
||||
|
@ -4098,7 +4105,7 @@ class FormBackOfficeStatusPage(FormStatusPage):
|
|||
class FakeField:
|
||||
can_include_in_listing = True
|
||||
|
||||
def __init__(self, id, type_key, label, addable=True, include_in_statistics=False):
|
||||
def __init__(self, id, type_key, label, addable=True, include_in_statistics=False, geojson_label=None):
|
||||
self.id = id
|
||||
self.contextual_id = self.id
|
||||
self.key = type_key
|
||||
|
@ -4110,6 +4117,7 @@ class FakeField:
|
|||
self.store_structured_value = None
|
||||
self.addable = addable
|
||||
self.include_in_statistics = include_in_statistics
|
||||
self.geojson_label = force_str(geojson_label or self.label)
|
||||
|
||||
def get_view_value(self, value):
|
||||
# just here to quack like a duck
|
||||
|
|
|
@ -925,6 +925,25 @@ class FormData(StorableObject):
|
|||
return None
|
||||
|
||||
def get_field_view_value(self, field, max_length=None):
|
||||
class StatusFieldValue:
|
||||
def __init__(self, status):
|
||||
self.status = status
|
||||
|
||||
def get_ods_style_name(self):
|
||||
return 'StatusStyle-%s' % misc.simplify(self.status.name) if self.status else None
|
||||
|
||||
def get_ods_colour(self, colour):
|
||||
return {'black': '#000000', 'white': '#ffffff'}.get(colour, colour)
|
||||
|
||||
def get_ods_style_bg_colour(self):
|
||||
return self.get_ods_colour(self.status.colour) if self.status else 'transparent'
|
||||
|
||||
def get_ods_style_fg_colour(self):
|
||||
return self.get_ods_colour(self.status.get_contrast_color()) if self.status else '#000000'
|
||||
|
||||
def __str__(self):
|
||||
return str(get_publisher().translate(self.status.name) if self.status else _('Unknown'))
|
||||
|
||||
def get_value(field, data, **kwargs):
|
||||
# return the value of the given field, with special handling for "fake"
|
||||
# field types that are shortcuts to internal properties.
|
||||
|
@ -939,33 +958,9 @@ class FormData(StorableObject):
|
|||
if field.key == 'user-label':
|
||||
return self.get_user_label() or '-'
|
||||
if field.key == 'status':
|
||||
|
||||
class StatusFieldValue:
|
||||
def __init__(self, status):
|
||||
self.status = status
|
||||
|
||||
def get_ods_style_name(self):
|
||||
return 'StatusStyle-%s' % misc.simplify(self.status.name) if self.status else None
|
||||
|
||||
def get_ods_colour(self, colour):
|
||||
return {'black': '#000000', 'white': '#ffffff'}.get(colour, colour)
|
||||
|
||||
def get_ods_style_bg_colour(self):
|
||||
return self.get_ods_colour(self.status.colour) if self.status else 'transparent'
|
||||
|
||||
def get_ods_style_fg_colour(self):
|
||||
return (
|
||||
self.get_ods_colour(self.status.get_contrast_color())
|
||||
if self.status
|
||||
else '#000000'
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return str(
|
||||
get_publisher().translate(self.status.name) if self.status else _('Unknown')
|
||||
)
|
||||
|
||||
return StatusFieldValue(self.get_status())
|
||||
if field.key == 'user-visible-status':
|
||||
return StatusFieldValue(self.get_visible_status(user=None))
|
||||
if field.key == 'submission_channel':
|
||||
return self.get_submission_channel_label()
|
||||
if field.key == 'submission_agent':
|
||||
|
|
Loading…
Reference in New Issue