231 lines
11 KiB
HTML
231 lines
11 KiB
HTML
{% extends "base.html" %}
|
|
{% from "_datetime_picker_field.html" import datetime_picker_field %}
|
|
|
|
{% block content %}
|
|
{% include "_mission_ops_tabs.html" %}
|
|
{% include "_mission_preview_header.html" %}
|
|
|
|
<section class="mission-detail-layout top-gap">
|
|
<div class="mission-detail-main">
|
|
<section class="panel mission-asset-overview">
|
|
<div class="mission-asset-head">
|
|
<div>
|
|
<p class="eyebrow">Asset Summary</p>
|
|
<h2>{{ asset.name }}</h2>
|
|
<p class="small-muted">{{ asset.asset_type }} · {{ asset.program or 'No program assigned' }}</p>
|
|
</div>
|
|
<div class="mission-asset-chip-row">
|
|
<span class="chip strong">{{ asset_summary.current_state }}</span>
|
|
<span class="chip">{{ asset_summary.current_location }}</span>
|
|
{% if asset.home_region %}
|
|
<span class="chip">{{ asset.home_region }}</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mission-meta-grid">
|
|
<div class="mission-meta-item">
|
|
<dt>Current Mission</dt>
|
|
<dd>{{ asset_summary.current_mission }}</dd>
|
|
</div>
|
|
<div class="mission-meta-item">
|
|
<dt>Active Window</dt>
|
|
<dd>{{ asset_summary.state_window }}</dd>
|
|
</div>
|
|
<div class="mission-meta-item field-span-two">
|
|
<dt>Next Planned Event</dt>
|
|
<dd>{{ asset_summary.next_event }}</dd>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="panel mission-future-panel">
|
|
<div class="mission-log-top">
|
|
<div class="panel-heading">
|
|
<p class="eyebrow">未来事件</p>
|
|
<h2>可编辑的未来记录</h2>
|
|
<p class="small-muted">这里汇总了未来的 Event Point、State Interval,以及当前区间里尚未发生的 State Node。</p>
|
|
</div>
|
|
<div class="mission-group-count">{{ future_events|length }} future items</div>
|
|
</div>
|
|
|
|
{% if future_events %}
|
|
<div class="mission-future-list">
|
|
{% for item in future_events %}
|
|
<article class="mission-upcoming-item mission-future-item">
|
|
<div class="mission-upcoming-head">
|
|
<div>
|
|
<p class="mission-upcoming-date">{{ item.when }}</p>
|
|
<h3>{{ item.title }}</h3>
|
|
<p class="small-muted">{{ item.kind_label }} · {{ item.status_label }}</p>
|
|
</div>
|
|
<a class="table-link mission-future-action" href="{{ item.edit_url }}">{{ item.action_label }}</a>
|
|
</div>
|
|
|
|
<p class="small-muted">{{ item.scope }}</p>
|
|
<p class="small-muted mission-future-summary">{{ item.summary }}</p>
|
|
{% if item.edit_hint %}
|
|
<p class="small-muted">{{ item.edit_hint }}</p>
|
|
{% endif %}
|
|
|
|
{% if item.state_labels or item.mission_labels %}
|
|
<div class="mission-asset-chip-row mission-entry-label-row">
|
|
{% for label in item.state_labels %}<span class="chip">{{ label }}</span>{% endfor %}
|
|
{% for label in item.mission_labels %}<span class="chip">{{ label }}</span>{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
</article>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<section class="empty-state compact-empty">
|
|
<h2>没有未来记录</h2>
|
|
<p>当前选定的 Simulation Time 之后还没有排定的事件。</p>
|
|
</section>
|
|
{% endif %}
|
|
</section>
|
|
|
|
<section class="panel mission-log-panel">
|
|
<div class="mission-log-top">
|
|
<div class="panel-heading">
|
|
<p class="eyebrow">全部日志</p>
|
|
<h2>资产日志</h2>
|
|
</div>
|
|
<div class="mission-group-count">{{ filtered_entry_count }} / {{ total_entry_count }} entries</div>
|
|
</div>
|
|
|
|
<form method="get" class="mission-log-filter-grid">
|
|
<input type="hidden" name="sim_time" value="{{ simulation_time_input }}">
|
|
{{ datetime_picker_field('Start', 'start', entry_filter_start_input, field_id='asset-log-start') }}
|
|
{{ datetime_picker_field('End', 'end', entry_filter_end_input, field_id='asset-log-end') }}
|
|
<button class="primary-button" type="submit">筛选</button>
|
|
<a class="secondary-button" href="{{ url_for('web.asset_detail', asset_id=asset.id, sim_time=simulation_time_input) }}">重置</a>
|
|
</form>
|
|
|
|
{% if entries %}
|
|
<div class="table-shell">
|
|
<table class="data-table compact-table mission-log-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Time</th>
|
|
<th>Entry</th>
|
|
<th>Labels</th>
|
|
<th>Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for entry in entries %}
|
|
<tr>
|
|
<td class="two-line-cell">
|
|
<strong class="table-title">{{ entry.timestamp }}</strong>
|
|
{% if entry.end_timestamp %}
|
|
<div class="table-subline">→ {{ entry.end_timestamp }}</div>
|
|
{% endif %}
|
|
<div class="table-subline single-line-cell">{{ entry.location }}</div>
|
|
</td>
|
|
<td class="two-line-cell">
|
|
<strong class="table-title">{{ entry.title }}</strong>
|
|
<div class="table-subline">{{ entry.mode_label }} · {{ entry.status_label }}</div>
|
|
<div class="table-subline clamp-line">{{ entry.summary }}</div>
|
|
</td>
|
|
<td>
|
|
{% if entry.state_labels or entry.mission_labels %}
|
|
<div class="mission-asset-chip-row mission-entry-label-row">
|
|
{% for label in entry.state_labels %}<span class="chip">{{ label }}</span>{% endfor %}
|
|
{% for label in entry.mission_labels %}<span class="chip">{{ label }}</span>{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<span class="small-muted">-</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<div class="table-actions">
|
|
<a class="table-link" href="{{ url_for('web.asset_entry_edit', asset_id=asset.id, entry_id=entry.id, sim_time=simulation_time_input) }}">编辑条目</a>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{% if entry_total_pages > 1 %}
|
|
<nav class="pagination-bar" aria-label="Asset timeline pagination">
|
|
{% if entry_has_prev %}
|
|
<a class="pagination-link" href="{{ entry_prev_url }}">上一页</a>
|
|
{% else %}
|
|
<span class="pagination-link disabled">上一页</span>
|
|
{% endif %}
|
|
|
|
<div class="pagination-pages">
|
|
{% for item in entry_page_links %}
|
|
{% if item.ellipsis %}
|
|
<span class="pagination-ellipsis">...</span>
|
|
{% elif item.current %}
|
|
<span class="pagination-link current">{{ item.number }}</span>
|
|
{% else %}
|
|
<a class="pagination-link" href="{{ item.url }}">{{ item.number }}</a>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</div>
|
|
|
|
{% if entry_has_next %}
|
|
<a class="pagination-link" href="{{ entry_next_url }}">下一页</a>
|
|
{% else %}
|
|
<span class="pagination-link disabled">下一页</span>
|
|
{% endif %}
|
|
</nav>
|
|
{% endif %}
|
|
{% else %}
|
|
<section class="empty-state compact-empty">
|
|
{% if total_entry_count %}
|
|
<h2>没有命中筛选条件的日志条目</h2>
|
|
<p>调整起止时间,或者重置筛选后重试。</p>
|
|
{% else %}
|
|
<h2>还没有日志条目</h2>
|
|
<p>先为这个资产新增一个 Event Point 或 State Interval。</p>
|
|
{% endif %}
|
|
</section>
|
|
{% endif %}
|
|
</section>
|
|
</div>
|
|
|
|
<aside class="mission-detail-side">
|
|
<section class="panel mission-current-state-panel">
|
|
<div class="panel-heading">
|
|
<p class="eyebrow">当前状态</p>
|
|
<h2>当前派生状态</h2>
|
|
</div>
|
|
<div class="mission-meta-grid">
|
|
<div class="mission-meta-item">
|
|
<dt>Status</dt>
|
|
<dd>{{ asset_summary.current_state }}</dd>
|
|
</div>
|
|
<div class="mission-meta-item">
|
|
<dt>Location</dt>
|
|
<dd>{{ asset_summary.current_location }}</dd>
|
|
</div>
|
|
<div class="mission-meta-item field-span-two">
|
|
<dt>Mission</dt>
|
|
<dd>{{ asset_summary.current_mission }}</dd>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{% include "_mission_upcoming_events.html" %}
|
|
|
|
<section class="panel mission-entry-actions-panel">
|
|
<div class="panel-heading">
|
|
<p class="eyebrow">操作</p>
|
|
<h2>日志操作</h2>
|
|
</div>
|
|
<div class="mission-action-stack">
|
|
<a class="primary-button" href="{{ url_for('web.asset_entry_new', asset_id=asset.id, kind='event', sim_time=simulation_time_input) }}">新增事件点</a>
|
|
<a class="primary-button" href="{{ url_for('web.asset_entry_new', asset_id=asset.id, kind='state', sim_time=simulation_time_input) }}">新增状态区间</a>
|
|
<a class="secondary-button" href="{{ url_for('web.asset_edit', asset_id=asset.id, sim_time=simulation_time_input) }}">编辑资产</a>
|
|
<a class="secondary-button" href="{{ url_for('web.asset_list', sim_time=simulation_time_input) }}">返回任务资产</a>
|
|
</div>
|
|
</section>
|
|
</aside>
|
|
</section>
|
|
{% endblock %} |