feat: timeline refactor, docking UI, location/state dropdowns, sim_time cleanup
Templates: - mission_timeline_preview: client-side rendering with lane stacking, wheel zoom, drag pan, percentage-based layout, event dedup, scale labels - asset_detail: dock/undock modals with time selection, future event warning, Mission Label column replacing Location/State - asset_entry_form: all_locations expanded to 72 items (draft board hierarchy), all_states dynamic from DB, event point dropdown uses same list - Remove sim_time from all template url_for links - base.html: remove Today button JS: - app.js: sim_time controls use POST /api/v1/sim-time API instead of URL param Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
// ─── Sidebar ───
|
||||
function initSidebar() {
|
||||
document.querySelectorAll('.ni[data-pg]').forEach(el => {
|
||||
el.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
window.location.href = this.getAttribute('href');
|
||||
});
|
||||
});
|
||||
document.querySelectorAll('.nst').forEach(el => {
|
||||
el.addEventListener('click', function() { this.classList.toggle('on'); });
|
||||
});
|
||||
}
|
||||
initSidebar();
|
||||
|
||||
// ─── Global Time Control ───
|
||||
function openTimeModal() {
|
||||
const display = document.getElementById('sim-time-display');
|
||||
if (!display) return;
|
||||
const modal = document.getElementById('time-modal');
|
||||
const input = document.getElementById('time-input');
|
||||
if (modal && input) {
|
||||
input.value = display.textContent.trim().replace(' ', 'T');
|
||||
modal.classList.add('open');
|
||||
}
|
||||
}
|
||||
function closeTimeModal() {
|
||||
const modal = document.getElementById('time-modal');
|
||||
if (modal) modal.classList.remove('open');
|
||||
}
|
||||
async function applyTime() {
|
||||
const input = document.getElementById('time-input');
|
||||
if (!input || !input.value) return;
|
||||
await setSimTimeAndReload(input.value.replace('T', ' ') + ':00');
|
||||
}
|
||||
async function shiftTime(days) {
|
||||
const display = document.getElementById('sim-time-display');
|
||||
if (!display) return;
|
||||
const d = new Date(display.textContent.trim().replace(' ', 'T') + 'Z');
|
||||
d.setUTCDate(d.getUTCDate() + days);
|
||||
await setSimTimeAndReload(d.toISOString().slice(0, 10) + ' 09:00');
|
||||
}
|
||||
async function resetTime() {
|
||||
await setSimTimeAndReload('2060-03-12 09:00');
|
||||
}
|
||||
async function setSimTimeAndReload(timeStr) {
|
||||
try {
|
||||
await fetch('/api/v1/sim-time', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({sim_time: timeStr})
|
||||
});
|
||||
} catch(e) {}
|
||||
location.reload();
|
||||
}
|
||||
Reference in New Issue
Block a user