From bc138a63d22b8b00a3fb3f3fdb8054c40c891274 Mon Sep 17 00:00:00 2001 From: Dmytro Trotsko Date: Fri, 4 Jul 2025 23:32:20 +0300 Subject: [PATCH 1/3] In the Selected Indicators view, filter the Location choices down to those actually available for any of the selected indicators, or at least to the geo-levels available for any of the selected indicators. --- src/assets/js/selectedIndicatorsModal.js | 38 ++++++++++++++++-- src/epiportal/settings.py | 2 +- src/indicatorsets/urls.py | 3 +- src/indicatorsets/views.py | 40 +++++++++++++++++++ .../selectedIndicatorsModal.html | 18 ++------- 5 files changed, 81 insertions(+), 20 deletions(-) diff --git a/src/assets/js/selectedIndicatorsModal.js b/src/assets/js/selectedIndicatorsModal.js index 0d4af60..6b5002a 100644 --- a/src/assets/js/selectedIndicatorsModal.js +++ b/src/assets/js/selectedIndicatorsModal.js @@ -175,6 +175,29 @@ async function checkGeoCoverage(geoValue) { } } +function getAvailableGeos(indicators) { + var availableGeos = null; + + const csrftoken = Cookies.get("csrftoken"); + + const submitData = { + indicators: indicators + } + + $.ajax({ + url: "get_available_geos/", + type: "POST", + async: false, // Synchronous request to ensure availableGeos is populated before returning + dataType: "json", + contentType: "application/json", + headers: { "X-CSRFToken": csrftoken }, + data: JSON.stringify(submitData), + }).done(function (data) { + availableGeos = data.geographic_granularities; + }); + return availableGeos; +} + $("#geographic_value").on("select2:select", function (e) { var geo = e.params.data; checkGeoCoverage(geo.id).then((notCoveredIndicators) => { @@ -187,6 +210,14 @@ $("#geographic_value").on("select2:select", function (e) { $("#showSelectedIndicatorsButton").click(function () { alertPlaceholder.innerHTML = ""; + const availableGeos = getAvailableGeos(checkedIndicatorMembers); + const locationIds = $("#location_search").select2("data").map((item) => item.id); + $("#geographic_value").select2({ + data: availableGeos, + minimumInputLength: 0, + maximumSelectionLength: 5, + }); + $('#geographic_value').val(locationIds).trigger('change'); if (!indicatorHandler.checkForCovidcastIndicators()) { $('#geographic_value').val(null).trigger('change'); $("#geographic_value").prop("disabled", true); @@ -200,11 +231,10 @@ $("#showSelectedIndicatorsButton").click(function () { } }) }); - var otherEndpointLocationsWarning = `` + var otherEndpointLocationsWarning = `` if (indicatorHandler.getFluviewIndicators().length > 0) { $("#differentLocationNote").html(otherEndpointLocationsWarning) if (document.getElementsByName("fluviewRegions").length === 0) { diff --git a/src/epiportal/settings.py b/src/epiportal/settings.py index 661afc1..b1a6858 100644 --- a/src/epiportal/settings.py +++ b/src/epiportal/settings.py @@ -26,7 +26,7 @@ EPIVIS_URL = os.environ.get("EPIVIS_URL", "https://delphi.cmu.edu/epivis/") -EPIDATA_URL = os.environ.get("EPIDATA_URL", "https://api.delphi.cmu.edu/epidata/") +EPIDATA_URL = os.environ.get("EPIDATA_URL", "http://delphi_web_epidata/epidata/") EPIDATA_API_KEY = os.environ.get("EPIDATA_API_KEY", "") SENTRY_DSN = os.environ.get('SENTRY_DSN') diff --git a/src/indicatorsets/urls.py b/src/indicatorsets/urls.py index 8b1da73..f40a5d1 100644 --- a/src/indicatorsets/urls.py +++ b/src/indicatorsets/urls.py @@ -1,7 +1,7 @@ from django.urls import path from django.urls.resolvers import URLPattern from indicatorsets.views import (IndicatorSetListView, epivis, - generate_export_data_url, preview_data, create_query_code) + generate_export_data_url, preview_data, create_query_code, get_available_geos) urlpatterns: list[URLPattern] = [ path("", IndicatorSetListView.as_view(), name="indicatorsets"), @@ -9,4 +9,5 @@ path("export/", generate_export_data_url, name="export"), path("preview_data/", preview_data, name="preview_data"), path("create_query_code/", create_query_code, name="create_query_code"), + path("get_available_geos/", get_available_geos, name="get_available_geos"), ] diff --git a/src/indicatorsets/views.py b/src/indicatorsets/views.py index 8f6ac50..fbd5ed2 100644 --- a/src/indicatorsets/views.py +++ b/src/indicatorsets/views.py @@ -372,6 +372,7 @@ def preview_data(request): params = { "regions": regions, "epiweeks": f"{date_from}-{date_to}", + "api_key": settings.EPIDATA_API_KEY, } response = requests.get(f"{settings.EPIDATA_URL}fluview", params=params) if response.status_code == 200: @@ -451,3 +452,42 @@ def create_query_code(request): {"python_code_blocks": python_code_blocks, "r_code_blocks": r_code_blocks}, safe=False, ) + + +def get_available_geos(request): + if request.method == "POST": + geo_values = [] + data = json.loads(request.body) + indicators = data.get("indicators", []) + grouped_indicators = group_by_property(indicators, "data_source") + for data_source, indicators in grouped_indicators.items(): + indicators_str = ",".join(indicator["indicator"] for indicator in indicators) + response = requests.get(f"{settings.EPIDATA_URL}covidcast/indicator_geo_coverage", params={"data_source": data_source, "signals": indicators_str}, auth=("epidata", settings.EPIDATA_API_KEY)) + if response.status_code == 200: + data = response.json() + if len(data["epidata"]): + geo_values.extend(data["epidata"]) + unique_values = set(geo_values) + geo_levels = set([el.split(":")[0] for el in unique_values]) + geo_unit_ids = set([geo_value.split(":")[1] for geo_value in unique_values]) + geographic_granularities = [ + { + "id": f"{geo_unit.geo_level.name}:{geo_unit.geo_id}", + "geoType": geo_unit.geo_level.name, + "text": geo_unit.display_name, + "geoTypeDisplayName": geo_unit.geo_level.display_name, + } + for geo_unit in GeographyUnit.objects.filter(geo_level__name__in=geo_levels).filter(geo_id__in=geo_unit_ids) + .prefetch_related("geo_level") + .order_by("level") + ] + grouped_geographic_granularities = group_by_property( + geographic_granularities, "geoTypeDisplayName" + ) + geographic_granularities = [] + for key, value in grouped_geographic_granularities.items(): + geographic_granularities.append({ + "text": key, + "children": value, + }) + return JsonResponse({"geographic_granularities": geographic_granularities}, safe=False) diff --git a/src/templates/indicatorsets/selectedIndicatorsModal.html b/src/templates/indicatorsets/selectedIndicatorsModal.html index 73ea492..baed0ca 100644 --- a/src/templates/indicatorsets/selectedIndicatorsModal.html +++ b/src/templates/indicatorsets/selectedIndicatorsModal.html @@ -129,19 +129,9 @@