Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/assets/css/custom_styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ tr:not(.odd-row) > .dtfc-fixed-end {

.table-stats-info {
font-size: 20px;
margin-bottom: 10px;
}

/* Mobile Filter Sidebar */
Expand Down
155 changes: 124 additions & 31 deletions src/assets/js/indicatorSetsTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,60 +11,153 @@ function calculate_table_height() {
}

var table = new DataTable("#indicatorSetsTable", {
serverSide: true,
ajax: {
url: `${window.location.pathname}${window.location.search.replace(/[?&]format=[^&]*/, "")}${window.location.search ? "&" : "?"}format=json`,
dataSrc: "data"
},
columns: [
{
className: 'dt-control',
orderable: false,
data: null,
defaultContent: ''
}, // dt-control column
{ data: "name" }, // Name
{
data: "pathogens",
render: function (data, type, row) {
if (data) {
return data.map(pathogen => `<span class="badge badge-pill-outline">${pathogen.display_name}</span>`).join('');
} else {
return '';
}
}
}, // Pathogens
{ data: "geographic_scope" }, // Geographic Coverage
{
data: "geographic_levels",
render: function (data, type, row) {
if (data) {
return data.map(geography => `<span class="badge badge-pill-outline">${geography.display_name}</span>`).join('');
} else {
return '';
}
}
}, // Geographic Levels
{ data: "temporal_scope_start" }, // Temporal Scope Start
{ data: "temporal_scope_end" }, // Temporal Scope End
{
data: "temporal_granularity",
render: function (data, type, row) {
if (data) {
return `<span class="badge badge-pill-outline">${data}</span>`;
} else {
return '';
}
}
}, // Temporal Granularity
{ data: "reporting_cadence" }, // Reporting Cadence
{ data: "reporting_lag" }, // Reporting Lag
{ data: "revision_cadence" }, // Revision Cadence
{ data: "demographic_scope" }, // Population
{ data: "demographic_granularity" }, // Population Stratifiers
{
data: "severity_pyramid_rungs",
render: function (data, type, row) {
if (data) {
return data.map(severity_pyramid_rung => `<span class="badge badge-pill-outline">${severity_pyramid_rung.display_name}</span>`).join('');
} else {
return '';
}
}
}, // Surveillance Categories
{ data: "original_data_provider" }, // Original Data Provider
{ data: "preprocessing_description" }, // Pre-processing
{ data: "censoring" }, // Censoring
{ data: "missingness" }, // Missingness
{ data: "delphi_hosted" }, // Hosted by Delphi?
{ data: "dua_required" }, // DUA required?
{ data: "license" }, // Data Use Terms
{
data: "documentation_link",
render: function (data, type, row) {
if (data) {
return `<a href="${data}" target="_blank">${data}</a>`;
} else {
return '';
}
}
}, // Documentation
],
fixedHeader: true,
paging: false,
scrollCollapse: true,
scrollX: true,
scrollY: calculate_table_height() + 75,
info: false,
fixedColumns: {
left: 2,
},
ordering: false,
mark: true,

language: {
emptyTable: "No indicators match your specified filters. Try relaxing some filters, or clear all filters and try again.",
// buttons: {
// colvis: "Toggle Columns",
// },
},
search: {
smart: true,
highlight: true,
layout: {
topStart: function () {
let indicatorSetsInfo = document.createElement('span');
indicatorSetsInfo.className = 'table-stats-info';
indicatorSetsInfo.id = 'indicatorSetsInfo';
$.ajax({

url: "get_table_stats_info/" + window.location.search,
method: "GET",
success: function (response) {
if (response.num_of_locations > 0) {
indicatorSetsInfo.innerHTML =
`Showing <b>${response.num_of_indicators}</b> distinct ${pluralize(response.num_of_indicators, "indicator")} (arranged in <b>${response.num_of_indicator_sets}</b> ${pluralize(response.num_of_indicator_sets, "set")}), including <b>${numberWithCommas(response.num_of_locations)}</b> Delphi-hosted time series across numerous locations.`;
} else {
indicatorSetsInfo.innerHTML =
`Showing <b>${response.num_of_indicators}</b> indicator sets (arranged in <b>${response.num_of_indicator_sets}</b> ${pluralize(response.num_of_indicator_sets, "set")}).`;
}
}
});
return indicatorSetsInfo;
},
topEnd: null,
bottomStart: null,
bottomEnd: null
},
sDom: 'ltipr',
rowCallback: function(row, data, index) {
if (index % 2 === 0) {
createdRow: function (row, data, dataIndex) {
if (data.description) {
$(row).attr('data-description', data.description);
} else {
$(row).attr('data-description', '');
}
// Set row ID if present
if (data.DT_RowId) {
$(row).attr('data-id', data.DT_RowId);
}
// Add odd-row class for styling
if (dataIndex % 2 === 0) {
$(row).addClass('odd-row');
}
}
},
});

// new DataTable.Buttons(table, {
// buttons: [
// {
// extend: "colvis",
// columns: "th:nth-child(n+3)",
// prefixButtons: ["colvisRestore"],
// },
// ],
// });

// table.buttons(0, null).container().appendTo("#colvis");

// $("#tableSearch").keyup(function () {
// table.search(this.value).draw();
// });

function format(indicatorSetId, relatedIndicators, indicatorSetDescription) {
if (!relatedIndicators) {
return '<div class="d-flex justify-content-start my-3" style="padding-left: 20px;"><div class="spinner-border text-primary" role="status"><span class="visually-hidden">Loading...</span></div></div>';
}

var indicators = relatedIndicators.filter(
(indicator) => indicator.indicator_set === indicatorSetId
);
var indicators;
if (Array.isArray(relatedIndicators)) {
indicators = relatedIndicators.filter(
(indicator) => indicator.indicator_set === indicatorSetId
);
} else {
indicators = relatedIndicators[indicatorSetId] || [];
}
var disabled, restricted, sourceType;

if (indicators.length > 0) {
Expand Down
1 change: 0 additions & 1 deletion src/assets/js/selectedIndicatorsModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ async function checkFluviewGeoCoverage(geoValue) {
checkedIndicator["notCoveredGeos"] = [geoValue];
}
}
console.log(checkedIndicatorMembers);
return result["not_covered_indicators"];
} catch (error) {
console.error("Error fetching fluview geo coverage:", error);
Expand Down
2 changes: 1 addition & 1 deletion src/epiportal/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from sentry_sdk.integrations.django import DjangoIntegration
from sentry_sdk.integrations.redis import RedisIntegration

APP_VERSION = "1.0.23"
APP_VERSION = "1.1.0"
ALTERNATIVE_INTERFACE_VERSION = "1.0.10"


Expand Down
4 changes: 2 additions & 2 deletions src/epiportal/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@
f"{settings.MAIN_PAGE}/" if settings.MAIN_PAGE else "",
include("alternative_interface.urls"),
),
path("__debug__/", include("debug_toolbar.urls")),
path("__debug__/", include("debug_toolbar.urls")),
]


urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # type: ignore
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) # type: ignore
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) # type: ignore
2 changes: 1 addition & 1 deletion src/indicatorsets/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

