feat(dashboard): clarify the fleet status card and swap map locations to project monitoring location coords.
feat: Location no longer assigned directly to unit, locations and coords are assigned to location only, unit only is deployed or benched.
This commit is contained in:
+47
-35
@@ -129,6 +129,15 @@
|
||||
<span id="viewProjectNoLink" class="text-gray-900 dark:text-white font-medium">Not assigned</span>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm font-medium text-gray-500 dark:text-gray-400">Deployment Location</label>
|
||||
<p id="viewLocationContainer" class="mt-1">
|
||||
<a id="viewLocationLink" href="#" class="text-seismo-orange hover:text-orange-600 font-medium hover:underline hidden">
|
||||
<span id="viewLocationText">--</span>
|
||||
</a>
|
||||
<span id="viewLocationNoLink" class="text-gray-500 dark:text-gray-400 italic">Not deployed</span>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-sm font-medium text-gray-500 dark:text-gray-400">Address</label>
|
||||
<p id="viewAddress" class="mt-1 text-gray-900 dark:text-white font-medium">--</p>
|
||||
@@ -639,18 +648,12 @@
|
||||
{% include "partials/project_picker.html" with context %}
|
||||
</div>
|
||||
|
||||
<!-- Address -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Address</label>
|
||||
<input type="text" name="address" id="address" placeholder="123 Main St, City, State"
|
||||
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>
|
||||
|
||||
<!-- Coordinates -->
|
||||
<div class="md:col-span-2">
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">Coordinates</label>
|
||||
<input type="text" name="coordinates" id="coordinates" placeholder="34.0522,-118.2437"
|
||||
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 font-mono">
|
||||
<!-- Address / coordinates are managed on the project's
|
||||
MonitoringLocation, not the unit itself. Edit them on
|
||||
the project page. -->
|
||||
<div class="md:col-span-2 rounded-lg bg-gray-50 dark:bg-slate-700/50 border border-gray-200 dark:border-gray-700 p-3 text-sm text-gray-600 dark:text-gray-400">
|
||||
Address & coordinates are set on the deployment location.
|
||||
Open the project to edit them.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -848,16 +851,6 @@
|
||||
class="w-4 h-4 text-seismo-orange focus:ring-seismo-orange rounded">
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">Project</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input type="checkbox" name="cascade_location" id="detailCascadeLocation" value="true"
|
||||
class="w-4 h-4 text-seismo-orange focus:ring-seismo-orange rounded">
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">Address</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input type="checkbox" name="cascade_coordinates" id="detailCascadeCoordinates" value="true"
|
||||
class="w-4 h-4 text-seismo-orange focus:ring-seismo-orange rounded">
|
||||
<span class="text-sm text-gray-700 dark:text-gray-300">Coordinates</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-2 cursor-pointer">
|
||||
<input type="checkbox" name="cascade_note" id="detailCascadeNote" value="true"
|
||||
class="w-4 h-4 text-seismo-orange focus:ring-seismo-orange rounded">
|
||||
@@ -1168,8 +1161,28 @@ function populateViewMode() {
|
||||
if (projectLink) projectLink.classList.add('hidden');
|
||||
}
|
||||
|
||||
document.getElementById('viewAddress').textContent = currentUnit.address || '--';
|
||||
document.getElementById('viewCoordinates').textContent = currentUnit.coordinates || '--';
|
||||
// Deployment Location — comes from the active UnitAssignment →
|
||||
// MonitoringLocation. Show project link if present, otherwise
|
||||
// "Not deployed" placeholder.
|
||||
const locLink = document.getElementById('viewLocationLink');
|
||||
const locText = document.getElementById('viewLocationText');
|
||||
const locNoLink = document.getElementById('viewLocationNoLink');
|
||||
const activeLoc = currentUnit.active_location;
|
||||
if (activeLoc && activeLoc.location_id) {
|
||||
if (locText) locText.textContent = activeLoc.name || activeLoc.address || 'Active location';
|
||||
if (locLink) {
|
||||
locLink.href = `/projects/${activeLoc.project_id}`;
|
||||
locLink.classList.remove('hidden');
|
||||
}
|
||||
if (locNoLink) locNoLink.classList.add('hidden');
|
||||
} else {
|
||||
if (locLink) locLink.classList.add('hidden');
|
||||
if (locNoLink) locNoLink.classList.remove('hidden');
|
||||
}
|
||||
|
||||
// Address / coordinates also come from the active assignment.
|
||||
document.getElementById('viewAddress').textContent = (activeLoc && activeLoc.address) || '--';
|
||||
document.getElementById('viewCoordinates').textContent = (activeLoc && activeLoc.coordinates) || '--';
|
||||
|
||||
// Seismograph fields
|
||||
document.getElementById('viewLastCalibrated').textContent = currentUnit.last_calibrated || '--';
|
||||
@@ -1327,8 +1340,6 @@ function populateEditForm() {
|
||||
if (projectPickerClear) projectPickerClear.classList.add('hidden');
|
||||
}
|
||||
|
||||
document.getElementById('address').value = currentUnit.address || '';
|
||||
document.getElementById('coordinates').value = currentUnit.coordinates || '';
|
||||
document.getElementById('deployed').checked = currentUnit.deployed;
|
||||
document.getElementById('outForCalibration').checked = currentUnit.out_for_calibration || false;
|
||||
document.getElementById('retired').value = currentUnit.retired ? 'true' : '';
|
||||
@@ -1609,8 +1620,13 @@ function initUnitMap() {
|
||||
// Update marker (can be called multiple times)
|
||||
updateMapMarker(lat, lon);
|
||||
|
||||
// Update location text
|
||||
// Update location text — prefer the assignment's location name, fall
|
||||
// back to address, then coordinates.
|
||||
const locationParts = [];
|
||||
const loc = currentUnit.active_location;
|
||||
if (loc && loc.name) {
|
||||
locationParts.push(loc.name);
|
||||
}
|
||||
if (currentUnit.address) {
|
||||
locationParts.push(currentUnit.address);
|
||||
}
|
||||
@@ -1724,13 +1740,12 @@ async function uploadPhoto(file) {
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
// Show success message with metadata info
|
||||
// Show success message with metadata info. Location is on the
|
||||
// assignment's MonitoringLocation now, so we just surface what GPS
|
||||
// came in — the backend no longer mutates the unit row.
|
||||
let message = 'Photo uploaded successfully!';
|
||||
if (result.metadata && result.metadata.coordinates) {
|
||||
message += ` GPS location detected: ${result.metadata.coordinates}`;
|
||||
if (result.coordinates_updated) {
|
||||
message += ' (Unit coordinates updated automatically)';
|
||||
}
|
||||
} else {
|
||||
message += ' No GPS data found in photo.';
|
||||
}
|
||||
@@ -1738,11 +1753,8 @@ async function uploadPhoto(file) {
|
||||
statusDiv.className = 'mt-4 p-4 rounded-lg bg-green-100 dark:bg-green-900 text-green-800 dark:text-green-200';
|
||||
statusDiv.textContent = message;
|
||||
|
||||
// Reload photos and unit data
|
||||
// Reload photos
|
||||
await loadPhotos();
|
||||
if (result.coordinates_updated) {
|
||||
await loadUnitData();
|
||||
}
|
||||
|
||||
// Hide status after 5 seconds
|
||||
setTimeout(() => {
|
||||
|
||||
Reference in New Issue
Block a user