diff --git a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/reports/filters/multi_option.html.diff.txt b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/reports/filters/multi_option.html.diff.txt index c944a0432f26..747778376632 100644 --- a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/reports/filters/multi_option.html.diff.txt +++ b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/reports/filters/multi_option.html.diff.txt @@ -1,8 +1,55 @@ --- +++ -@@ -1,4 +1,4 @@ +@@ -1,26 +1,37 @@ -{% extends 'reports/filters/bootstrap3/base.html' %} +{% extends 'reports/filters/bootstrap5/base.html' %} {% load hq_shared_tags %} {% block filter_content %} {% if not endpoint %} +- ++ + {% else %} +- ++ + {% endif %} + {% if filter_help_inline or search_help_inline %} + + {{ filter_help_inline }} +- {% if filter_help_inline and search_help_inline %}
{% endif %} ++ {% if filter_help_inline and search_help_inline %} ++
++ {% endif %} + {{ search_help_inline }} +
+ {% endif %} diff --git a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/reports/filters/simple.html.diff.txt b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/reports/filters/simple.html.diff.txt index a7cf716342da..61b30ea572fa 100644 --- a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/reports/filters/simple.html.diff.txt +++ b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/reports/filters/simple.html.diff.txt @@ -1,6 +1,6 @@ --- +++ -@@ -1,9 +1,9 @@ +@@ -1,29 +1,33 @@ -{% extends 'reports/filters/bootstrap3/base.html' %} +{% extends 'reports/filters/bootstrap5/base.html' %} {% load hq_shared_tags %} @@ -10,14 +10,46 @@ -
+
{% endif %} - +- {% if help_inline %} +-

+- +- {{ help_inline }} +-

+- {% endif %} ++ ++ {% if help_inline %} ++

++ ++ {{ help_inline }} ++