class IndicatorSetFilter(django_filters.FilterSet):

indicators_qs = Indicator.objects.filter(indicator_set__isnull=False)
indicators_qs = Indicator.objects.filter(indicator_set__isnull=False).select_related("indicator_set", "source")

pathogens = django_filters.ModelMultipleChoiceFilter(
field_name="pathogens",
Expand Down
7 changes: 6 additions & 1 deletion src/indicatorsets/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
check_fluview_geo_coverage, create_query_code,
epivis, generate_export_data_url,
get_available_geos,
get_related_indicators_json, preview_data)
get_related_indicators_json, preview_data, get_table_stats_info)

urlpatterns: list[URLPattern] = [
path("", IndicatorSetListView.as_view(), name="indicatorsets"),
Expand All @@ -24,4 +24,9 @@
check_fluview_geo_coverage,
name="check_fluview_geo_coverage",
),
path(
"get_table_stats_info/",
get_table_stats_info,
name="get_table_stats_info",
),
]
28 changes: 17 additions & 11 deletions src/indicatorsets/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import requests
from django.conf import settings
from django.http import JsonResponse
from django.core.cache import cache
from epiweeks import Week
from delphi_utils import get_structured_logger

Expand Down Expand Up @@ -813,16 +814,21 @@ def log_form_data(request, data, form_mode):
def get_num_locations_from_meta(indicators):
timeseries_count = 0
indicators = set(
(indicator["source"], indicator["name"]) for indicator in indicators
(indicator["source__name"], indicator["name"]) for indicator in indicators
)
try:
metadata = requests.get(
f"{settings.EPIDATA_URL}covidcast_meta/", timeout=5
).json()["epidata"]
for r in metadata:
if (r["data_source"], r["signal"]) in indicators:
timeseries_count += r["num_locations"]
except Exception as e:
print(f"Error fetching covidcast metadata: {e}")
return 0

metadata = cache.get("covidcast_meta")
if not metadata:
try:
metadata = requests.get(
f"{settings.EPIDATA_URL}covidcast_meta/", timeout=5
).json()["epidata"]
cache.set("covidcast_meta", metadata, 60 * 60 * 24)
except Exception as e:
print(f"Error fetching covidcast metadata: {e}")
return 0

for r in metadata:
if (r["data_source"], r["signal"]) in indicators:
timeseries_count += r["num_locations"]
return timeseries_count
Loading
Loading