Skip to content

Commit f1352a2

Browse files
authored
Merge pull request #50 from cmu-delphi/staging
Prep for production deployment
2 parents 6bd761e + c7b1019 commit f1352a2

36 files changed

+1557
-286
lines changed

src/assets/css/style.css

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1349,6 +1349,10 @@ h6 {
13491349
padding-left: 0px!important;
13501350
}
13511351

1352+
.select2-dropdown {
1353+
z-index: 9999!important;
1354+
}
1355+
13521356
.popover {
13531357
max-width: 50%;
13541358
}
@@ -1367,4 +1371,18 @@ h6 {
13671371

13681372
.tableformat td:nth-child(1){
13691373
width: 10rem;
1370-
}
1374+
}
1375+
1376+
1377+
.float{
1378+
position:fixed;
1379+
width:150px;
1380+
height:60px;
1381+
bottom:40px;
1382+
right:40px;
1383+
text-align:center;
1384+
}
1385+
1386+
.form-check > label.form-check-label {
1387+
display: block!important; /* Ensure the label takes up the full width */
1388+
}

src/assets/js/select_signals.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Function to update the modal content
2+
function updateSelectedSignalsModal() {
3+
var selectedSignals = localStorage.getItem('selectedSignals');
4+
var signals = selectedSignals ? JSON.parse(selectedSignals) : {};
5+
6+
var selectedSignalsList = document.getElementById('selectedSignalsList');
7+
selectedSignalsList.innerHTML = ''; // Clear existing items
8+
9+
10+
for (const signal in signals) {
11+
let data = JSON.parse(localStorage.getItem("selectedSignals"))[signal];
12+
console.log(data);
13+
var tr = document.createElement('tr');
14+
var memberName = document.createElement('td');
15+
memberName.textContent = data['info']['memberName'];
16+
tr.appendChild(memberName);
17+
var memberDescription = document.createElement('td');
18+
memberDescription.textContent = data['info']['memberDescription'];
19+
tr.appendChild(memberDescription);
20+
var dataSource = document.createElement('td');
21+
dataSource.textContent = data['epivis']['params']['data_source'];
22+
tr.appendChild(dataSource);
23+
var signalName = document.createElement('td');
24+
signalName.textContent = data['epivis']['params']['signal'];
25+
tr.appendChild(signalName);
26+
var timeType = document.createElement('td');
27+
timeType.textContent = data['epivis']['params']['time_type'];
28+
tr.appendChild(timeType);
29+
var geoType = document.createElement('td');
30+
geoType.textContent = data['epivis']['params']['geo_type'];
31+
tr.appendChild(geoType);
32+
var geoValue = document.createElement('td');
33+
geoValue.textContent = data['epivis']['params']['geo_value'];
34+
tr.appendChild(geoValue);
35+
selectedSignalsList.appendChild(tr);
36+
}
37+
}
38+
39+
function addSelectedSignals(dataSource, timeType, signalSetEndpoint) {
40+
let selectedSignals = localStorage.getItem("selectedSignals");
41+
selectedSignals = selectedSignals ? JSON.parse(selectedSignals) : {};
42+
var dataSignals = Array.from(document.getElementsByName('selectedSignal'), (signal) => (signal.checked) ? signal : null).filter((el) => el !== null);
43+
var geographicType = document.getElementById('geographic_type').value;
44+
// geographicValue is a comma separated string of geographic values. type can be string or integer
45+
// in case of string, it should be converted to lowercase
46+
// else it will be treated as integer
47+
var geographicValue = $('#geographic_value').select2('data').map((el) => (typeof el.id === 'string') ? el.id.toLowerCase() : el.id).join(',');
48+
49+
if (geographicType === 'Choose...' || geographicValue === '') {
50+
showWarningAlert("Geographic Type or Geographic Value is not selected.");
51+
return;
52+
}
53+
54+
var geographicValues = geographicValue.split(',');
55+
dataSignals.forEach((signal) => {
56+
geographicValues.forEach((geographicValue) => {
57+
selectedSignals[`${signal.value}_${geographicValue}`] = {
58+
info: {
59+
memberName: signal.getAttribute('data-member-name'),
60+
memberDescription: signal.getAttribute('data-member-description'),
61+
},
62+
epivis: {
63+
color: '#' + (Math.random() * 0xFFFFFF << 0).toString(16).padStart(6, '0'),
64+
title: "value",
65+
params: {
66+
_endpoint: signalSetEndpoint,
67+
data_source: dataSource,
68+
signal: signal.value,
69+
time_type: timeType,
70+
geo_type: geographicType,
71+
geo_value: geographicValue
72+
}
73+
}
74+
};
75+
});
76+
});
77+
localStorage.setItem("selectedSignals", JSON.stringify(selectedSignals));
78+
updateSelectedSignalsModal();
79+
$("#showSelectedSignalsButton").show();
80+
}
81+
82+
83+
84+
document.addEventListener('DOMContentLoaded', function() {
85+
// Call the function to update the modal content when the page loads
86+
updateSelectedSignalsModal();
87+
88+
});
89+
90+
91+
92+
//for (const signal in JSON.parse(localStorage.getItem("selectedSignals"))) {console.log(JSON.parse(localStorage.getItem("selectedSignals"))[signal])}

