Skip to content

Commit baafffd

Browse files
authored
Merge pull request #36213 from dimagi/bmb/dc/select-records-mismatch-alert
[Data Cleaning] Show an alert to the user when there are selected records not visible in the current filtered view
2 parents 947df6e + 648a00d commit baafffd

File tree

4 files changed

+59
-5
lines changed

4 files changed

+59
-5
lines changed

corehq/apps/data_cleaning/models.py

+15
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,21 @@ def get_queryset(self):
254254
def get_num_selected_records(self):
255255
return self.records.filter(is_selected=True).count()
256256

257+
def get_num_selected_records_in_queryset(self):
258+
case_ids = self.records.filter(is_selected=True).values_list(
259+
"doc_id", flat=True
260+
)
261+
262+
from corehq.apps.hqwebapp.tables.elasticsearch.tables import ElasticTableData
263+
264+
num_selected_records = 0
265+
for doc_ids in chunked(case_ids, BULK_OPERATION_CHUNK_SIZE, list):
266+
num_selected_records += ElasticTableData.get_total_records_in_query(
267+
self.get_queryset().case_ids(doc_ids)
268+
)
269+
270+
return num_selected_records
271+
257272
def get_num_edited_records(self):
258273
return self.records.filter(changes__isnull=False).count()
259274

corehq/apps/data_cleaning/tables.py

+22
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from memoized import memoized
2+
13
from django.utils.translation import gettext_lazy
24
from django_tables2 import columns, tables
35

@@ -65,13 +67,33 @@ def get_columns_from_session(cls, session):
6567
return visible_columns
6668

6769
@property
70+
@memoized
71+
def has_any_filtering(self):
72+
"""
73+
Return whether any filtering is applied to the session.
74+
"""
75+
return self.session.has_any_filtering
76+
77+
@property
78+
@memoized
6879
def num_selected_records(self):
6980
"""
7081
Return the number of selected records in the session.
7182
"""
7283
return self.session.get_num_selected_records()
7384

7485
@property
86+
@memoized
87+
def num_visible_selected_records(self):
88+
"""
89+
Return the number of selected records visible with the current set of filters.
90+
"""
91+
if self.has_any_filtering:
92+
return self.session.get_num_selected_records_in_queryset()
93+
return self.num_selected_records
94+
95+
@property
96+
@memoized
7597
def num_edited_records(self):
7698
"""
7799
Return the number of edited records in the session.

corehq/apps/data_cleaning/templates/data_cleaning/tables/table_with_controls.html

+12-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
{% block table-container-attrs %}
66
{{ block.super }}
77
x-data="{
8-
numRecordsSelected: {{ table.num_selected_records }},
8+
numRecordsSelected: {{ table.num_visible_selected_records }},
99
totalRecords: {{ table.page.paginator.count }},
1010
pageTotalRecords: {{ table.paginated_rows|length }},
1111
pageNumRecordsSelected: 0,
@@ -36,7 +36,7 @@
3636
{% block before_table %}
3737
<div class="d-flex align-items-center pb-2">
3838

39-
{% if table.session.has_any_filtering %}
39+
{% if table.has_any_filtering %}
4040
<div class="pe-2">
4141
<div class="input-group">
4242
<div class="input-group-text">
@@ -76,6 +76,16 @@
7676
{% blocktrans %}
7777
Records Selected
7878
{% endblocktrans %}
79+
{% if table.num_visible_selected_records != table.num_selected_records %}
80+
<div
81+
class="ms-2 ps-2 border-start inline-block text-warning"
82+
data-bs-custom-class="fs-6"
83+
data-bs-title="{% trans 'Some records are selected in the session but not currently visible. They will not be part of cleaning actions until all filters are removed.' %}"
84+
x-tooltip=""
85+
>
86+
<i class="fa-solid fa-triangle-exclamation"></i>
87+
</div>
88+
{% endif %}
7989
</div>
8090
<button
8191
class="btn btn-outline-danger"

corehq/apps/hqwebapp/tables/elasticsearch/tables.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def _get_records(self, start, stop):
103103
raise ValueError("'stop' must be greater than 'start'")
104104
size = stop - start
105105
page_query = self.query.start(start).size(size)
106-
results = self._get_es_results(page_query)
106+
results = self.get_es_results(page_query)
107107
self.data = [self.table.record_class(record, self.table.request, **self.record_kwargs)
108108
for record in results['hits'].get('hits', [])]
109109
return self.data
@@ -133,14 +133,21 @@ def __len__(self):
133133
@property
134134
@memoized
135135
def _total_records(self):
136-
res = self._get_es_results(self.query.size(0))
136+
return self.get_total_records_in_query(self.query)
137+
138+
@classmethod
139+
def get_total_records_in_query(cls, query):
140+
"""
141+
Returns the total number of records in the ESQuery.
142+
"""
143+
res = cls.get_es_results(query.size(0))
137144
if res is not None:
138145
return res['hits'].get('total', 0)
139146
else:
140147
return 0
141148

142149
@staticmethod
143-
def _get_es_results(query):
150+
def get_es_results(query):
144151
try:
145152
return query.run().raw
146153
except ESError as e:

0 commit comments

Comments
 (0)