backoffice: allow adding custom user column to management tables (#40031)
This commit is contained in:
parent
fe4b237fd9
commit
a6315551b5
|
@ -651,6 +651,46 @@ def test_backoffice_image_column(pub):
|
|||
assert 'download?f=4&thumbnail=1' not in resp.text
|
||||
|
||||
|
||||
def test_backoffice_user_columns(pub):
|
||||
create_superuser(pub)
|
||||
create_environment(pub)
|
||||
|
||||
from wcs.admin.settings import UserFieldsFormDef
|
||||
user_formdef = UserFieldsFormDef(pub)
|
||||
user_formdef.fields.append(fields.StringField(id='_first_name', label='name', type='string'))
|
||||
user_formdef.fields.append(fields.StringField(id='3', label='test', type='string'))
|
||||
user_formdef.store()
|
||||
pub.cfg['users']['field_name'] = ['3', '4']
|
||||
pub.write_cfg()
|
||||
|
||||
user1 = pub.user_class(name='userA')
|
||||
user1.form_data = {'_first_name': 'toto', '3': 'nono'}
|
||||
user1.set_attributes_from_formdata(user1.form_data)
|
||||
user1.store()
|
||||
user2 = pub.user_class(name='userB')
|
||||
user2.form_data = {'_first_name': 'tutu', '3': 'nunu'}
|
||||
user2.set_attributes_from_formdata(user2.form_data)
|
||||
user2.store()
|
||||
|
||||
formdef = FormDef.get_by_urlname('form-title')
|
||||
for i, formdata in enumerate(formdef.data_class().select()):
|
||||
formdata.user_id = user1.id if bool(i % 2) else user2.id
|
||||
formdata.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
resp = app.get('/backoffice/management/form-title/')
|
||||
assert resp.text.count('</th>') == 8 # six columns
|
||||
|
||||
if not pub.is_using_postgresql():
|
||||
# no support for relation columns unless using SQL
|
||||
assert 'user-label$3' not in resp.forms['listing-settings'].fields
|
||||
return
|
||||
resp.forms['listing-settings']['user-label$3'].checked = True
|
||||
resp = resp.forms['listing-settings'].submit()
|
||||
assert resp.text.count('</th>') == 9
|
||||
assert '<td>nono</td' in resp
|
||||
|
||||
|
||||
def test_backoffice_card_field_columns(pub):
|
||||
user = create_superuser(pub)
|
||||
create_environment(pub)
|
||||
|
|
|
@ -1428,9 +1428,9 @@ class FormPage(Directory):
|
|||
attrs = ''
|
||||
if isinstance(field, RelatedField):
|
||||
classnames = 'related-field'
|
||||
if field.parent_field.id in seen_parents:
|
||||
if field.parent_field_id in seen_parents:
|
||||
classnames += ' collapsed'
|
||||
attrs = 'data-relation-attr="%s"' % field.parent_field.id
|
||||
attrs = 'data-relation-attr="%s"' % field.parent_field_id
|
||||
elif getattr(field, 'has_relations', False):
|
||||
classnames = 'has-relations-field'
|
||||
attrs = 'data-field-id="%s"' % field.id
|
||||
|
@ -1538,7 +1538,16 @@ class FormPage(Directory):
|
|||
yield FakeField('submission_agent', 'submission_agent', _('Submission By'))
|
||||
yield FakeField('time', 'time', _('Created'))
|
||||
yield FakeField('last_update_time', 'last_update_time', _('Last Modified'))
|
||||
|
||||
# user fields
|
||||
yield FakeField('user-label', 'user-label', _('User Label'))
|
||||
if get_publisher().is_using_postgresql():
|
||||
for field in get_publisher().user_class.get_fields():
|
||||
if not hasattr(field, 'get_view_value'):
|
||||
continue
|
||||
field.has_relations = True
|
||||
yield UserRelatedField(field)
|
||||
|
||||
for field in self.formdef.get_all_fields():
|
||||
yield field
|
||||
if not get_publisher().is_using_postgresql():
|
||||
|
@ -3161,6 +3170,10 @@ class FakeField(object):
|
|||
def get_csv_value(self, element, **kwargs):
|
||||
return [element]
|
||||
|
||||
@property
|
||||
def has_relations(self):
|
||||
return bool(self.id == 'user-label')
|
||||
|
||||
|
||||
class RelatedField:
|
||||
is_related_field = True
|
||||
|
@ -3170,16 +3183,17 @@ class RelatedField:
|
|||
|
||||
def __init__(self, carddef, field, parent_field):
|
||||
self.carddef = carddef
|
||||
self.carddef_field = field
|
||||
self.related_field = field
|
||||
self.parent_field = parent_field
|
||||
self.parent_field_id = parent_field.id
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
return '%s$%s' % (self.parent_field.id, self.carddef_field.id)
|
||||
return '%s$%s' % (self.parent_field_id, self.related_field.id)
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
return '%s - %s' % (self.parent_field.label, self.carddef_field.label)
|
||||
return '%s - %s' % (self.parent_field.label, self.related_field.label)
|
||||
|
||||
def get_view_value(self, value, **kwargs):
|
||||
if value is None:
|
||||
|
@ -3200,6 +3214,19 @@ class RelatedField:
|
|||
return [self.get_view_value(value)]
|
||||
|
||||
|
||||
class UserRelatedField(RelatedField):
|
||||
# it is named 'user-label' and not 'user' for compatibility with existing
|
||||
# listings, as the 'classic' user column is named 'user-label'.
|
||||
parent_field_id = 'user-label'
|
||||
|
||||
def __init__(self, field):
|
||||
self.related_field = field
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
return _('%s of User') % self.related_field.label
|
||||
|
||||
|
||||
def do_graphs_section(period_start=None, period_end=None, criterias=None):
|
||||
from wcs import sql
|
||||
r = TemplateIO(html=True)
|
||||
|
|
|
@ -102,7 +102,7 @@ class FormDefUI(object):
|
|||
field_sort_key = 'receipt_time'
|
||||
elif f.id in ('user-label', 'submission_agent'):
|
||||
field_sort_key = None
|
||||
elif hasattr(f, 'column_id'):
|
||||
elif getattr(f, 'is_related_field', False):
|
||||
field_sort_key = None
|
||||
else:
|
||||
field_sort_key = 'f%s' % f.id
|
||||
|
|
26
wcs/sql.py
26
wcs/sql.py
|
@ -1159,19 +1159,25 @@ class SqlMixin(object):
|
|||
for field in fields:
|
||||
if not getattr(field, 'is_related_field', False):
|
||||
continue
|
||||
carddef_dataclass = field.carddef.data_class()
|
||||
carddef_table_alias = 't%s' % id(field.carddef)
|
||||
carddef_table_decl = 'LEFT JOIN %s AS %s ON (CAST(%s.%s AS INTEGER) = %s.id)' % (
|
||||
carddef_dataclass._table_name,
|
||||
carddef_table_alias,
|
||||
cls._table_name,
|
||||
get_field_id(field.parent_field),
|
||||
carddef_table_alias)
|
||||
if field.parent_field_id == 'user-label':
|
||||
# relation to user table
|
||||
carddef_table_alias = 'users'
|
||||
carddef_table_decl = 'LEFT JOIN users ON (CAST(%s.user_id AS INTEGER) = users.id)' % cls._table_name
|
||||
else:
|
||||
carddef_dataclass = field.carddef.data_class()
|
||||
carddef_table_alias = 't%s' % id(field.carddef)
|
||||
carddef_table_decl = 'LEFT JOIN %s AS %s ON (CAST(%s.%s AS INTEGER) = %s.id)' % (
|
||||
carddef_dataclass._table_name,
|
||||
carddef_table_alias,
|
||||
cls._table_name,
|
||||
get_field_id(field.parent_field),
|
||||
carddef_table_alias)
|
||||
|
||||
if carddef_table_decl not in tables:
|
||||
tables.append(carddef_table_decl)
|
||||
|
||||
column_field_id = get_field_id(field.carddef_field)
|
||||
if field.carddef_field.store_display_value:
|
||||
column_field_id = get_field_id(field.related_field)
|
||||
if field.related_field.store_display_value:
|
||||
column_field_id += '_display'
|
||||
columns.append('%s.%s' % (carddef_table_alias, column_field_id))
|
||||
extra_fields.append(field.id)
|
||||
|
|
|
@ -80,6 +80,11 @@ class User(StorableObject):
|
|||
from .admin.settings import UserFieldsFormDef
|
||||
return UserFieldsFormDef()
|
||||
|
||||
@classmethod
|
||||
def get_fields(cls):
|
||||
formdef = cls.get_formdef()
|
||||
return formdef.fields or []
|
||||
|
||||
@property
|
||||
def ascii_name(self):
|
||||
return simplify(self.get_display_name(), space=' ')
|
||||
|
|
Loading…
Reference in New Issue