Esempio n. 1
0
    def test_delete_master_deletes_linked(self):
        linked_report_info = create_linked_ucr(self.domain_link, self.report.get_id)
        soft_delete(self.report)
        update_linked_ucr(self.domain_link, linked_report_info.report.get_id)
        report = ReportConfiguration.get(linked_report_info.report.get_id)
        self.assertTrue(is_deleted(report))

        self.report.config.deactivate()
        update_linked_ucr(self.domain_link, linked_report_info.report.get_id)
        report = ReportConfiguration.get(linked_report_info.report.get_id)
        self.assertTrue(report.config.is_deactivated)
Esempio n. 2
0
def update_linked_ucr(domain_link, report_id):
    linked_report = ReportConfiguration.get(report_id)
    linked_datasource = linked_report.config

    if domain_link.is_remote:
        remote_configs = remote_get_ucr_config(domain_link, report_id)
        master_report = remote_configs["report"]
        master_datasource = remote_configs["datasource"]
    else:
        master_report = ReportConfiguration.get(linked_report.report_meta.master_id)
        master_datasource = master_report.config

    _update_linked_datasource(master_datasource, linked_datasource)
    _update_linked_report(master_report, linked_report)
Esempio n. 3
0
    def test_remote_link_ucr(self, fake_ucr_getter):
        create_domain(self.domain)
        self.addCleanup(delete_all_domains)

        couch_user = WebUser.create(self.domain, "test", "foobar", None, None)
        django_user = couch_user.get_django_user()
        self.addCleanup(delete_all_users)

        api_key, _ = HQApiKey.objects.get_or_create(user=django_user)
        auth_headers = {'HTTP_AUTHORIZATION': 'apikey test:%s' % api_key.key}
        self.domain_link.save()

        url = reverse('linked_domain:ucr_config', args=[self.domain, self.report.get_id])
        headers = auth_headers.copy()
        headers[REMOTE_REQUESTER_HEADER] = self.domain_link.linked_domain
        resp = self.client.get(url, **headers)

        fake_ucr_getter.return_value = json.loads(resp.content)

        # Create
        linked_report_info = create_linked_ucr(self.domain_link, self.report.get_id)
        self.assertEqual(1, len(ReportConfiguration.by_domain(self.domain_link.linked_domain)))
        self.assertEqual(self.report.get_id, linked_report_info.report.report_meta.master_id)

        # Update
        self.report.title = "Another new title"
        self.report.save()

        update_linked_ucr(self.domain_link, linked_report_info.report.get_id)
        report = ReportConfiguration.get(linked_report_info.report.get_id)
        self.assertEqual("Another new title", report.title)
Esempio n. 4
0
def pop_report(report_id, reports):
    report = reports.pop(report_id, None)
    if report is None:
        report = ReportConfiguration.get(report_id)
        if report.doc_type == "ReportConfiguration-Deleted":
            return None
    return report
Esempio n. 5
0
    def _make_model_cell(self, record):
        name = LINKED_MODELS_MAP[record.model]
        if record.model == MODEL_APP:
            detail = record.wrapped_detail
            app_name = ugettext_lazy('Unknown App')
            if detail:
                app_names = self.linked_app_names(self.selected_link.linked_domain)
                app_name = app_names.get(detail.app_id, detail.app_id)
            return '{} ({})'.format(name, app_name)

        if record.model == MODEL_FIXTURE:
            detail = record.wrapped_detail
            tag = ugettext_lazy('Unknown')
            if detail:
                data_type = get_fixture_data_type_by_tag(self.selected_link.linked_domain, detail.tag)
                if data_type:
                    tag = data_type.tag
            return '{} ({})'.format(name, tag)

        if record.model == MODEL_REPORT:
            detail = record.wrapped_detail
            report_name = ugettext_lazy('Unknown Report')
            if detail:
                try:
                    report_name = ReportConfiguration.get(detail.report_id).title
                except ResourceNotFound:
                    pass
            return '{} ({})'.format(name, report_name)

        return name
Esempio n. 6
0
    def test_link_creates_datasource_and_report(self):
        link_info = create_linked_ucr(self.domain_link, self.report.get_id)

        new_datasource = DataSourceConfiguration.get(link_info.datasource.get_id)
        self.assertEqual(new_datasource.domain, self.domain_link.linked_domain)

        new_report = ReportConfiguration.get(link_info.report.get_id)
        self.assertEqual(new_report.domain, self.domain_link.linked_domain)
        self.assertEqual(self.report.get_id, new_report.report_meta.master_id)
