feat: add data collection mode to projects with UI updates and migration script

This commit is contained in:
2026-03-05 21:50:41 +00:00
parent ef8c046f31
commit 015ce0a254
6 changed files with 181 additions and 4 deletions

View File

@@ -40,12 +40,12 @@
class="tab-button px-4 py-3 border-b-2 border-transparent font-medium text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:border-gray-300 dark:hover:border-gray-600 transition-colors whitespace-nowrap">
<span id="locations-tab-label">Locations</span>
</button>
<button onclick="switchTab('units')"
<button id="units-tab-btn" onclick="switchTab('units')"
data-tab="units"
class="tab-button px-4 py-3 border-b-2 border-transparent font-medium text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:border-gray-300 dark:hover:border-gray-600 transition-colors whitespace-nowrap">
Assigned Units
</button>
<button onclick="switchTab('schedules')"
<button id="schedules-tab-btn" onclick="switchTab('schedules')"
data-tab="schedules"
class="tab-button px-4 py-3 border-b-2 border-transparent font-medium text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white hover:border-gray-300 dark:hover:border-gray-600 transition-colors whitespace-nowrap">
Schedules
@@ -324,6 +324,30 @@
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Data Collection</label>
<div class="grid grid-cols-2 gap-3">
<label class="flex items-start gap-3 p-3 border-2 rounded-lg cursor-pointer" id="settings-mode-manual-label">
<input type="radio" name="data_collection_mode" id="settings-mode-manual" value="manual"
onchange="settingsUpdateModeStyles()"
class="mt-0.5 accent-seismo-orange shrink-0">
<div>
<p class="text-sm font-medium text-gray-900 dark:text-white">Manual</p>
<p class="text-xs text-gray-500 dark:text-gray-400">SD card retrieved daily</p>
</div>
</label>
<label class="flex items-start gap-3 p-3 border-2 rounded-lg cursor-pointer" id="settings-mode-remote-label">
<input type="radio" name="data_collection_mode" id="settings-mode-remote" value="remote"
onchange="settingsUpdateModeStyles()"
class="mt-0.5 accent-seismo-orange shrink-0">
<div>
<p class="text-sm font-medium text-gray-900 dark:text-white">Remote</p>
<p class="text-xs text-gray-500 dark:text-gray-400">Modem, data pulled via FTP</p>
</div>
</label>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Site Address</label>
<input type="text" name="site_address" id="settings-site-address"
@@ -775,6 +799,12 @@ async function loadProjectDetails() {
document.getElementById('settings-start-date').value = formatDate(data.start_date);
document.getElementById('settings-end-date').value = formatDate(data.end_date);
// Update data collection mode radio
const mode = data.data_collection_mode || 'manual';
const modeRadio = document.getElementById('settings-mode-' + mode);
if (modeRadio) modeRadio.checked = true;
settingsUpdateModeStyles();
// Update tab labels and visibility based on project type
const isSoundProject = projectTypeId === 'sound_monitoring';
if (isSoundProject) {
@@ -782,9 +812,16 @@ async function loadProjectDetails() {
document.getElementById('locations-header').textContent = 'Noise Recording Locations';
document.getElementById('add-location-label').textContent = 'Add NRL';
}
// Monitoring Sessions and Data Files tabs are SLM-only
// Monitoring Sessions and Data Files tabs are sound-only
// Data Files also hides the FTP browser section for manual projects
const isRemote = mode === 'remote';
document.getElementById('sessions-tab-btn').classList.toggle('hidden', !isSoundProject);
document.getElementById('data-tab-btn').classList.toggle('hidden', !isSoundProject);
// Schedules and Assigned Units are remote-only (manual projects collect data by hand)
document.getElementById('schedules-tab-btn')?.classList.toggle('hidden', isSoundProject && !isRemote);
document.getElementById('units-tab-btn')?.classList.toggle('hidden', isSoundProject && !isRemote);
// FTP browser within Data Files tab
document.getElementById('ftp-browser')?.classList.toggle('hidden', !isRemote);
document.getElementById('settings-error').classList.add('hidden');
updateDangerZone();
@@ -800,6 +837,24 @@ function formatDate(value) {
return date.toISOString().slice(0, 10);
}
function settingsUpdateModeStyles() {
const manualChecked = document.getElementById('settings-mode-manual')?.checked;
const manualLabel = document.getElementById('settings-mode-manual-label');
const remoteLabel = document.getElementById('settings-mode-remote-label');
if (!manualLabel || !remoteLabel) return;
if (manualChecked) {
manualLabel.classList.add('border-seismo-orange', 'bg-orange-50', 'dark:bg-orange-900/20');
manualLabel.classList.remove('border-gray-300', 'dark:border-gray-600');
remoteLabel.classList.remove('border-seismo-orange', 'bg-orange-50', 'dark:bg-orange-900/20');
remoteLabel.classList.add('border-gray-300', 'dark:border-gray-600');
} else {
remoteLabel.classList.add('border-seismo-orange', 'bg-orange-50', 'dark:bg-orange-900/20');
remoteLabel.classList.remove('border-gray-300', 'dark:border-gray-600');
manualLabel.classList.remove('border-seismo-orange', 'bg-orange-50', 'dark:bg-orange-900/20');
manualLabel.classList.add('border-gray-300', 'dark:border-gray-600');
}
}
// Project settings form submission
document.getElementById('project-settings-form').addEventListener('submit', async function(e) {
e.preventDefault();
@@ -812,7 +867,8 @@ document.getElementById('project-settings-form').addEventListener('submit', asyn
site_address: document.getElementById('settings-site-address').value.trim() || null,
site_coordinates: document.getElementById('settings-site-coordinates').value.trim() || null,
start_date: document.getElementById('settings-start-date').value || null,
end_date: document.getElementById('settings-end-date').value || null
end_date: document.getElementById('settings-end-date').value || null,
data_collection_mode: document.querySelector('input[name="data_collection_mode"]:checked')?.value || 'manual'
};
try {