src/rest_api/__init__.py

Whitespace-only changes.

src/rest_api/admin.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.contrib import admin
2+
3+
# Register your models here.

src/rest_api/apps.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from django.apps import AppConfig
2+
3+
4+
class RestApiConfig(AppConfig):
5+
default_auto_field = 'django.db.models.BigAutoField'
6+
name = 'rest_api'

src/rest_api/migrations/__init__.py

Whitespace-only changes.

src/rest_api/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from django.db import models
2+
3+
# Create your models here.

src/rest_api/serializers.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from rest_framework.serializers import ModelSerializer, SlugRelatedField
2+
3+
from signals.models import Signal, Geography
4+
5+
6+
class SignalSerializer(ModelSerializer):
7+
"""
8+
Serializer for the Signal model.
9+
"""
10+
11+
source = SlugRelatedField(read_only=True, slug_field="name")
12+
signal_type = SlugRelatedField(read_only=True, slug_field="name")
13+
available_geography = SlugRelatedField(many=True, read_only=True, slug_field="name")
14+
15+
class Meta:
16+
model = Signal
17+
fields = ["name", "source", "signal_type", "available_geography", "time_type"]
18+
19+
20+
class AvailableGeographySerializer(ModelSerializer):
21+
"""
22+
Serializer for the AvailableGeography model.
23+
"""
24+
25+
class Meta:
26+
model = Geography
27+
fields = ["name", "display_name"]

src/rest_api/urls.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from django.urls import path
2+
from django.urls.resolvers import URLPattern
3+
4+
from rest_api.views import api_signal_detail_view, api_available_geography_view
5+
6+
7+
urlpatterns: list[URLPattern] = [
8+
path("rest_api/signal/<int:pk>", api_signal_detail_view, name="api_signal_detail"),
9+
path("rest_api/signal/", api_signal_detail_view, name="api_signal_detail"),
10+
path("rest_api/geo_level/<int:pk>", api_available_geography_view, name="api_available_geography_detail"),
11+
path("rest_api/geo_level/", api_available_geography_view, name="api_available_geography_detail")
12+
]

src/rest_api/views.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
from rest_framework.decorators import api_view
2+
from rest_framework.response import Response
3+
4+
from rest_api.serializers import SignalSerializer, AvailableGeographySerializer
5+
from signals.models import Signal, Geography
6+
7+
8+
@api_view(
9+
[
10+
"GET",
11+
]
12+
)
13+
def api_signal_detail_view(request, pk):
14+
"""
15+
API view for getting a single Signal object.
16+
17+
Args:
18+
request: The request object.
19+
pk: The primary key of the Signal object.
20+
21+
Returns:
22+
Response: The response object.
23+
"""
24+
25+
try:
26+
signal = Signal.objects.get(pk=pk)
27+
except Signal.DoesNotExist:
28+
return Response(status=404)
29+
30+
if request.method == "GET":
31+
serializer = SignalSerializer(signal)
32+
return Response(serializer.data)
33+
34+
35+
@api_view(
36+
[
37+
"GET",
38+
]
39+
)
40+
def api_available_geography_view(request, pk):
41+
"""
42+
API view for getting a single Geography.
43+
44+
Args:
45+
request: The request object.
46+
pk: The primary key of the Geography object.
47+
48+
Returns:
49+
Response: The response object.
50+
"""
51+
52+
try:
53+
geography = Geography.objects.get(pk=pk)
54+
except Geography.DoesNotExist:
55+
return Response(status=404)
56+
57+
if request.method == "GET":
58+
serializer = AvailableGeographySerializer(geography)
59+
return Response(serializer.data)

0 commit comments

Comments
 (0)