Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8e74445
Automated column description refresh
Dec 22, 2025
da200d8
Automated filter description refresh
Dec 22, 2025
6861563
Merge pull request #272 from cmu-delphi/development
dmytrotsko Dec 22, 2025
a56d2f8
'Temporal granularity' filter fix
Dec 22, 2025
a3d705b
Merge pull request #273 from cmu-delphi/development
dmytrotsko Dec 22, 2025
f7ef0c8
ADded express view indicators import, fixed chart, added field to tra…
Dec 23, 2025
4917aed
Merge pull request #274 from cmu-delphi/development
dmytrotsko Dec 23, 2025
7e09534
Changed indicator sets table header
Dec 23, 2025
d000207
Merge pull request #275 from cmu-delphi/development
dmytrotsko Dec 23, 2025
8db15dc
Added caching
Dec 29, 2025
8c15f67
Merge pull request #276 from cmu-delphi/development
dmytrotsko Dec 29, 2025
9e64f47
Removed caching, made table stats async
Dec 29, 2025
fa0a1bb
Merge pull request #277 from cmu-delphi/development
dmytrotsko Dec 29, 2025
4e7539a
Optimized filters
Dec 29, 2025
7d31d19
ADded loader when indicators are loading
Dec 29, 2025
ba87d28
Merge pull request #278 from cmu-delphi/development
dmytrotsko Dec 29, 2025
f65dd0f
Debounce filters
Dec 30, 2025
1a97f3d
Merge pull request #279 from cmu-delphi/development
dmytrotsko Dec 30, 2025
b3bad24
Fixed preserve selected indicators after applying filters
Dec 30, 2025
54642db
Minimize bouncing effect of filters section after location_search loads
Dec 30, 2025
5be5e29
Merge pull request #280 from cmu-delphi/development
dmytrotsko Dec 30, 2025
5297545
Version bump
Dec 30, 2025
8396cbf
Merge pull request #281 from cmu-delphi/development
dmytrotsko Dec 30, 2025
ab00e0d
Added warning message if fluview/fluview_clinical indicator(s) is/are…
Dec 31, 2025
e620987
Merge pull request #282 from cmu-delphi/development
dmytrotsko Dec 31, 2025
8fd79c2
Fluview indicators will not be plotted if there is no data for select…
Jan 2, 2026
e6a4ca3
Merge pull request #283 from cmu-delphi/development
dmytrotsko Jan 2, 2026
fdc2911
Changed some text in alternative interface
Jan 5, 2026
ea911e4
Merge pull request #285 from cmu-delphi/development
dmytrotsko Jan 5, 2026
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
36 changes: 35 additions & 1 deletion src/alternative_interface/admin.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from django.conf import settings
from django.contrib import admin

from django.urls import path
from import_export.admin import ImportExportModelAdmin

from alternative_interface.models import ExpressViewIndicator
from alternative_interface.resources import ExpressViewIndicatorResource
from base.utils import download_source_file, import_data


@admin.register(ExpressViewIndicator)
Expand All @@ -13,3 +15,35 @@ class ExpressViewIndicatorAdmin(ImportExportModelAdmin):
search_fields = ["menu_item", "indicator", "display_name"]
list_filter = ["menu_item", "indicator"]
ordering = ["menu_item", "indicator"]

change_list_template = "admin/alternative_interface/express_view_indicators_changelist.html"

def get_urls(self):
urls = super().get_urls()
custom_urls = [
path(
"import-from-spreadsheet",
self.admin_site.admin_view(self.import_from_spreadsheet),
name="import_express_view_indicators",
),
path(
"download-source-file",
self.admin_site.admin_view(self.download_express_view_indicators),
name="download_express_view_indicators",
),
]
return custom_urls + urls

def import_from_spreadsheet(self, request):
return import_data(
self,
request,
ExpressViewIndicatorResource,
settings.SPREADSHEET_URLS["express_view_indicators"],
)

def download_express_view_indicators(self, request):
return download_source_file(
settings.SPREADSHEET_URLS["express_view_indicators"],
"Express_View_Indicators.csv",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 5.2.5 on 2025-12-23 14:21

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("alternative_interface", "0003_expressviewindicator_grouping_key"),
]

operations = [
migrations.AddField(
model_name="expressviewindicator",
name="display_order",
field=models.IntegerField(
default=0,
help_text="Order to display the indicator in the legend",
verbose_name="Display Order",
),
),
]
6 changes: 6 additions & 0 deletions src/alternative_interface/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ class ExpressViewIndicator(models.Model):
help_text="Key to group indicators for scaling",
)

display_order: models.IntegerField = models.IntegerField(
verbose_name="Display Order",
default=0,
help_text="Order to display the indicator in the legend",
)

class Meta:
verbose_name = "Express View Indicator"
verbose_name_plural = "Express View Indicators"
Expand Down
5 changes: 5 additions & 0 deletions src/alternative_interface/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class ExpressViewIndicatorResource(resources.ModelResource):
grouping_key = Field(
attribute="grouping_key", column_name="tie together for scaling"
)
display_order = Field(
attribute="display_order", column_name="Display Order"
)

def before_import_row(self, row, **kwargs):
process_indicator(row)
Expand All @@ -50,6 +53,8 @@ class Meta:
"menu_item",
"indicator",
"display_name",
"grouping_key",
"display_order",
)
import_id_fields = ("menu_item", "indicator")
skip_unchanged = True
Expand Down
1 change: 1 addition & 0 deletions src/alternative_interface/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def _get_indicators_queryset(pathogen_filter):
return (
ExpressViewIndicator.objects.filter(menu_item=pathogen_filter)
.select_related("indicator__indicator_set", "indicator__source")
.order_by("display_order")
)


Expand Down
2 changes: 1 addition & 1 deletion src/assets/css/alter_dashboard.css
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ body {
.hero-section {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-dark) 100%);
color: white;
padding: 4rem 0;
padding: 2rem 0;
margin-bottom: 3rem;
position: relative;
overflow: hidden;
Expand Down
4 changes: 4 additions & 0 deletions src/assets/css/custom_styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,7 @@ tr:not(.odd-row) > .dtfc-fixed-end {
display: block;
}
}

#location_search {
height: 38px !important;
}
57 changes: 44 additions & 13 deletions src/assets/js/alter_dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,44 @@ class AlterDashboard {
button.appendChild(text);
list.appendChild(button);
});

// Add "Show All" button as part of the list
const showAllButton = document.createElement('button');
showAllButton.type = 'button';
Object.assign(showAllButton.style, {
display: 'inline-flex',
alignItems: 'center',
gap: '6px',
border: '1px solid #cbd5e1',
borderRadius: '12px',
padding: '4px 8px',
background: '#f1f5f9',
cursor: 'pointer',
fontSize: '11px',
lineHeight: '1.2',
maxWidth: '100%',
color: '#334155',
fontWeight: '500'
});
showAllButton.title = "Show all indicators";

const icon = document.createElement('span');
icon.textContent = '👁️';
icon.style.fontSize = '10px';

const showAllText = document.createElement('span');
showAllText.textContent = 'Show All';

showAllButton.onclick = () => {
if (dashboard) {
dashboard.showAllDatasets();
}
};

showAllButton.appendChild(icon);
showAllButton.appendChild(showAllText);
list.appendChild(showAllButton);

