Skip to content

Instantly share code, notes, and snippets.

@benrudolph
Last active February 7, 2017 12:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benrudolph/bd714a0d6da4f12e89bcc705e797173f to your computer and use it in GitHub Desktop.
Save benrudolph/bd714a0d6da4f12e89bcc705e797173f to your computer and use it in GitHub Desktop.

Current infrastructure

Filters

Rendering

Filters are defined on the report on the fields attribute. Every filter is injected into the report context and then in a template they are looped over and rendered:

{% for field in report_filters %}
    <fieldset id="fieldset_{{ field.slug }}">
        <div class="form-group" id="group_{{ field.slug }}">
            {{ field.field|safe }}
        </div>
    </fieldset>
{% endfor %}

Each filter is responsible for rendering itself via the render command. The filters are not first rendered on page load. It happens like this:

  • First the reports template is loaded (TODO: find link to template)
  • Javascript in reports.async.js makes a query to that looks like
GET "/a/aspace/reports/async/submissions_by_form/?hq_filters=true&&startdate=2017-01-30&enddate=2017-02-05&filterSet=false&&"`
  • HQ processes the request and returns a dict:
{
    filters: "<HTML for the filters>",
    report: "<HTML for initial report page>",
    slug: "<slug for report e.g submissions_by_form>"
    title: "<title for report e.g. Submissions By Form>"
    url_root: "<root url e.g. /a/aspace/reports/async/>"
}
  • Success function calls loadFilters to splat in the filter HTML. Similar function is called for report body

Note: some of the report templates have links to other scripts that load when the html gets loaded.

Applying filters to reports

Filters are applied when the Apply button is hit on the report. The request makes the same call when initially rendering the filters.

First a call is made to the backend to get the filter HTML:

GET /a/aspace/reports/filters/submissions_by_form/?emw=t__0&emw=t__4&form_unknown=&form_unknown_xmlns=&form_app_id=&form_module=&form_xmlns=&sub_time=&startdate=2017-01-01&enddate=2017-01-31&

This returns a dict with the filter HTML put no report data:

{
filter: '<filter HTML>',
slug: '<slug>',
title: '<title>',
}

Then another query is fired off to get the report HTML

GET  "/a/aspace/reports/async/submissions_by_form/?hq_filters=true&&startdate=2017-01-30&enddate=2017-02-05&filterSet=true&&"

This returns a dict with the report html:

{
report: '<report HTML>'
filter: null,
slug: '<slug>',
title: '<title>',
}

A key difference here is that filterSet is set to true.

Routing

Most of the routing goes through corehq/apps/reports/dispatcher.py. Report classes are determined via the map_name attribute on the ReportDispatcher class. Various other available reports are added in via settings. The main method that does this is ReportDispatcher.get_reports.

Once we've gotten the report class by the slug, we instantiate it with the passed in params. Depending on the params passed in, we either return the report html or the filter html (as discussed above).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment