Skip to content

Commit

Permalink
Merge pull request #35488 from dimagi/jc/enterprise-console-metric
Browse files Browse the repository at this point in the history
Show metric description in Enterprise Console
  • Loading branch information
jingcheng16 authored Dec 10, 2024
2 parents 155b20c + 55df4bd commit 6d5e403
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 58 deletions.
46 changes: 29 additions & 17 deletions corehq/apps/enterprise/enterprise.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from abc import ABC, abstractmethod
import re
from django.db.models import Count
from datetime import datetime, timedelta
Expand Down Expand Up @@ -30,7 +31,7 @@
from corehq.apps.users.models import CouchUser, Invitation


class EnterpriseReport:
class EnterpriseReport(ABC):
DOMAINS = 'domains'
WEB_USERS = 'web_users'
MOBILE_USERS = 'mobile_users'
Expand All @@ -40,8 +41,18 @@ class EnterpriseReport:

DATE_ROW_FORMAT = '%Y/%m/%d %H:%M:%S'

title = _('Enterprise Report')
subtitle = ''
@property
@abstractmethod
def title(self):
pass

@property
@abstractmethod
def total_description(self):
"""
To provide a description of the total number we displayed in tile
"""
pass

def __init__(self, account, couch_user, **kwargs):
self.account = account
Expand Down Expand Up @@ -115,7 +126,9 @@ def total(self):


class EnterpriseDomainReport(EnterpriseReport):
title = _('Project Spaces')

title = gettext_lazy('Project Spaces')
total_description = gettext_lazy('# of Project Spaces')

@property
def headers(self):
Expand All @@ -138,7 +151,9 @@ def total_for_domain(self, domain_obj):


class EnterpriseWebUserReport(EnterpriseReport):
title = _('Web Users')

title = gettext_lazy('Web Users')
total_description = gettext_lazy('# of Web Users')

@property
def headers(self):
Expand Down Expand Up @@ -184,7 +199,8 @@ def total_for_domain(self, domain_obj):


class EnterpriseMobileWorkerReport(EnterpriseReport):
title = _('Mobile Workers')
title = gettext_lazy('Mobile Workers')
total_description = gettext_lazy('# of Mobile Workers')

@property
def headers(self):
Expand Down Expand Up @@ -215,7 +231,9 @@ def total_for_domain(self, domain_obj):


class EnterpriseFormReport(EnterpriseReport):
title = _('Mobile Form Submissions')
title = gettext_lazy('Mobile Form Submissions')
total_description = gettext_lazy('# of Mobile Form Submissions')

