mirror of
https://github.com/wagtail/wagtail.git
synced 2024-11-29 09:33:54 +01:00
Implement ordering by date in Form Submission View
* add url parsing for ordering * add data_fields_with_ordering * send data_fields_with_ordering and use in template * use full words 'ascending' not 'asc' * add styles for ordered headings * add links for changing ordering to headings * linting * move field ordering to the form page model * use form page model field ordering * view to use rearranged field ordering * add tests for new submission list ordering * change to be easier to read * Update tests to reflect new listing with ordering information
This commit is contained in:
parent
fa302c0853
commit
f219493365
@ -689,3 +689,28 @@ td.ord {
|
||||
margin-top: -28px;
|
||||
}
|
||||
}
|
||||
|
||||
table.listing {
|
||||
th.ordered {
|
||||
color: $color-teal;
|
||||
|
||||
&.ascending {
|
||||
&:before {
|
||||
content: '\25B2'; // up arrow
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
&.descending {
|
||||
&:before {
|
||||
content: '\25BC'; // down arrow
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -212,6 +212,33 @@ class AbstractForm(Page):
|
||||
def get_landing_page_template(self, request, *args, **kwargs):
|
||||
return self.landing_page_template
|
||||
|
||||
def get_field_ordering(self, ordering_list, default=('submit_time', 'descending')):
|
||||
"""
|
||||
Accepts a list of strings ['-submit_time', 'id']
|
||||
Returns a list of tuples [(field_name, 'ascending'/'descending'), ...]
|
||||
Intented to be used to process ordering via request.GET.getlist('order_by')
|
||||
Checks if the field options are valid, only returns valid, de-duplicated options
|
||||
invalid options are simply ignored - no error created
|
||||
"""
|
||||
valid_fields = ['id', 'submit_time']
|
||||
field_ordering = []
|
||||
if len(ordering_list) == 0:
|
||||
return [default]
|
||||
for ordering in ordering_list:
|
||||
try:
|
||||
none, prefix, field_name = ordering.rpartition('-')
|
||||
if field_name not in valid_fields:
|
||||
continue # Invalid field_name, skip it
|
||||
# only add to ordering if the field is not already set
|
||||
if field_name not in [order[0] for order in field_ordering]:
|
||||
asc_desc = 'ascending'
|
||||
if prefix == '-':
|
||||
asc_desc = 'descending'
|
||||
field_ordering.append((field_name, asc_desc))
|
||||
except (IndexError, ValueError):
|
||||
continue # Invalid ordering specified, skip it
|
||||
return field_ordering
|
||||
|
||||
def get_submission_class(self):
|
||||
"""
|
||||
Returns submission class.
|
||||
|
@ -6,14 +6,16 @@
|
||||
<col />
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="{{ data_headings|length|add:1 }}">
|
||||
<th colspan="{{ data_fields_with_ordering|length|add:1 }}">
|
||||
<button class="button no" id="delete-submissions" style="visibility: hidden">{% trans "Delete selected submissions" %}</button>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><input type="checkbox" id="select-all" /></th>
|
||||
{% for heading in data_headings %}
|
||||
<th>{{ heading }}</th>
|
||||
{% for heading in data_fields_with_ordering %}
|
||||
<th id="{{ heading.name }}" class="{% if heading.order %}ordered {{ heading.order }}{% endif %}">
|
||||
{% if heading.order %}<a href="?order_by={% if heading.order == 'ascending' %}-{% endif %}{{ heading.name }}">{{ heading.label }}</a>{% else %}{{ heading.label }}{% endif %}
|
||||
</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -300,6 +300,33 @@ class TestFormsSubmissionsList(TestCase, WagtailTestUtils):
|
||||
# Check that we got the last page
|
||||
self.assertEqual(response.context['submissions'].number, response.context['submissions'].paginator.num_pages)
|
||||
|
||||
def test_list_submissions_default_order(self):
|
||||
response = self.client.get(reverse(
|
||||
'wagtailforms:list_submissions', args=(self.form_page.id,)))
|
||||
# check default ordering, most recent responses first
|
||||
first_row_values = response.context['data_rows'][0]['fields']
|
||||
self.assertTrue('this is a fairly new message' in first_row_values)
|
||||
|
||||
def test_list_submissions_url_params_ordering_recent_first(self):
|
||||
response = self.client.get(reverse(
|
||||
'wagtailforms:list_submissions',
|
||||
args=(self.form_page.id,)),
|
||||
{'order_by': '-submit_time'}
|
||||
)
|
||||
# check ordering matches '-submit_time' (most recent first)
|
||||
first_row_values = response.context['data_rows'][0]['fields']
|
||||
self.assertTrue('this is a fairly new message' in first_row_values)
|
||||
|
||||
def test_list_submissions_url_params_ordering_oldest_first(self):
|
||||
response = self.client.get(reverse(
|
||||
'wagtailforms:list_submissions',
|
||||
args=(self.form_page.id,)),
|
||||
{'order_by': 'submit_time'}
|
||||
)
|
||||
# check ordering matches 'submit_time' (oldest first)
|
||||
first_row_values = response.context['data_rows'][0]['fields']
|
||||
self.assertTrue('this is a really old message' in first_row_values)
|
||||
|
||||
|
||||
class TestFormsSubmissionsExport(TestCase, WagtailTestUtils):
|
||||
def setUp(self):
|
||||
@ -673,7 +700,7 @@ class TestCustomFormsSubmissionsList(TestCase, WagtailTestUtils):
|
||||
self.assertEqual(len(response.context['data_rows']), 2)
|
||||
|
||||
# CustomFormPageSubmission have custom field. This field should appear in the listing
|
||||
self.assertContains(response, '<th>Username</th>', html=True)
|
||||
self.assertContains(response, '<th id="username" class="">Username</th>', html=True)
|
||||
self.assertContains(response, '<td>user-m1kola</td>', html=True)
|
||||
self.assertContains(response, '<td>user-john</td>', html=True)
|
||||
|
||||
@ -688,7 +715,7 @@ class TestCustomFormsSubmissionsList(TestCase, WagtailTestUtils):
|
||||
self.assertEqual(len(response.context['data_rows']), 1)
|
||||
|
||||
# CustomFormPageSubmission have custom field. This field should appear in the listing
|
||||
self.assertContains(response, '<th>Username</th>', html=True)
|
||||
self.assertContains(response, '<th id="username" class="">Username</th>', html=True)
|
||||
self.assertContains(response, '<td>user-m1kola</td>', html=True)
|
||||
|
||||
def test_list_submissions_filtering_date_to(self):
|
||||
@ -702,7 +729,7 @@ class TestCustomFormsSubmissionsList(TestCase, WagtailTestUtils):
|
||||
self.assertEqual(len(response.context['data_rows']), 1)
|
||||
|
||||
# CustomFormPageSubmission have custom field. This field should appear in the listing
|
||||
self.assertContains(response, '<th>Username</th>', html=True)
|
||||
self.assertContains(response, '<th id="username" class="">Username</th>', html=True)
|
||||
self.assertContains(response, '<td>user-john</td>', html=True)
|
||||
|
||||
def test_list_submissions_filtering_range(self):
|
||||
@ -717,7 +744,7 @@ class TestCustomFormsSubmissionsList(TestCase, WagtailTestUtils):
|
||||
self.assertEqual(len(response.context['data_rows']), 1)
|
||||
|
||||
# CustomFormPageSubmission have custom field. This field should appear in the listing
|
||||
self.assertContains(response, '<th>Username</th>', html=True)
|
||||
self.assertContains(response, '<th id="username" class="">Username</th>', html=True)
|
||||
self.assertContains(response, '<td>user-m1kola</td>', html=True)
|
||||
|
||||
def test_list_submissions_pagination(self):
|
||||
@ -733,7 +760,7 @@ class TestCustomFormsSubmissionsList(TestCase, WagtailTestUtils):
|
||||
self.assertEqual(response.context['submissions'].number, 2)
|
||||
|
||||
# CustomFormPageSubmission have custom field. This field should appear in the listing
|
||||
self.assertContains(response, '<th>Username</th>', html=True)
|
||||
self.assertContains(response, '<th id="username" class="">Username</th>', html=True)
|
||||
self.assertContains(response, 'generated-username-', count=20)
|
||||
|
||||
def test_list_submissions_pagination_invalid(self):
|
||||
|
@ -68,7 +68,30 @@ def list_submissions(request, page_id):
|
||||
|
||||
data_fields = form_page.get_data_fields()
|
||||
|
||||
submissions = form_submission_class.objects.filter(page=form_page).order_by('submit_time')
|
||||
ordering = form_page.get_field_ordering(request.GET.getlist('order_by'))
|
||||
|
||||
# convert ordering tuples to a list of strings like ['-submit_time']
|
||||
ordering_strings = [
|
||||
'%s%s' % ('-' if order_str[1] == 'descending' else '', order_str[0])
|
||||
for order_str in ordering]
|
||||
|
||||
if request.GET.get('action') == 'CSV':
|
||||
# Revert to CSV being sorted submit_time ascending for backwards compatibility
|
||||
submissions = form_submission_class.objects.filter(page=form_page).order_by('submit_time')
|
||||
else:
|
||||
submissions = form_submission_class.objects.filter(page=form_page).order_by(*ordering_strings)
|
||||
|
||||
data_fields_with_ordering = []
|
||||
for name, label in data_fields:
|
||||
order = None
|
||||
for order_value in [o[1] for o in ordering if o[0] == name]:
|
||||
order = order_value
|
||||
data_fields_with_ordering.append({
|
||||
"name": name,
|
||||
"label": label,
|
||||
"order": order,
|
||||
})
|
||||
|
||||
data_headings = [label for name, label in data_fields]
|
||||
|
||||
select_date_form = SelectDateForm(request.GET)
|
||||
@ -127,6 +150,6 @@ def list_submissions(request, page_id):
|
||||
'form_page': form_page,
|
||||
'select_date_form': select_date_form,
|
||||
'submissions': submissions,
|
||||
'data_headings': data_headings,
|
||||
'data_fields_with_ordering': data_fields_with_ordering,
|
||||
'data_rows': data_rows
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user