Esempio n. 7
0
def ucr_config(request, domain, config_id):
    report_config = ReportConfiguration.get(config_id)
    datasource_id = report_config.config_id
    datasource_config = DataSourceConfiguration.get(datasource_id)

    return JsonResponse({
        "report": report_config.to_json(),
        "datasource": datasource_config.to_json(),
    })
Esempio n. 8
0
def pop_report_for_action(action, reports):
    report_id = action.wrapped_detail.report_id
    try:
        report = reports.get(report_id)
        del reports[report_id]
    except KeyError:
        report = ReportConfiguration.get(report_id)

    return report
Esempio n. 9
0
    def test_update_ucr(self):
        linked_report_info = create_linked_ucr(self.domain_link, self.report.get_id)
        self.report.title = "New title"
        self.report.save()

        update_linked_ucr(self.domain_link, linked_report_info.report.get_id)

        report = ReportConfiguration.get(linked_report_info.report.get_id)
        self.assertEqual("New title", report.title)
        self.assertEqual(self.report.get_id, report.report_meta.master_id)
        self.assertNotEqual(self.report.config_id, report.config_id)
Esempio n. 10
0
def create_linked_ucr(domain_link, report_config_id):
    if domain_link.is_remote:
        remote_configs = remote_get_ucr_config(domain_link, report_config_id)
        datasource = remote_configs["datasource"]
        report_config = remote_configs["report"]
    else:
        report_config = ReportConfiguration.get(report_config_id)
        datasource = DataSourceConfiguration.get(report_config.config_id)
    new_datasource = _get_or_create_datasource_link(domain_link, datasource)
    new_report = _get_or_create_report_link(domain_link, report_config, new_datasource)
    return LinkedUCRInfo(datasource=new_datasource, report=new_report)
Esempio n. 11
0
 def test_linked_report_with_app_id_is_not_updated(self):
     self.linked_report.config.meta.build.app_id = self.linked_app._id
     self.linked_report.save()
     self.assertEqual(self.linked_app._id,
                      self.linked_report.config.meta.build.app_id)
     num_of_failed_attempts = migrate_linked_reports()
     self.assertEqual(0, num_of_failed_attempts)
     # refetch
     actual_report = ReportConfiguration.get(self.linked_report._id)
     self.assertEqual(self.linked_app._id,
                      actual_report.config.meta.build.app_id)
Esempio n. 12
0
    def _get_master_model_status(self,
                                 apps,
                                 fixtures,
                                 reports,
                                 ignore_models=None):
        model_status = []
        ignore_models = ignore_models or []

        for model, name in LINKED_MODELS:
            if (model not in ignore_models
                    and model not in (MODEL_APP, MODEL_FIXTURE, MODEL_REPORT)
                    and
                (model != MODEL_CASE_SEARCH
                 or toggles.SYNC_SEARCH_CASE_CLAIM.enabled(self.domain))):
                model_status.append({
                    'type': model,
                    'name': name,
                    'last_update': ugettext('Never'),
                    'detail': None,
                    'can_update': True
                })

        linked_models = dict(LINKED_MODELS)
        for app in apps.values():
            update = {
                'type': MODEL_APP,
                'name': '{} ({})'.format(linked_models['app'], app.name),
                'last_update': None,
                'detail': AppLinkDetail(app_id=app._id).to_json(),
                'can_update': True
            }
            model_status.append(update)
        for fixture in fixtures.values():
            update = {
                'type': MODEL_FIXTURE,
                'name': '{} ({})'.format(linked_models['fixture'],
                                         fixture.tag),
                'last_update': None,
                'detail': FixtureLinkDetail(tag=fixture.tag).to_json(),
                'can_update': fixture.is_global,
            }
            model_status.append(update)
        for report in reports.values():
            report = ReportConfiguration.get(report.get_id)
            update = {
                'type': MODEL_REPORT,
                'name': f"{linked_models['report']} ({report.title})",
                'last_update': None,
                'detail': ReportLinkDetail(report_id=report.get_id).to_json(),
                'can_update': True,
            }
            model_status.append(update)

        return model_status
