0004-backoffice-sorting-on-a-field-of-block-field-46500.patch
tests/backoffice_pages/test_columns.py | ||
---|---|---|
471 | 471 |
data_class = formdef.data_class() |
472 | 472 |
data_class.wipe() |
473 | 473 | |
474 |
formdata = data_class() |
|
475 |
formdata.data = { |
|
474 |
formdata1 = data_class()
|
|
475 |
formdata1.data = {
|
|
476 | 476 |
'8': { |
477 | 477 |
'data': [{'123': 'blah', '456': card.id, '456_display': card.default_digest}], |
478 | 478 |
'schema': {}, # not important here |
479 | 479 |
}, |
480 | 480 |
'8_display': 'blah', |
481 | 481 |
} |
482 |
formdata.just_created() |
|
483 |
formdata.jump_status('new') |
|
484 |
formdata.store() |
|
482 |
formdata1.just_created()
|
|
483 |
formdata1.jump_status('new')
|
|
484 |
formdata1.store()
|
|
485 | 485 | |
486 | 486 |
app = login(get_app(pub)) |
487 | 487 |
resp = app.get('/backoffice/management/form-title/') |
... | ... | |
504 | 504 |
assert resp.text.count('<tr') == 2 |
505 | 505 |
assert '<td>blah</td>' in resp |
506 | 506 |
assert '<td>Foo Bar</td>' in resp |
507 | ||
508 |
formdef.fields[0].max_items = 1 |
|
509 |
formdef.store() |
|
510 | ||
511 |
card2 = carddef.data_class()() |
|
512 |
card2.data = { |
|
513 |
'1': 'Bar2', |
|
514 |
'2': 'Foo2', |
|
515 |
} |
|
516 |
card2.store() |
|
517 | ||
518 |
formdata2 = data_class() |
|
519 |
formdata2.data = { |
|
520 |
'8': { |
|
521 |
'data': [{'123': 'blah', '456': card2.id, '456_display': card2.default_digest}], |
|
522 |
'schema': {}, # not important here |
|
523 |
}, |
|
524 |
'8_display': 'blah', |
|
525 |
} |
|
526 |
formdata2.just_created() |
|
527 |
formdata2.jump_status('new') |
|
528 |
formdata2.store() |
|
529 | ||
530 |
formdata3 = data_class() |
|
531 |
formdata3.data = { |
|
532 |
'8': { |
|
533 |
'data': [{'123': 'blah'}], |
|
534 |
'schema': {}, # not important here |
|
535 |
}, |
|
536 |
'8_display': 'blah', |
|
537 |
} |
|
538 |
formdata3.just_created() |
|
539 |
formdata3.jump_status('new') |
|
540 |
formdata3.store() |
|
541 | ||
542 |
resp = app.get('/backoffice/management/form-title/') |
|
543 |
assert [x.text_content() for x in resp.pyquery('#columns-filter label')] == [ |
|
544 |
'Number', |
|
545 |
'Created', |
|
546 |
'Last Modified', |
|
547 |
'User Label', |
|
548 |
'Status', |
|
549 |
'Block', |
|
550 |
'Block / Test', |
|
551 |
'Block / card field', |
|
552 |
'Anonymised', |
|
553 |
] |
|
554 |
resp.forms['listing-settings']['8-123'].checked = True |
|
555 |
resp.forms['listing-settings']['8-456'].checked = True |
|
556 |
resp = resp.forms['listing-settings'].submit() |
|
557 |
assert '<th data-field-sort-key="f8-123"><span>Block / Test</span></th>' in resp |
|
558 |
assert '<th data-field-sort-key="f8-456"><span>Block / card field</span></th>' in resp |
|
559 |
assert resp.text.count('<tr') == 4 |
|
560 | ||
561 |
# XXX ordering is done on card id, to be fixed with #60742 |
|
562 |
resp = app.get('/backoffice/management/form-title/?order_by=f8-456') |
|
563 |
ids = [int(x.strip('/')) for x in re.findall(r'data-link="(.*?)"', resp.text)] |
|
564 |
assert ids == [formdata1.id, formdata2.id, formdata3.id] |
|
565 | ||
566 |
resp = app.get('/backoffice/management/form-title/?order_by=-f8-456') |
|
567 |
ids = [int(x.strip('/')) for x in re.findall(r'data-link="(.*?)"', resp.text)] |
|
568 |
assert ids == [formdata3.id, formdata2.id, formdata1.id] |
wcs/forms/backoffice.py | ||
---|---|---|
111 | 111 |
field_sort_key = 'receipt_time' |
112 | 112 |
elif f.id in ('user-label', 'submission_agent'): |
113 | 113 |
field_sort_key = None |
114 |
elif getattr(f, 'is_related_field', False) or getattr(f, 'block_field', None): |
|
114 |
elif getattr(f, 'is_related_field', False): |
|
115 |
field_sort_key = None |
|
116 |
elif getattr(f, 'block_field', None) and f.block_field.max_items != 1: |
|
117 |
# allow sorting on a field of block field if there is one item only |
|
115 | 118 |
field_sort_key = None |
116 | 119 |
else: |
117 | 120 |
field_sort_key = 'f%s' % f.contextual_id |
... | ... | |
213 | 216 |
if order_by and not hasattr(formdata_class, 'get_sorted_ids'): |
214 | 217 |
# get_sorted_ids is only implemented in the SQL backend |
215 | 218 |
order_by = None |
219 | ||
220 |
def iter_fields(fields, block_field=None): |
|
221 |
for field in fields: |
|
222 |
field.contextual_id = field.id |
|
223 |
if block_field: |
|
224 |
if field.key == 'items': |
|
225 |
# not yet |
|
226 |
continue |
|
227 |
field.block_field = block_field |
|
228 |
field.contextual_id = '%s-%s' % (field.block_field.id, field.id) |
|
229 |
yield field |
|
230 |
if field.key == 'block': |
|
231 |
yield from iter_fields(field.block.fields, block_field=field) |
|
232 |
continue |
|
233 | ||
216 | 234 |
if order_by and not anonymise: |
235 |
direction = '' |
|
236 |
if order_by.startswith('-'): |
|
237 |
order_by = order_by[1:] |
|
238 |
direction = '-' |
|
239 |
for field in iter_fields(self.formdef.get_all_fields()): |
|
240 |
if getattr(field, 'block_field', None) and 'f%s' % field.contextual_id == order_by: |
|
241 |
# field of block field, sort on the first element |
|
242 |
order_by = "f%s->'data'->0->>'%s'" % (field.block_field.id, field.id) |
|
243 |
order_by = '%s%s' % (direction, order_by) |
|
217 | 244 |
ordered_ids = formdata_class.get_sorted_ids(order_by, clause=criterias) |
218 | 245 |
item_ids_dict = {x: True for x in item_ids} |
219 | 246 |
item_ids = [x for x in ordered_ids if x in item_ids_dict] |
wcs/sql.py | ||
---|---|---|
1654 | 1654 |
if order_by.startswith('-'): |
1655 | 1655 |
order_by = order_by[1:] |
1656 | 1656 |
direction = 'DESC' |
1657 |
order_by = order_by.replace('-', '_') |
|
1657 |
if '->' in order_by: |
|
1658 |
# sort on field of block field: f42->'data'->0->>'bf13e4d8a8-fb08-4808-b5ae-02d6247949b9' |
|
1659 |
parts = order_by.split('->') |
|
1660 |
order_by = '%s->%s' % (parts[0].replace('-', '_'), '->'.join(parts[1:])) |
|
1661 |
else: |
|
1662 |
order_by = order_by.replace('-', '_') |
|
1658 | 1663 | |
1659 | 1664 |
fields = [x[0] for x in cls._table_static_fields] + cls.get_data_fields() |
1660 |
if order_by not in fields: |
|
1665 |
if order_by.split('->')[0] not in fields: |
|
1666 |
# for a sort on field of block field, just check the existence of the block field |
|
1661 | 1667 |
return '' |
1662 | 1668 | |
1663 | 1669 |
return ' ORDER BY %s %s' % (order_by, direction) |
1664 |
- |