Skip to content

Development #138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Mar 28, 2025
73 changes: 49 additions & 24 deletions src/assets/js/signal_sets.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,32 @@ function showWarningAlert(warningMessage, slideUpTime = 2000) {
});
}

function checkGeoCoverage(geoType, geoValue) {
var notCoveredSignals = [];
$.ajax({
url: "epidata/covidcast/geo_coverage/",
type: 'GET',
async: false,
data: {
'geo': `${geoType}:${geoValue}`
},
success: function (result) {
checkedSignalMembers.forEach(signal => {
var covered = result["epidata"].some(
e => (e.source === signal.data_source && e.signal === signal.signal)
)
if (!covered) {
notCoveredSignals.push(signal);
}
})
}
})
return notCoveredSignals;
async function checkGeoCoverage(geoType, geoValue) {
const notCoveredSignals = [];

try {
const result = await $.ajax({
url: "epidata/covidcast/geo_coverage/",
type: 'GET',
data: {
'geo': `${geoType}:${geoValue}`
}
});

checkedSignalMembers.forEach(signal => {
const covered = result["epidata"].some(
e => (e.source === signal.data_source && e.signal === signal.signal)
);
if (!covered) {
notCoveredSignals.push(signal);
}
});

return notCoveredSignals;
} catch (error) {
console.error('Error fetching geo coverage:', error);
return notCoveredSignals;
}
}


Expand Down Expand Up @@ -123,6 +128,18 @@ function addSelectedSignal(element) {
}
}

$("#showSelectedSignalsButton").click(function() {
alertPlaceholder.innerHTML = "";
$('#geographic_value').select2("data").forEach(geo => {
checkGeoCoverage(geo.geoType, geo.id).then((notCoveredSignals) => {
if (notCoveredSignals.length > 0) {
showNotCoveredGeoWarningMessage(notCoveredSignals, geo.text);
}
})

});
});