++ {% endif %} {% if help_title and help_content %}
-
+- +
- +
+
+ {% endif %} diff --git a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/reports/filters/single_option.html.diff.txt b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/reports/filters/single_option.html.diff.txt index c8218f7b675f..df8ca4818944 100644 --- a/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/reports/filters/single_option.html.diff.txt +++ b/corehq/apps/hqwebapp/tests/data/bootstrap5_diffs/reports/filters/single_option.html.diff.txt @@ -1,26 +1,53 @@ --- +++ -@@ -1,4 +1,4 @@ +@@ -1,23 +1,33 @@ -{% extends 'reports/filters/bootstrap3/base.html' %} +{% extends 'reports/filters/bootstrap5/base.html' %} {% load hq_shared_tags %} {% block filter_content %} {% if pagination.enabled %} -@@ -7,7 +7,7 @@ - data-handler="{{ pagination.handler }}" - data-url="{{ pagination.url }}" - data-action="{{ pagination.action }}" +- -@@ -16,7 +16,7 @@ - data-select-options="{% html_attr select.options %}" - data-selected="{{ select.selected|default:'' }}" - class="report-filter-single-option" +- data-placeholder="{{ select.default_text }}" +- data-selected="{{ select.selected|default:'' }}" +- name="{{ slug }}"> ++ + {% else %} +- +- data-bind="options: select_params, optionsText: 'text', optionsValue: 'val', {% if select.default_text %}optionsCaption: '{{ select.default_text|escapejs }}', {% endif %}value: current_selection" +- name="{{ slug }}"> ++ {% endif %} + {% endblock %} diff --git a/corehq/apps/hqwebapp/utils/bootstrap/reports/progress/bootstrap3_to_5.json b/corehq/apps/hqwebapp/utils/bootstrap/reports/progress/bootstrap3_to_5.json index f886b067fd2c..8898c19b1310 100644 --- a/corehq/apps/hqwebapp/utils/bootstrap/reports/progress/bootstrap3_to_5.json +++ b/corehq/apps/hqwebapp/utils/bootstrap/reports/progress/bootstrap3_to_5.json @@ -1,5 +1,19 @@ { - "reports": [], - "filters": [], - "filter_templates": [] + "reports": [ + "ApplicationStatusReport", + "CaseListReport" + ], + "filters": [ + "corehq.apps.reports.filters.case_list.CaseListFilter", + "corehq.apps.reports.filters.select.CaseTypeFilter", + "corehq.apps.reports.filters.select.SelectApplicationFilter", + "corehq.apps.reports.filters.select.SelectOpenCloseFilter", + "corehq.apps.reports.filters.users.ExpandedMobileWorkerFilter", + "corehq.apps.reports.standard.cases.filters.CaseSearchFilter" + ], + "filter_templates": [ + "reports/filters/bootstrap5/multi_option.html", + "reports/filters/bootstrap5/simple.html", + "reports/filters/bootstrap5/single_option.html" + ] } diff --git a/corehq/apps/reports/standard/cases/basic.py b/corehq/apps/reports/standard/cases/basic.py index 71b5f9370436..90776070cae4 100644 --- a/corehq/apps/reports/standard/cases/basic.py +++ b/corehq/apps/reports/standard/cases/basic.py @@ -155,6 +155,7 @@ class CaseListReport(CaseListMixin, ProjectReport, ReportDataSource): name = gettext_lazy('Case List') slug = 'case_list' + use_bootstrap5 = True @classmethod def get_subpages(cls): @@ -201,13 +202,20 @@ def slugs(self): @property def headers(self): headers = DataTablesHeader( - DataTablesColumn(_("Case Type"), prop_name="type.exact"), - DataTablesColumn(_("Name"), prop_name="name.exact", css_class="case-name-link"), - DataTablesColumn(_("Owner"), prop_name="owner_display", sortable=False), - DataTablesColumn(_("Created Date"), prop_name="opened_on"), - DataTablesColumn(_("Created By"), prop_name="opened_by_display", sortable=False), - DataTablesColumn(_("Modified Date"), prop_name="modified_on"), - DataTablesColumn(_("Status"), prop_name="get_status_display", sortable=False) + DataTablesColumn(_("Case Type"), prop_name="type.exact", + use_bootstrap5=self.use_bootstrap5), + DataTablesColumn(_("Name"), prop_name="name.exact", css_class="case-name-link", + use_bootstrap5=self.use_bootstrap5), + DataTablesColumn(_("Owner"), prop_name="owner_display", sortable=False, + use_bootstrap5=self.use_bootstrap5), + DataTablesColumn(_("Created Date"), prop_name="opened_on", + use_bootstrap5=self.use_bootstrap5), + DataTablesColumn(_("Created By"), prop_name="opened_by_display", sortable=False, + use_bootstrap5=self.use_bootstrap5), + DataTablesColumn(_("Modified Date"), prop_name="modified_on", + use_bootstrap5=self.use_bootstrap5), + DataTablesColumn(_("Status"), prop_name="get_status_display", sortable=False, + use_bootstrap5=self.use_bootstrap5) ) headers.custom_sort = [[5, 'desc']] return headers diff --git a/corehq/apps/reports/standard/cases/case_list_explorer.py b/corehq/apps/reports/standard/cases/case_list_explorer.py index dee2803f4544..b2be44b70b23 100644 --- a/corehq/apps/reports/standard/cases/case_list_explorer.py +++ b/corehq/apps/reports/standard/cases/case_list_explorer.py @@ -59,6 +59,7 @@ class CaseListExplorer(CaseListReport, XpathCaseSearchFilterMixin): search_class = CaseSearchES description = _("Use Case List Explorer to run deep searches on your cases by case properties. ") documentation_link = DOCS_LINK_CASE_LIST_EXPLORER + use_bootstrap5 = False exportable = True exportable_all = True diff --git a/corehq/apps/reports/standard/cases/duplicate_cases.py b/corehq/apps/reports/standard/cases/duplicate_cases.py index 4c46520ed2e0..d2483b9a9746 100644 --- a/corehq/apps/reports/standard/cases/duplicate_cases.py +++ b/corehq/apps/reports/standard/cases/duplicate_cases.py @@ -20,6 +20,7 @@ class DuplicateCasesExplorer(CaseListExplorer): name = _("Duplicate Cases") slug = 'duplicate_cases' description = _("Identify and manage duplicate cases") + use_bootstrap5 = False fields = [ DuplicateCaseRuleFilter, diff --git a/corehq/apps/reports/standard/deployments.py b/corehq/apps/reports/standard/deployments.py index 001b27470bef..e42cc6bd58ad 100644 --- a/corehq/apps/reports/standard/deployments.py +++ b/corehq/apps/reports/standard/deployments.py @@ -75,6 +75,7 @@ class ApplicationStatusReport(GetParamsMixin, PaginatedReportMixin, DeploymentsR 'corehq.apps.reports.filters.select.SelectApplicationFilter' ] primary_sort_prop = None + use_bootstrap5 = True @property def _columns(self): @@ -84,37 +85,45 @@ def _columns(self): return [ DataTablesColumn(_("Username"), prop_name='username.exact', - sql_col='user_dim__username'), + sql_col='user_dim__username', + use_bootstrap5=self.use_bootstrap5), DataTablesColumn(_("Assigned Location(s)"), help_text=_('Assigned locations for the user, with the primary ' 'location highlighted in bold.'), - sortable=False), + sortable=False, + use_bootstrap5=self.use_bootstrap5), DataTablesColumn(_("Last Submission"), prop_name='reporting_metadata.last_submissions.submission_date', alt_prop_name='reporting_metadata.last_submission_for_user.submission_date', - sql_col='last_form_submission_date'), + sql_col='last_form_submission_date', + use_bootstrap5=self.use_bootstrap5), DataTablesColumn(_("Last Sync"), prop_name='reporting_metadata.last_syncs.sync_date', alt_prop_name='reporting_metadata.last_sync_for_user.sync_date', - sql_col='last_sync_log_date'), + sql_col='last_sync_log_date', + use_bootstrap5=self.use_bootstrap5), DataTablesColumn(_("Application"), help_text=_("The name of the application from the user's last request."), - sortable=False), + sortable=False, + use_bootstrap5=self.use_bootstrap5), DataTablesColumn(_("Application Version"), help_text=_("The application version from the user's last request."), prop_name='reporting_metadata.last_builds.build_version', alt_prop_name='reporting_metadata.last_build_for_user.build_version', - sql_col='last_form_app_build_version'), + sql_col='last_form_app_build_version', + use_bootstrap5=self.use_bootstrap5), DataTablesColumn(_("CommCare Version"), help_text=_("""The CommCare version from the user's last request"""), prop_name='reporting_metadata.last_submissions.commcare_version', alt_prop_name='reporting_metadata.last_submission_for_user.commcare_version', - sql_col='last_form_app_commcare_version'), + sql_col='last_form_app_commcare_version', + use_bootstrap5=self.use_bootstrap5), DataTablesColumn(_("Number of unsent forms in user's phone"), help_text=_("The number of unsent forms in users' phones for {app_info}".format( app_info=selected_app_info )), - sortable=False), + sortable=False, + use_bootstrap5=self.use_bootstrap5), ] @property @@ -124,7 +133,8 @@ def headers(self): columns.append( DataTablesColumn(_("Build Profile"), help_text=_("The build profile from the user's last hearbeat request."), - sortable=False) + sortable=False, + use_bootstrap5=self.use_bootstrap5) ) headers = DataTablesHeader(*columns) headers.custom_sort = [[2, 'desc']] @@ -162,41 +172,43 @@ def sort_filter(self): def get_sorting_block(self): sort_prop_name = 'prop_name' if self.selected_app_id else 'alt_prop_name' - res = [] - #the NUMBER of cols sorting - sort_cols = int(self.request.GET.get('iSortingCols', 0)) - if sort_cols > 0: - for x in range(sort_cols): - col_key = 'iSortCol_%d' % x - sort_dir = self.request.GET['sSortDir_%d' % x] - col_id = int(self.request.GET[col_key]) - col = self.headers.header[col_id] - sort_prop = getattr(col, sort_prop_name) or col.prop_name - if x == 0: - self.primary_sort_prop = sort_prop - if self.selected_app_id: - sort_dict = { - sort_prop: { - "order": sort_dir, - "nested_filter": { - "term": { - self.sort_filter: self.selected_app_id - } - } - } + block = [] + for col in self.datatables_params.order: + col_ind = col['column'] + sort_dir = col['dir'] + dt_column_obj = self.headers.header[col_ind] + sort_prop = getattr(dt_column_obj, sort_prop_name) or dt_column_obj.prop_name + if col_ind == 0: + # this feels like a bit of a hack, but kept it in from the original sorting block + # prior to bootstrap 5 migration. could use a second look in the future + self.primary_sort_prop = sort_prop + if self.selected_app_id: + sort_dict = self._get_selected_app_sort_dict(sort_prop, sort_dir) + else: + sort_dict = {sort_prop: sort_dir} + block.append(sort_dict) + if len(block) == 0 and self.default_sort is not None: + block.append(self.default_sort) + return block + + def _get_selected_app_sort_dict(self, sort_prop, sort_dir): + sort_dict = { + sort_prop: { + "order": sort_dir, + "nested_filter": { + "term": { + self.sort_filter: self.selected_app_id } - sort_prop_path = sort_prop.split('.') - if sort_prop_path[-1] == 'exact': - sort_prop_path.pop() - sort_prop_path.pop() - if sort_prop_path: - sort_dict[sort_prop]['nested_path'] = '.'.join(sort_prop_path) - else: - sort_dict = {sort_prop: sort_dir} - res.append(sort_dict) - if len(res) == 0 and self.default_sort is not None: - res.append(self.default_sort) - return res + } + } + } + sort_prop_path = sort_prop.split('.') + if sort_prop_path[-1] == 'exact': + sort_prop_path.pop() + sort_prop_path.pop() + if sort_prop_path: + sort_dict[sort_prop]['nested_path'] = '.'.join(sort_prop_path) + return sort_dict @property @memoized @@ -579,7 +591,7 @@ def _timedelta_class(delta): return _bootstrap_class(delta, timedelta(days=7), timedelta(days=3)) if not date: - text = format_html('{}', _("Never")) + text = format_html('{}', _("Never")) else: text = format_html( '{text}', @@ -602,11 +614,11 @@ def _bootstrap_class(obj, severe, warn): assumes bigger is worse and default is good. """ if obj > severe: - return "label label-danger" + return "badge text-bg-danger" elif obj > warn: - return "label label-warning" + return "badge text-bg-warning" else: - return "label label-success" + return "badge text-bg-success" def _get_histogram_aggregation_for_app(field_name, date_field_name, app_id): diff --git a/corehq/apps/reports/templates/reports/filters/bootstrap5/multi_option.html b/corehq/apps/reports/templates/reports/filters/bootstrap5/multi_option.html index fe2ab303fa46..6e31172af2d3 100644 --- a/corehq/apps/reports/templates/reports/filters/bootstrap5/multi_option.html +++ b/corehq/apps/reports/templates/reports/filters/bootstrap5/multi_option.html @@ -2,25 +2,36 @@ {% load hq_shared_tags %} {% block filter_content %} {% if not endpoint %} - + {% else %} - + {% endif %} {% if filter_help_inline or search_help_inline %} {{ filter_help_inline }} - {% if filter_help_inline and search_help_inline %}
{% endif %} + {% if filter_help_inline and search_help_inline %} +
+ {% endif %} {{ search_help_inline }}
{% endif %} diff --git a/corehq/apps/reports/templates/reports/filters/bootstrap5/simple.html b/corehq/apps/reports/templates/reports/filters/bootstrap5/simple.html index d9fe2735188b..1ffc936ff2bd 100644 --- a/corehq/apps/reports/templates/reports/filters/bootstrap5/simple.html +++ b/corehq/apps/reports/templates/reports/filters/bootstrap5/simple.html @@ -5,25 +5,29 @@
{% endif %} - - {% if help_inline %} -

- - {{ help_inline }} -

- {% endif %} + + {% if help_inline %} +

+ + {{ help_inline }} +

+ {% endif %} {% if help_title and help_content %}
- +
{% endif %} diff --git a/corehq/apps/reports/templates/reports/filters/bootstrap5/single_option.html b/corehq/apps/reports/templates/reports/filters/bootstrap5/single_option.html index bb8801d42936..c20bea8d3fae 100644 --- a/corehq/apps/reports/templates/reports/filters/bootstrap5/single_option.html +++ b/corehq/apps/reports/templates/reports/filters/bootstrap5/single_option.html @@ -2,22 +2,32 @@ {% load hq_shared_tags %} {% block filter_content %} {% if pagination.enabled %} - + {% else %} - + {% endif %} {% endblock %}