Esempio n. 13
0
    def _get_model_status(self, master_link, apps, reports):
        model_status = []
        if not master_link:
            return model_status

        models_seen = set()
        history = DomainLinkHistory.objects.filter(link=master_link).annotate(row_number=RawSQL(
            'row_number() OVER (PARTITION BY model, model_detail ORDER BY date DESC)',
            []
        ))
        linked_models = dict(LINKED_MODELS)
        timezone = get_timezone_for_request()
        for action in history:
            models_seen.add(action.model)
            if action.row_number != 1:
                # first row is the most recent
                continue
            name = linked_models[action.model]
            update = {
                'type': action.model,
                'name': name,
                'last_update': server_to_user_time(action.date, timezone),
                'detail': action.model_detail,
                'can_update': True
            }
            if action.model == 'app':
                app_name = ugettext('Unknown App')
                if action.model_detail:
                    detail = action.wrapped_detail
                    app = apps.pop(detail.app_id, None)
                    app_name = app.name if app else detail.app_id
                    if app:
                        update['detail'] = action.model_detail
                    else:
                        update['can_update'] = False
                else:
                    update['can_update'] = False
                update['name'] = '{} ({})'.format(name, app_name)
            model_status.append(update)
            if action.model == 'report':
                report_id = action.wrapped_detail.report_id
                try:
                    report = reports.get(report_id)
                    del reports[report_id]
                except KeyError:
                    report = ReportConfiguration.get(report_id)
                update['name'] = f'{name} ({report.title})'

        # Add in models and apps that have never been synced
        model_status.extend(self._get_master_model_status(apps, reports, ignore_models=models_seen))

        return model_status
Esempio n. 14
0
    def test_app_id_for_linked_reports_updates_given_family_id(self):
        self.linked_report.config.meta.build.app_id = None
        self.linked_report.save()
        self.assertIsNone(self.linked_report.config.meta.build.app_id)
        self.linked_app.family_id = self.original_app._id
        self.linked_app.upstream_app_id = None
        self.linked_app.save()

        num_of_failed_attempts = migrate_linked_reports()
        self.assertEqual(0, num_of_failed_attempts)
        # refetch
        actual_report = ReportConfiguration.get(self.linked_report._id)
        self.assertEqual(self.linked_app._id,
                         actual_report.config.meta.build.app_id)
Esempio n. 15
0
def migrate_linked_reports(upstream_domain=None):
    logger.setLevel(logging.INFO)
    if upstream_domain:
        domain_links = DomainLink.all_objects.filter(
            master_domain=upstream_domain)
    else:
        domain_links = DomainLink.all_objects.all()

    num_of_failed_attempts = 0
    for domain_link in domain_links:
        reports = get_report_configs_for_domain(domain_link.linked_domain)
        for report in reports:
            if report.report_meta.master_id and not report.config.meta.build.app_id:
                upstream_report = ReportConfiguration.get(
                    report.report_meta.master_id)
                upstream_datasource = DataSourceConfiguration.get(
                    upstream_report.config_id)
                downstream_app_id = get_downstream_app_id(
                    domain_link.linked_domain,
                    upstream_datasource.meta.build.app_id,
                )
                if not downstream_app_id:
                    # just as a backup in case upstream_app_id is not set but family_id is
                    downstream_app_id = get_downstream_app_id(
                        domain_link.linked_domain,
                        upstream_datasource.meta.build.app_id,
                        use_upstream_app_id=False)
                    if downstream_app_id:
                        logger.info(
                            f"Needed to use family_id to find downstream app {downstream_app_id}"
                        )

                if not downstream_app_id:
                    logger.warning(
                        f"Could not find downstream_app_id for upstream app"
                        f" {upstream_datasource.meta.build.app_id} "
                        f"in downstream domain {domain_link.linked_domain}")
                    num_of_failed_attempts += 1

                report.config.meta.build.app_id = downstream_app_id
                report.config.save()
    logger.info(
        f"Completed linked report migration with {num_of_failed_attempts} failed attempts"
    )
    return num_of_failed_attempts
Esempio n. 16
0
def create_linked_ucr(domain_link, report_config_id):
    if domain_link.is_remote:
        remote_configs = remote_get_ucr_config(domain_link, report_config_id)
        datasource = remote_configs["datasource"]
        report_config = remote_configs["report"]
    else:
        report_config = ReportConfiguration.get(report_config_id)
        datasource = DataSourceConfiguration.get(report_config.config_id)

    # grab the linked app this linked report references
    try:
        downstream_app_id = get_downstream_app_id(domain_link.linked_domain, datasource.meta.build.app_id)
    except MultipleDownstreamAppsError:
        raise DomainLinkError(_("This report cannot be linked because it references an app that has multiple "
                                "downstream apps."))

    new_datasource = _get_or_create_datasource_link(domain_link, datasource, downstream_app_id)
    new_report = _get_or_create_report_link(domain_link, report_config, new_datasource)
    return LinkedUCRInfo(datasource=new_datasource, report=new_report)