// Add an event listener to each 'bulk-select' element
let bulkSelectDivs = document.querySelectorAll('.bulk-select');
bulkSelectDivs.forEach(div => {
Expand Down Expand Up @@ -439,15 +456,23 @@ function showNotCoveredGeoWarningMessage(notCoveredSignals, geoValue) {

$('#geographic_value').on('select2:select', function (e) {
var geo = e.params.data;
var notCoveredSignals = checkGeoCoverage(geo.geoType, geo.id)
if (notCoveredSignals.length > 0) {
showNotCoveredGeoWarningMessage(notCoveredSignals, geo.text);
checkGeoCoverage(geo.geoType, geo.id).then((notCoveredSignals) => {
if (notCoveredSignals.length > 0) {
showNotCoveredGeoWarningMessage(notCoveredSignals, geo.text);
}
}
);
});


function submitMode(event) {
event.preventDefault();
var geographicValues = $('#geographic_value').select2('data');

if (geographicValues.length === 0) {
appendAlert("Please select at least one geographic location", "warning")
return;
}

if (currentMode === 'epivis') {
plotData();
Expand Down
13 changes: 12 additions & 1 deletion src/datasources/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,21 @@ def process_links(row, dua_column_name="DUA", link_column_name="Link"):
links.append(link.id)
else:
for match in matches:
link, _ = Link.objects.get_or_create(url=match[1], defaults={'link_type': match[0], })
link, _ = Link.objects.get_or_create(
url=match[1],
defaults={
"link_type": match[0],
},
)
links.append(link.id)
row["Links"] = links


def process_datasource_name(row):
if row["Name"]:
row["Name"] = row["Name"].capitalize()


def process_datasources(row):
datasource, _ = DataSource.objects.get_or_create(
name=row["DB Source"],
Expand Down Expand Up @@ -67,5 +77,6 @@ class Meta:
skip_unchanged = True

def before_import_row(self, row, **kwargs):
process_datasource_name(row)
process_links(row)
process_datasources(row)
34 changes: 22 additions & 12 deletions src/fixtures/severity_pyramid_rungs.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@
"fields": {
"created": "2024-08-15T09:57:49.327Z",
"modified": "2024-08-15T13:07:46.136Z",
"name": "Population",
"display_name": "Population",
"used_in": "signal_sets"
"name": "Entire Population",
"display_name": "Entire Population",
"used_in": "signal_sets",
"display_order_number": 1
}
},
{
Expand All @@ -95,7 +96,8 @@
"modified": "2024-08-15T13:07:46.136Z",
"name": "Vaccinated",
"display_name": "Vaccinated",
"used_in": "signal_sets"
"used_in": "signal_sets",
"display_order_number": 2
}
},
{
Expand All @@ -106,7 +108,8 @@
"modified": "2024-08-15T13:07:46.136Z",
"name": "Infected",
"display_name": "Infected",
"used_in": "signal_sets"
"used_in": "signal_sets",
"display_order_number": 3
}
},
{
Expand All @@ -117,7 +120,8 @@
"modified": "2024-08-15T13:07:46.136Z",
"name": "Tested",
"display_name": "Tested",
"used_in": "signal_sets"
"used_in": "signal_sets",
"display_order_number": 4
}
},
{
Expand All @@ -128,7 +132,8 @@
"modified": "2024-08-15T13:07:46.136Z",
"name": "Ascertained (Case)",
"display_name": "Ascertained (Case)",
"used_in": "signal_sets"
"used_in": "signal_sets",
"display_order_number": 5
}
},
{
Expand All @@ -139,7 +144,8 @@
"modified": "2024-08-15T13:07:46.136Z",
"name": "Symptomatic",
"display_name": "Symptomatic",
"used_in": "signal_sets"
"used_in": "signal_sets",
"display_order_number": 6
}
},
{
Expand All @@ -150,7 +156,8 @@
"modified": "2024-08-15T13:07:46.136Z",
"name": "Outpatient / ED",
"display_name": "Outpatient / ED",
"used_in": "signal_sets"
"used_in": "signal_sets",
"display_order_number": 7
}
},
{
Expand All @@ -161,7 +168,8 @@
"modified": "2024-08-15T13:07:46.136Z",
"name": "Hospitalized",
"display_name": "Hospitalized",
"used_in": "signal_sets"
"used_in": "signal_sets",
"display_order_number": 8
}
},
{
Expand All @@ -172,7 +180,8 @@
"modified": "2024-08-15T13:07:46.136Z",
"name": "ICU",
"display_name": "ICU",
"used_in": "signal_sets"
"used_in": "signal_sets",
"display_order_number": 9
}
},
{
Expand All @@ -183,7 +192,8 @@
"modified": "2024-08-15T13:07:46.136Z",
"name": "Deceased",
"display_name": "Deceased",
"used_in": "signal_sets"
"used_in": "signal_sets",
"display_order_number": 10
}
}
]
2 changes: 1 addition & 1 deletion src/signal_sets/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class SignalSetFilterForm(forms.ModelForm):
queryset=SeverityPyramidRung.objects.filter(
# id__in=SignalSet.objects.values_list("severity_pyramid_rungs", flat="True")
used_in="signal_sets"
),
).order_by("display_order_number"),
widget=forms.CheckboxSelectMultiple(),
)

Expand Down
5 changes: 3 additions & 2 deletions src/signal_sets/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,10 @@ def skip_row(self, instance, original, row, import_validation_errors=None):
def after_import_row(self, row, row_result, **kwargs):
try:
signal_set_obj = SignalSet.objects.get(id=row_result.object_id)
signal_set_obj.pathogens.clear()
signal_set_obj.severity_pyramid_rungs.clear()
signal_set_obj.available_geographies.clear()
for pathogen in row["Pathogen(s)/Syndrome(s)"].split(","):
signal_set_obj.pathogens.clear()
pathogen = Pathogen.objects.get(name=pathogen, used_in="signal_sets")
signal_set_obj.pathogens.add(pathogen)
for severity_pyramid_rung in row["Surveillance Categories"].split(","):
Expand All @@ -231,7 +233,6 @@ def after_import_row(self, row, row_result, **kwargs):
used_in="signal_sets"
).first()
signal_set_obj.severity_pyramid_rungs.add(severity_pyramid_rung)