MAXIMUM_USERS_PER_DOMAIN = getattr(settings, 'ENTERPRISE_REPORT_DOMAIN_USER_LIMIT', 20_000)
MAXIMUM_ROWS_PER_REQUEST = getattr(settings, 'ENTERPRISE_REPORT_ROW_LIMIT', 1_000_000)
MAX_DATE_RANGE_DAYS = 90
Expand All @@ -231,13 +249,8 @@ def __init__(self, account, couch_user, start_date=None, end_date=None, num_days
if isinstance(start_date, str):
start_date = datetime.fromisoformat(start_date)
self.datespan = DateSpan(start_date, end_date)
self.subtitle = _("{} to {}").format(
start_date.date(),
end_date.date(),
)
else:
self.datespan = DateSpan(end_date - timedelta(days=num_days), end_date)
self.subtitle = _("past {} days").format(num_days)

if self.datespan.enddate - self.datespan.startdate > timedelta(days=self.MAX_DATE_RANGE_DAYS):
raise TooMuchRequestedDataError(
Expand Down Expand Up @@ -328,6 +341,8 @@ def total_for_domain(self, domain_obj):

class EnterpriseODataReport(EnterpriseReport):
title = gettext_lazy('OData Feeds')
total_description = gettext_lazy('# of OData Feeds')

MAXIMUM_EXPECTED_EXPORTS = 150

def __init__(self, account, couch_user):
Expand Down Expand Up @@ -392,6 +407,8 @@ def _get_individual_export_rows(self, exports, export_line_counts):

class EnterpriseSMSReport(EnterpriseReport):
title = gettext_lazy('SMS Usage')
total_description = gettext_lazy('# of SMS Sent')

MAX_DATE_RANGE_DAYS = 90

def __init__(self, account, couch_user, start_date=None, end_date=None, num_days=30):
Expand All @@ -406,13 +423,8 @@ def __init__(self, account, couch_user, start_date=None, end_date=None, num_days
if isinstance(start_date, str):
start_date = datetime.fromisoformat(start_date)
self.datespan = DateSpan(start_date, end_date)
self.subtitle = _("{} to {}").format(
start_date.date(),
end_date.date(),
)
else:
self.datespan = DateSpan(end_date - timedelta(days=num_days), end_date)
self.subtitle = _("past {} days").format(num_days)

if self.datespan.enddate - self.datespan.startdate > timedelta(days=self.MAX_DATE_RANGE_DAYS):
raise TooMuchRequestedDataError(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
{% load hq_shared_tags %}
{% load i18n %}

<div class="modal" role="dialog" tabindex="-1" id="enterpriseFormsDaterange">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{% trans 'Customize Mobile Form Submissions Date Range' %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{% trans_html_attr 'Close' %}"></button>
</div>
<div class="modal-body">
<select-toggle name="range_type" data-apply-bindings="false" params="value: presetType, options: presetOptions"></select-toggle>
<div class="row">
<div class="col-xs-6 pt-1">
<input type="text" name="date_range" class="form-control" id="id_date_range" data-bind="visible: displayCustom">
<div id="clarifyingText" class="form-control-plaintext" data-bind="html: clarifyingText, visible: !displayCustom()"></div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-primary" data-bind="click: onCancel" data-bs-dismiss="modal">{% trans 'Cancel' %}</button>
<button type="button" class="btn btn-primary" data-bind="click: onApply" data-bs-dismiss="modal">{% trans 'Apply' %}</button>
</div>
<div class="modal fade" role="dialog" tabindex="-1" id="enterpriseFormsDaterange">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{% trans 'Customize Mobile Form Submissions Date Range' %}</h5>
<button
type="button" class="btn-close" aria-label="{% trans_html_attr 'Close' %}"
data-bs-dismiss="modal"
></button>
</div>
<div class="modal-body">
<select-toggle
name="range_type"
data-apply-bindings="false"
params="value: presetType, options: presetOptions"
></select-toggle>
<div class="row">
<div class="col-xs-6 pt-1">
<input type="text" name="date_range" class="form-control" id="id_date_range" data-bind="visible: displayCustom">
<div
class="form-control-plaintext" id="clarifyingText"
data-bind="html: clarifyingText, visible: !displayCustom()"
></div>
</div>
</div>
</div>
<div class="modal-footer">
<button
class="btn btn-outline-primary" type="button"
data-bind="click: onCancel"
data-bs-dismiss="modal"
>{% trans 'Cancel' %}</button>
<button
class="btn btn-primary" type="button"
data-bind="click: onApply"
data-bs-dismiss="modal"
>{% trans 'Apply' %}</button>
</div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
{% load i18n %}

<div class="col-md-6 col-lg-6 col-xl-3">
<div class="card text-center report-panel mb-3" data-slug="{{ report.slug }}" id="{{ report.slug }}">
<div class="card-header">
<div class="fs-4">{{ report.title }}</div>
<div
class="card text-center report-panel mb-3" id="{{ report.slug }}"
data-slug="{{ report.slug }}"
>
<div class="card-header">
<h4 class="fs-5 pt-2">{{ report.title }}</h4>
</div>
<div class="card-body pb-5">
<div class="total fw-bold fs-1">
<i class="fa fa-spin fa-spinner"></i>
</div>
<div class="fs-5">{{ report.total_description }}</div>
<div class="py-2">
{% if report.title == "Mobile Form Submissions" %}
<button id="form_submission_dateRangeDisplay" type="button" data-bind="text: presetText" data-bs-toggle="modal" data-bs-target="#enterpriseFormsDaterange" data-sender="form_submission" class="btn btn-link fs-6">&nbsp;</button>
<button
class="btn btn-link fs-6" id="form_submission_dateRangeDisplay" type="button"
data-bind="text: presetText"
data-bs-toggle="modal"
data-bs-target="#enterpriseFormsDaterange"
data-sender="form_submission"
>&nbsp;</button>
{% elif report.title == "SMS Usage" %}
<button id="sms_dateRangeDisplay" type="button" data-bind="text: presetText" data-bs-toggle="modal" data-bs-target="#enterpriseFormsDaterange" data-sender="sms" class="btn btn-link fs-6">&nbsp;</button>
<button
class="btn btn-link fs-6" id="sms_dateRangeDisplay" type="button"
data-bind="text: presetText"
data-bs-toggle="modal"
data-bs-target="#enterpriseFormsDaterange"
data-sender="sms"
>&nbsp;</button>
{% else %}
<div class="form-control-plaintext fs-6">{{ report.subtitle|default:"&nbsp;" }}</div>
<div class="form-control-plaintext fs-6">{{ "&nbsp;" }}</div>
{% endif %}
</div>
<div class="card-body">
<h1 class="card-text total">
<i class="fa fa-spin fa-spinner"></i>
</h1>
<br>
<button class="btn btn-primary btn-lg">
<i class="fa fa-envelope"></i>
{% trans "Email Report" %}
</button>
</div>
</div>
<button class="btn btn-primary btn-lg">
<i class="fa fa-envelope"></i>
{% trans "Email Report" %}
</button>
</div>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
{% initial_page_data 'max_date_range_days' max_date_range_days %}
{% initial_page_data 'metric_type' metric_type %}

<div class="row">
<div class="row mt-4">
{% for report in reports %}
{% include 'enterprise/partials/project_tile.html' with report=report %}
{% endfor %}
Expand Down
2 changes: 0 additions & 2 deletions corehq/apps/enterprise/tests/test_enterprise.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ def test_constructor_with_no_datespan_defaults_to_last_30_days(self):

self.assertEqual(report.datespan.startdate, datetime(month=9, day=1, year=2024))
self.assertEqual(report.datespan.enddate, datetime(month=10, day=1, year=2024))
self.assertEqual(report.subtitle, 'past 30 days')

def test_constructor_with_provided_dates_uses_that_datespan(self):
start_date = datetime(month=11, day=25, year=2023)
Expand All @@ -155,7 +154,6 @@ def test_constructor_with_provided_dates_uses_that_datespan(self):

self.assertEqual(report.datespan.startdate, start_date)
self.assertEqual(report.datespan.enddate, end_date)
self.assertEqual(report.subtitle, '2023-11-25 to 2023-12-15')

def test_constructor_with_only_end_date_uses_default_num_days(self):
end_date = datetime(month=10, day=1, year=2020)
Expand Down

0 comments on commit 6d5e403

Please sign in to comment.