Change: user sets date of previous calibration, not upcoming expire dates.
- seismograph list page enhanced with better visabilty, filtering, sorting, and calibration dates color coded.
This commit is contained in:
@@ -144,12 +144,12 @@
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">Seismograph Information</h3>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label class="text-sm font-medium text-gray-500 dark:text-gray-400">Last Calibrated</label>
|
||||
<label class="text-sm font-medium text-gray-500 dark:text-gray-400">Date of Last Calibration</label>
|
||||
<p id="viewLastCalibrated" class="mt-1 text-gray-900 dark:text-white font-medium">--</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm font-medium text-gray-500 dark:text-gray-400">Next Calibration Due</label>
|
||||
<p id="viewNextCalibrationDue" class="mt-1 text-gray-900 dark:text-white font-medium">--</p>
|
||||
<p id="viewNextCalibrationDue" class="mt-1 text-gray-900 dark:text-white font-medium inline-flex items-center gap-2">--</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm font-medium text-gray-500 dark:text-gray-400">Deployed With Modem</label>
|
||||
@@ -378,15 +378,12 @@
|
||||
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Seismograph Information</h3>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Last Calibrated</label>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Date of Last Calibration</label>
|
||||
<input type="date" name="last_calibrated" id="lastCalibrated"
|
||||
class="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-seismo-orange">
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1">Next calibration due date will be calculated automatically</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Next Calibration Due</label>
|
||||
<input type="date" name="next_calibration_due" id="nextCalibrationDue"
|
||||
class="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-slate-700 text-gray-900 dark:text-white focus:ring-2 focus:ring-seismo-orange">
|
||||
</div>
|
||||
<input type="hidden" name="next_calibration_due" id="nextCalibrationDue">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Deployed With Modem</label>
|
||||
<div class="flex gap-2">
|
||||
@@ -589,6 +586,42 @@ let currentSnapshot = null;
|
||||
let unitMap = null;
|
||||
let mapMarker = null;
|
||||
|
||||
// Calibration interval in days (default 365, will be loaded from preferences)
|
||||
let calibrationIntervalDays = 365;
|
||||
|
||||
// Load calibration interval from preferences
|
||||
async function loadCalibrationInterval() {
|
||||
try {
|
||||
const response = await fetch('/api/settings/preferences');
|
||||
if (response.ok) {
|
||||
const prefs = await response.json();
|
||||
calibrationIntervalDays = prefs.calibration_interval_days || 365;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to load calibration interval:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate next calibration due date from last calibrated date
|
||||
function calculateNextCalibrationDue(lastCalibratedStr) {
|
||||
if (!lastCalibratedStr) return '';
|
||||
const lastCalibrated = new Date(lastCalibratedStr);
|
||||
const nextDue = new Date(lastCalibrated);
|
||||
nextDue.setDate(nextDue.getDate() + calibrationIntervalDays);
|
||||
return nextDue.toISOString().split('T')[0];
|
||||
}
|
||||
|
||||
// Setup auto-calculation for calibration fields
|
||||
function setupCalibrationAutoCalc() {
|
||||
const lastCal = document.getElementById('lastCalibrated');
|
||||
const nextCal = document.getElementById('nextCalibrationDue');
|
||||
if (lastCal && nextCal) {
|
||||
lastCal.addEventListener('change', function() {
|
||||
nextCal.value = calculateNextCalibrationDue(this.value);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch project display name (combines project_number, client_name, name)
|
||||
async function fetchProjectDisplay(projectId) {
|
||||
if (!projectId) return '';
|
||||
@@ -819,7 +852,28 @@ function populateViewMode() {
|
||||
|
||||
// Seismograph fields
|
||||
document.getElementById('viewLastCalibrated').textContent = currentUnit.last_calibrated || '--';
|
||||
document.getElementById('viewNextCalibrationDue').textContent = currentUnit.next_calibration_due || '--';
|
||||
|
||||
// Calculate next calibration due and show with status indicator
|
||||
const nextCalDueEl = document.getElementById('viewNextCalibrationDue');
|
||||
if (currentUnit.last_calibrated) {
|
||||
const nextDue = calculateNextCalibrationDue(currentUnit.last_calibrated);
|
||||
const today = new Date().toISOString().split('T')[0];
|
||||
const daysUntil = Math.floor((new Date(nextDue) - new Date(today)) / (1000 * 60 * 60 * 24));
|
||||
|
||||
let dotColor = 'bg-green-500';
|
||||
let tooltip = `Calibration valid (${daysUntil} days remaining)`;
|
||||
if (daysUntil < 0) {
|
||||
dotColor = 'bg-red-500';
|
||||
tooltip = `Calibration expired ${-daysUntil} days ago`;
|
||||
} else if (daysUntil <= 14) {
|
||||
dotColor = 'bg-yellow-500';
|
||||
tooltip = `Calibration expires in ${daysUntil} days`;
|
||||
}
|
||||
|
||||
nextCalDueEl.innerHTML = `<span class="w-2 h-2 rounded-full ${dotColor}" title="${tooltip}"></span>${nextDue}`;
|
||||
} else {
|
||||
nextCalDueEl.textContent = '--';
|
||||
}
|
||||
|
||||
// Deployed with modem - show as clickable link
|
||||
const modemLink = document.getElementById('viewDeployedWithModemLink');
|
||||
@@ -960,7 +1014,10 @@ function populateEditForm() {
|
||||
|
||||
// Seismograph fields
|
||||
document.getElementById('lastCalibrated').value = currentUnit.last_calibrated || '';
|
||||
document.getElementById('nextCalibrationDue').value = currentUnit.next_calibration_due || '';
|
||||
// Calculate next calibration due from last calibrated
|
||||
document.getElementById('nextCalibrationDue').value = currentUnit.last_calibrated
|
||||
? calculateNextCalibrationDue(currentUnit.last_calibrated)
|
||||
: '';
|
||||
|
||||
// Populate modem picker for seismograph (uses -detail-seismo suffix)
|
||||
const modemPickerValue = document.getElementById('modem-picker-value-detail-seismo');
|
||||
@@ -1535,6 +1592,8 @@ async function pingModem() {
|
||||
}
|
||||
|
||||
// Load data when page loads
|
||||
loadCalibrationInterval();
|
||||
setupCalibrationAutoCalc();
|
||||
loadUnitData().then(() => {
|
||||
loadPhotos();
|
||||
loadUnitHistory();
|
||||
|
||||
Reference in New Issue
Block a user