Esempio n. 17
0
    def export_table(self):
        try:
            data = self.data_source
            data.set_filter_values(self.filter_values)
        except UserReportsError as e:
            return self.render_json_response({
                'error': e.message,
            })

        report_config = ReportConfiguration.get(self.report_config_id)
        raw_rows = list(data.get_data())
        headers = [column['display'] for column in report_config.columns]
        columns = [column['field'] for column in report_config.columns]
        rows = [[raw_row[column] for column in columns] for raw_row in raw_rows]
        return [
            [
                self.title,
                [headers] + rows
            ]
        ]
Esempio n. 18
0
def _safely_get_report_configs(project_name):
    try:
        configs = ReportConfiguration.by_domain(project_name)
    except BadSpecError as e:
        logging.exception(e)

        # Pick out the UCRs that don't have spec errors
        configs = []
        for config_id in get_doc_ids_in_domain_by_class(project_name, ReportConfiguration):
            try:
                configs.append(ReportConfiguration.get(config_id))
            except BadSpecError as e:
                logging.error("%s with report config %s" % (e.message, config_id))

    try:
        configs.extend(StaticReportConfiguration.by_domain(project_name))
    except BadSpecError as e:
        logging.exception(e)

    return configs
Esempio n. 19
0
    def _release_report(self, domain_link, model):
        report_id = model['detail']['report_id']
        found = False
        for linked_report in get_report_configs_for_domain(domain_link.linked_domain):
            if linked_report.report_meta.master_id == report_id:
                found = True
                update_linked_ucr(domain_link, linked_report.get_id)

        if not found:
            report = ReportConfiguration.get(report_id)
            if report.report_meta.created_by_builder:
                view = 'edit_report_in_builder'
            else:
                view = 'edit_configurable_report'
            url = get_url_base() + reverse(view, args=[domain_link.master_domain, report_id])
            return self._error_tuple(
                _('Could not find report. <a href="{}">Click here</a> and click "Link Report" to link this '
                  + 'report.').format(url),
                text=_('Could not find report. Please check that the report has been linked.'),
            )
Esempio n. 20
0
def _safely_get_report_configs(project_name):
    try:
        configs = ReportConfiguration.by_domain(project_name)
    except BadSpecError as e:
        logging.exception(e)

        # Pick out the UCRs that don't have spec errors
        configs = []
        for config_id in get_doc_ids_in_domain_by_class(project_name, ReportConfiguration):
            try:
                configs.append(ReportConfiguration.get(config_id))
            except BadSpecError as e:
                logging.error("%s with report config %s" % (e.message, config_id))

    try:
        configs.extend(StaticReportConfiguration.by_domain(project_name))
    except BadSpecError as e:
        logging.exception(e)

    return configs
Esempio n. 21
0
    def _make_model_cell(self, record):
        name = LINKED_MODELS_MAP[record.model]
        if record.model == 'app':
            detail = record.wrapped_detail
            app_name = ugettext_lazy('Unknown App')
            if detail:
                app_names = self.linked_app_names(self.selected_link.linked_domain)
                app_name = app_names.get(detail.app_id, detail.app_id)
            return '{} ({})'.format(name, app_name)

        if record.model == 'report':
            detail = record.wrapped_detail
            report_name = ugettext_lazy('Unknown Report')
            if detail:
                try:
                    report_name = ReportConfiguration.get(detail.report_id).title
                except ResourceNotFound:
                    pass
            return '{} ({})'.format(name, report_name)

        return name