for available_geography in row["Geographic Granularity - Delphi"].split(","):
available_geography = Geography.objects.get(name=available_geography, used_in="signal_sets")
signal_set_obj.available_geographies.add(available_geography)
Expand Down
33 changes: 32 additions & 1 deletion src/signals/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from django.contrib import admin
from import_export.admin import ImportExportModelAdmin

from signals.resources import SignalResource, SignalBaseResource
from signals.resources import SignalResource, SignalBaseResource, OtherEndpointSignalResource


from signals.models import (
Expand All @@ -14,6 +14,7 @@
Pathogen,
SeverityPyramidRung,
Signal,
OtherEndointSignal,
SignalType,
SignalGeography,
GeographyUnit,
Expand Down Expand Up @@ -102,6 +103,7 @@ class SeverityPyramidRungAdmin(admin.ModelAdmin):
"name",
"display_name",
"used_in",
"display_order_number",
)
exclude = ("id",)
search_fields: tuple[Literal["name"]] = ("name",)
Expand Down Expand Up @@ -149,6 +151,35 @@ class SignalAdmin(ImportExportModelAdmin):
resource_classes: list[type[SignalResource]] = [SignalResource, SignalBaseResource]


@admin.register(OtherEndointSignal)
class OtherEndpointsSignalAdmin(ImportExportModelAdmin):
"""
Admin interface for managing signal objects.
"""

list_display: tuple[
Literal["name"],
Literal["signal_type"],
Literal["format_type"],
Literal["category"],
Literal["geographic_scope"],
] = ("name", "signal_type", "format_type", "category", "geographic_scope")
search_fields: tuple[
Literal["name"],
Literal["signal_type__name"],
Literal["format_type__name"],
Literal["category__name"],
Literal["geographic_scope__name"],
] = (
"name",
"signal_type__name",
"format_type__name",
"category__name",
"geographic_scope__name",
)
resource_classes: list[type[SignalResource]] = [OtherEndpointSignalResource]


@admin.register(SignalGeography)
class SignalGeographyAdmin(admin.ModelAdmin):
"""
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.7 on 2025-03-12 17:52

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('signals', '0016_signal_source_view'),
]

operations = [
migrations.AddField(
model_name='severitypyramidrung',
name='display_order_number',
field=models.IntegerField(help_text='Display order number of the severity pyramid rung.', null=True, verbose_name='display order number'),
),
]
26 changes: 26 additions & 0 deletions src/signals/migrations/0018_otherendointsignal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 5.0.7 on 2025-03-27 18:21

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('signals', '0017_severitypyramidrung_display_order_number'),
]

operations = [
migrations.CreateModel(
name='OtherEndointSignal',
fields=[
],
options={
'verbose_name': 'Other Endpoint Signal',
'verbose_name_plural': 'Other Endpoint Signals',
'proxy': True,
'indexes': [],
'constraints': [],
},
bases=('signals.signal',),
),
]
13 changes: 13 additions & 0 deletions src/signals/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ class SeverityPyramidRung(TimeStampedModel):
default="signals",
)

display_order_number: models.IntegerField = models.IntegerField(
verbose_name=_("display order number"),
help_text=_("Display order number of the severity pyramid rung."),
null=True,
)

class Meta:
verbose_name_plural: str = "Severity Pyramid Rungs"
unique_together: list[str] = ["name", "used_in"]
Expand Down Expand Up @@ -569,6 +575,13 @@ def get_display_name(self):
return self.name


class OtherEndointSignal(Signal):
class Meta:
proxy = True
verbose_name = "Other Endpoint Signal"
verbose_name_plural = "Other Endpoint Signals"


class SignalsDbView(models.Model):
id = models.BigIntegerField(primary_key=True)
name = models.CharField(max_length=255)
Expand Down
Loading
Loading