container.appendChild(list);
}
};
Expand Down Expand Up @@ -927,36 +965,29 @@ class AlterDashboard {
let controlsContainer = document.getElementById('chartControls');
if (!controlsContainer) {
const chartSection = document.querySelector('.chart-section');
const cardHeader = chartSection?.querySelector('.card-header');
if (cardHeader) {
const wrapper = chartSection?.querySelector('.chart-container-wrapper');
if (wrapper) {
const controls = document.createElement('div');
controls.id = 'chartControls';
controls.className = 'chart-controls';
controls.style.padding = '0 1.5rem 1rem 1.5rem'; // Match wrapper padding
controls.style.borderTop = 'none'; // Remove top border if present
controls.innerHTML = `
<div class="controls-group" style="display: flex; align-items: center; gap: 15px;">
<div class="form-check form-switch" style="margin: 0; padding-left: 2.5em;">
<div class="form-check form-switch" style="margin: 0;">
<input class="form-check-input" type="checkbox" id="autoScaleToggle" checked style="cursor: pointer;">
<label class="form-check-label" for="autoScaleToggle" style="cursor: pointer; margin-left: 0.5em;">Auto-scale</label>
</div>
<button id="showAllBtn" class="btn-control" title="Show all indicators">
<span class="control-icon">👁️</span>
<span class="control-text">Show All</span>
</button>
</div>
`;
cardHeader.appendChild(controls);
wrapper.after(controls);
}
}

const autoScaleToggle = document.getElementById('autoScaleToggle');
if (autoScaleToggle) {
autoScaleToggle.addEventListener('change', () => this.handleAutoScaleChange());
}

const showAllBtn = document.getElementById('showAllBtn');
if (showAllBtn) {
showAllBtn.addEventListener('click', () => this.showAllDatasets());
}
}

handleAutoScaleChange(skipUpdate = false) {
Expand Down
1 change: 0 additions & 1 deletion src/assets/js/indicatorHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,6 @@ class IndicatorHandler {
data: JSON.stringify(submitData),
}).done((data) => {
const payload = this.prepareDataLayerPayload("epivis");
console.log(payload);
dataLayerPush(payload);
window.open(data["epivis_url"], '_blank').focus();
});
Expand Down
54 changes: 42 additions & 12 deletions src/assets/js/indicatorSetsFilters.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,31 @@ if (document.readyState === 'loading') {
initializeGroupSublistVisibility();
}

// Debounce function to delay execution
function debounce(func, wait) {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args);
}, wait);
};
}

// Function to handle form submission with UI feedback
function submitFilterForm(form) {
persistCheckedIndicators();
showLoader();
form.submit();
}

// Create debounced submission function
const debouncedSubmit = debounce(function(form) {
submitFilterForm(form);
}, 2000);

// Handle group checkbox clicks (e.g., "U.S. States")
document.addEventListener('change', function(event) {
if (event.target.classList.contains('original-data-provider-group-checkbox')) {
Expand Down Expand Up @@ -205,11 +230,9 @@ document.addEventListener('change', function(event) {
}
}

// Trigger form submission once after all checkboxes are updated
// Trigger debounced form submission
if (event.target.form) {
persistCheckedIndicators();
showLoader();
event.target.form.submit();
debouncedSubmit(event.target.form);
}
}
});
Expand Down Expand Up @@ -264,18 +287,25 @@ function showLoader() {
}

$("#filterIndicatorSetsForm").find("input[type='checkbox']").on("change", function (e) {
// Show loader and fade table
persistCheckedIndicators();
showLoader();
this.form.submit();
// Skip if it's a group checkbox (handled by separate event listener)
if (this.classList.contains('original-data-provider-group-checkbox')) {
return;
}

// Trigger debounced submission
debouncedSubmit(this.form);
});

$("#location_search").on({
"change": function (e) {
// Show loader and fade table
persistCheckedIndicators();
showLoader();
this.form.submit();
// Trigger debounced submission
debouncedSubmit(this.form);
},
// Also debounce on keyup for better UX if needed, or just keep change
"keyup": function(e) {
if (e.key === 'Enter') {
debouncedSubmit(this.form);
}
}
});

Expand Down
4 changes: 4 additions & 0 deletions src/assets/js/indicatorSetsTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ var table = new DataTable("#indicatorSetsTable", {
// });

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
);
Expand Down
Loading
Loading