Esempio n. 22
0
    def export_table(self):
        try:
            data = self.data_source
            data.set_filter_values(self.filter_values)
            data.set_order_by([(o['field'], o['order']) for o in self.spec.sort_expression])
        except UserReportsError as e:
            return self.render_json_response({
                'error': e.message,
            })

        report_config = ReportConfiguration.get(self.report_config_id)
        raw_rows = list(data.get_data())
        headers = [column.header for column in self.data_source.columns]
        columns = [column.column_id for column in report_config.report_columns]
        rows = [[raw_row[column] for column in columns] for raw_row in raw_rows]
        return [
            [
                self.title,
                [headers] + rows
            ]
        ]
    def test_remote_link_ucr(self, fake_ucr_getter):

        fake_ucr_getter.return_value = {
            "report": self.report,
            "datasource": self.data_source,
        }

        # Create
        linked_report_info = create_linked_ucr(self.domain_link,
                                               self.report.get_id)
        self.assertEqual(
            1,
            len(ReportConfiguration.by_domain(self.domain_link.linked_domain)))
        self.assertEqual(self.report.get_id,
                         linked_report_info.report.report_meta.master_id)

        # Update
        self.report.title = "Another new title"
        self.report.save()

        update_linked_ucr(self.domain_link, linked_report_info.report.get_id)
        report = ReportConfiguration.get(linked_report_info.report.get_id)
        self.assertEqual("Another new title", report.title)
Esempio n. 24
0
    def _get_model_status(self, master_link, apps, fixtures, reports,
                          keywords):
        model_status = []
        if not master_link:
            return model_status

        models_seen = set()
        history = DomainLinkHistory.objects.filter(
            link=master_link
        ).annotate(row_number=RawSQL(
            'row_number() OVER (PARTITION BY model, model_detail ORDER BY date DESC)',
            []))
        linked_models = dict(LINKED_MODELS)
        timezone = get_timezone_for_request()
        for action in history:
            models_seen.add(action.model)
            if action.row_number != 1:
                # first row is the most recent
                continue
            name = linked_models[action.model]
            update = {
                'type': action.model,
                'name': name,
                'last_update': server_to_user_time(action.date, timezone),
                'detail': action.model_detail,
                'can_update': True
            }
            if action.model == 'app':
                app_name = ugettext('Unknown App')
                if action.model_detail:
                    detail = action.wrapped_detail
                    app = apps.pop(detail.app_id, None)
                    app_name = app.name if app else detail.app_id
                    if app:
                        update['detail'] = action.model_detail
                    else:
                        update['can_update'] = False
                else:
                    update['can_update'] = False
                update['name'] = '{} ({})'.format(name, app_name)

            if action.model == 'fixture':
                tag_name = ugettext('Unknown Table')
                can_update = False
                if action.model_detail:
                    detail = action.wrapped_detail
                    tag = action.wrapped_detail.tag
                    try:
                        fixture = fixtures.get(tag)
                        del fixtures[tag]
                    except KeyError:
                        fixture = get_fixture_data_type_by_tag(
                            self.domain, tag)
                    tag_name = fixture.tag
                    can_update = fixture.is_global
                update['name'] = f'{name} ({tag_name})'
                update['can_update'] = can_update
            if action.model == 'report':
                report_id = action.wrapped_detail.report_id
                try:
                    report = reports.get(report_id)
                    del reports[report_id]
                except KeyError:
                    report = ReportConfiguration.get(report_id)
                update['name'] = f'{name} ({report.title})'
            if action.model == 'keyword':
                keyword_id = action.wrapped_detail.linked_keyword_id
                try:
                    keyword = keywords[keyword_id].keyword
                    del keywords[keyword_id]
                except KeyError:
                    try:
                        keyword = Keyword.objects.get(id=keyword_id).keyword
                    except Keyword.DoesNotExist:
                        keyword = ugettext_lazy("Deleted Keyword")
                        update['can_update'] = False
                update['name'] = f'{name} ({keyword})'

            model_status.append(update)

        # Add in models and apps that have never been synced
        model_status.extend(
            self._get_master_model_status(apps,
                                          fixtures,
                                          reports,
                                          keywords,
                                          ignore_models=models_seen))

        return model_status
