Files
ArmorandClaude Opus 4.7 ac5141fd02 feat: docking log management, sim_time DB-only, modal helpers
- Add docking_log_list and docking_log_delete routes with dedicated page
- _append_docking_log: detect existing state interval before creating new entry
- _append_undocking_log: find entry by node title+at_time, accept docked_at param
- Fix _entry_state_label and _entry_location to return time-correct values
- Add api_set_sim_time POST endpoint; remove sim_time from all url_for() calls
- _resolve_simulation_time simplified to DB-only (no URL param)
- app.js: add openModal/closeModal/toggleTheme helpers
- base.html: add 对接日志管理 nav item, remove Today button

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 16:19:32 +08:00

129 lines
5.7 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="zh-CN" data-theme="dark">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ title }} · {{ config["PROJECT_TITLE"] }}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
<script>
// Inline theme init to prevent FOUC
(() => {
const k = 'ksp-theme', c = 'ksp_theme';
const saved = (() => { try { return localStorage.getItem(k); } catch(e) { return null; } })()
|| (document.cookie.match(/(?:^|; )ksp_theme=(dark|light)(?:;|$)/) || [])[1];
const theme = saved || 'dark';
document.documentElement.dataset.theme = theme;
document.documentElement.style.colorScheme = theme;
})();
</script>
</head>
<body>
<!-- ═══ TOPBAR ═══ -->
<div id="topbar">
<div class="brand"><b>KSP</b>&nbsp;管理后台</div>
<div class="tb-sp"></div>
<div class="tb-time">
<span class="l">Sim Time</span>
<span class="td" id="sim-time-display" onclick="openTimeModal()">{{ simulation_time_display or '2060-03-12 09:00' }}</span>
<button class="b" onclick="shiftTime(-1)">1d</button>
<button class="b" onclick="shiftTime(1)">+1d</button>
<button class="b" onclick="shiftTime(7)">+7d</button>
</div>
<button class="b" onclick="toggleTheme()" title="Toggle theme" style="margin-left:4px"></button>
</div>
<div id="layout">
<!-- ═══ SIDEBAR ═══ -->
<nav id="sidebar">
<a class="ni{% if active_page == 'overview' %} act{% endif %}" href="{{ url_for('web.dashboard') }}">
<span class="ic"></span>任务总览
</a>
<div class="nst" onclick="this.classList.toggle('on')">
<span class="ar"></span>任务运营
</div>
<div class="niw">
<a class="ni su{% if active_page == 'assets' %} act{% endif %}" href="{{ url_for('web.asset_list') }}">
<span class="ic"></span>任务资产
</a>
<a class="ni su{% if active_page == 'missions' %} act{% endif %}" href="{{ url_for('web.mission_list') }}">
<span class="ic"></span>任务列表
</a>
<a class="ni su{% if active_page == 'timeline' %} act{% endif %}" href="{{ url_for('web.mission_timeline_preview') }}">
<span class="ic"></span>时间线
</a>
<a class="ni su{% if active_page == 'location' %} act{% endif %}" href="{{ url_for('web.mission_location_board_preview') }}">
<span class="ic"></span>地点板
</a>
</div>
<div class="nst" onclick="this.classList.toggle('on')">
<span class="ar"></span>数据中心
</div>
<div class="niw">
<a class="ni su{% if active_page == 'engines' %} act{% endif %}" href="{{ url_for('web.engine_list') }}">
<span class="ic"></span>引擎目录
</a>
<a class="ni su{% if active_page == 'comms' %} act{% endif %}" href="{{ url_for('web.communication_list') }}">
<span class="ic"></span>通信部件
</a>
<a class="ni su{% if active_page == 'tanks' %} act{% endif %}" href="{{ url_for('web.tank_list') }}">
<span class="ic"></span>燃料箱规格
</a>
<a class="ni su{% if active_page == 'vehicles' %} act{% endif %}" href="{{ url_for('web.vehicle_list') }}">
<span class="ic"></span>载具成本
</a>
</div>
<a class="ni{% if active_page == 'converter' %} act{% endif %}" href="{{ url_for('web.fuel_converter') }}">
<span class="ic"></span>燃料换算
</a>
<div class="nst" onclick="this.classList.toggle('on')">
<span class="ar"></span>控制台
</div>
<div class="niw">
<a class="ni su{% if active_page == 'docking_logs' %} act{% endif %}" href="{{ url_for('web.docking_log_list') }}">
<span class="ic"></span>对接日志管理
</a>
</div>
<a class="ni" href="{{ url_for('api.health') }}">
<span class="ic">📡</span>API 健康检查
</a>
</nav>
<!-- ═══ CONTENT ═══ -->
<main id="content">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class="flash-stack">
{% for category, message in messages %}
<div class="flash-message {{ category }}">{{ message }}</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</main>
</div>
<!-- ═══ TIME MODAL ═══ -->
<div class="modal-bg" id="time-modal">
<div class="modal">
<h2>Set Simulation Time</h2>
<div class="fg">
<label>Time<input type="datetime-local" id="time-input" step="60"></label>
</div>
<div class="btn-row">
<button class="b" onclick="closeTimeModal()">Cancel</button>
<button class="b ac" onclick="applyTime()">Apply</button>
</div>
</div>
</div>
<script src="{{ url_for('static', filename='app.js') }}"></script>
{% block scripts %}{% endblock %}
</body>
</html>