Esempio n. 25
0
    def _get_master_model_status(self,
                                 apps,
                                 fixtures,
                                 reports,
                                 keywords,
                                 ignore_models=None):
        model_status = []
        ignore_models = ignore_models or []

        for model, name in LINKED_MODELS:
            if (model not in ignore_models
                    and model not in (MODEL_APP, MODEL_FIXTURE, MODEL_REPORT,
                                      MODEL_KEYWORD) and
                (model != MODEL_CASE_SEARCH
                 or toggles.SYNC_SEARCH_CASE_CLAIM.enabled(self.domain))
                    and (model != MODEL_DATA_DICTIONARY
                         or toggles.DATA_DICTIONARY.enabled(self.domain))
                    and (model != MODEL_DIALER_SETTINGS
                         or toggles.WIDGET_DIALER.enabled(self.domain))
                    and (model != MODEL_OTP_SETTINGS
                         or toggles.GAEN_OTP_SERVER.enabled(self.domain))
                    and (model != MODEL_HMAC_CALLOUT_SETTINGS
                         or toggles.HMAC_CALLOUT.enabled(self.domain))):
                model_status.append({
                    'type': model,
                    'name': name,
                    'last_update': ugettext('Never'),
                    'detail': None,
                    'can_update': True
                })

        linked_models = dict(LINKED_MODELS)
        for app in apps.values():
            update = {
                'type': MODEL_APP,
                'name': '{} ({})'.format(linked_models['app'], app.name),
                'last_update': None,
                'detail': AppLinkDetail(app_id=app._id).to_json(),
                'can_update': True
            }
            model_status.append(update)
        for fixture in fixtures.values():
            update = {
                'type': MODEL_FIXTURE,
                'name': '{} ({})'.format(linked_models['fixture'],
                                         fixture.tag),
                'last_update': None,
                'detail': FixtureLinkDetail(tag=fixture.tag).to_json(),
                'can_update': fixture.is_global,
            }
            model_status.append(update)
        for report in reports.values():
            report = ReportConfiguration.get(report.get_id)
            update = {
                'type': MODEL_REPORT,
                'name': f"{linked_models['report']} ({report.title})",
                'last_update': None,
                'detail': ReportLinkDetail(report_id=report.get_id).to_json(),
                'can_update': True,
            }
            model_status.append(update)

        for keyword in keywords.values():
            update = {
                'type': MODEL_KEYWORD,
                'name': f"{linked_models['keyword']} ({keyword.keyword})",
                'last_update': None,
                'detail':
                KeywordLinkDetail(keyword_id=str(keyword.id)).to_json(),
                'can_update': True,
            }
            model_status.append(update)

        return model_status
Esempio n. 26
0
    def _report_config_to_fixture(report_config, user):
        report_elem = E.report(id=report_config.uuid)
        try:
            report = ReportConfiguration.get(report_config.report_id)
        except ResourceNotFound as err:
            # ReportConfiguration not found
            raise BadReportConfigurationError('Error getting ReportConfiguration with ID "{}": {}'.format(
                report_config.report_id, err))
        data_source = ReportFactory.from_spec(report)

        all_filter_values = {
            filter_slug: filter.get_filter_value(user, report.get_ui_filter(filter_slug))
            for filter_slug, filter in report_config.filters.items()
        }
        filter_values = {
            filter_slug: filter_value for filter_slug, filter_value in all_filter_values.items()
            if filter_value is not None
        }
        defer_filters = {
            filter_slug: report.get_ui_filter(filter_slug)
            for filter_slug, filter_value in all_filter_values.items()
            if filter_value is None
        }
        data_source.set_filter_values(filter_values)
        data_source.defer_filters(defer_filters)

        rows_elem = E.rows()

        deferred_fields = {ui_filter.field for ui_filter in defer_filters.values()}
        filter_options_by_field = defaultdict(set)

        def _row_to_row_elem(row, index, is_total_row=False):
            row_elem = E.row(index=str(index), is_total_row=str(is_total_row))
            for k in sorted(row.keys()):
                value = serialize(row[k])
                row_elem.append(E.column(value, id=k))
                if not is_total_row and k in deferred_fields:
                    filter_options_by_field[k].add(value)
            return row_elem

        for i, row in enumerate(data_source.get_data()):
            rows_elem.append(_row_to_row_elem(row, i))

        if data_source.has_total_row:
            total_row = data_source.get_total_row()
            rows_elem.append(_row_to_row_elem(
                dict(
                    zip(
                        map(lambda column_config: column_config.column_id, data_source.column_configs),
                        map(str, total_row)
                    )
                ),
                data_source.get_total_records(),
                is_total_row=True,
            ))

        filters_elem = E.filters()
        for filter_slug, ui_filter in defer_filters.items():
            # @field is maybe a bad name for this attribute,
            # since it's actually the filter slug
            filter_elem = E.filter(field=filter_slug)
            option_values = filter_options_by_field[ui_filter.field]
            choices = ui_filter.choice_provider.get_sorted_choices_for_values(option_values)
            for choice in choices:
                # add the correct text from ui_filter.choice_provider
                option_elem = E.option(choice.display, value=choice.value)
                filter_elem.append(option_elem)
            filters_elem.append(filter_elem)

        report_elem.append(filters_elem)
        report_elem.append(rows_elem)
        return report_elem