refacto: dashboard Flask Blueprints + templates Jinja2, engine run/lore_enricher mis a jour

This commit is contained in:
2026-06-17 14:10:01 +00:00
parent ae6356ded4
commit ea8e24e238
24 changed files with 2457 additions and 1850 deletions
+173
View File
@@ -0,0 +1,173 @@
{% extends "base.html" %}
{% block content %}
{% if session %}
<div class="info-bar">
<span><span class="label">Session</span> <strong class="val">#{{ session.id }} — {{ session.name }}</strong></span>
<span class="mode-tag">{{ session.mode | upper }}</span>
{% set st = session.status %}
<span class="status-badge {{ 'status-active' if st=='active' else 'status-stopped' if st=='stopped' else 'status-paused' }}">
<span class="dot {{ 'dot-green' if st=='active' else 'dot-red' if st=='stopped' else 'dot-amber' }}"></span>
{{ st | upper }}
</span>
<span><span class="label">Jour</span> <strong class="val">{{ session.current_day }}</strong> / <span class="label">Tick</span> <strong class="val">{{ session.current_tick }}h</strong></span>
</div>
{% endif %}
<div class="grid">
<!-- Config JSON -->
<div class="panel">
<h2>⚙ Config sim_{{ '%03d' % current_sid }}.json</h2>
<form method="POST" action="/params/save?sid={{ current_sid }}">
{% if cfg is not none %}
<div class="cfg-block">
<h3>Général</h3>
<div class="cfg-row">
<label>Nom de la session</label>
<input type="text" name="name" value="{{ cfg.get('name','') }}" style="width:220px">
</div>
<div class="cfg-row">
<label>Mode actif</label>
<select name="mode">
{% for m in ['pacifiste','politique','guerre_commerciale','guerre','survie_extreme'] %}
<option value="{{ m }}" {{ 'selected' if cfg.get('mode')==m else '' }}>{{ m }}</option>
{% endfor %}
</select>
</div>
<div class="cfg-row">
<label>Tick sleep (secondes)</label>
<input type="number" name="tick_sleep_sec" value="{{ cfg.get('tick',{}).get('tick_sleep_sec',60) }}" step="1" min="0">
</div>
</div>
<div class="cfg-block">
<h3>Survie</h3>
<div class="cfg-row">
<label>drain_speed (multiplicateur)</label>
<input type="number" name="survival_drain_speed" value="{{ cfg.get('survival',{}).get('drain_speed',1.0) }}" step="0.1" min="0.1" max="5">
</div>
<div class="cfg-row">
<label>fatigue_hp_per_2pts</label>
<input type="number" name="survival_fatigue_hp" value="{{ cfg.get('survival',{}).get('fatigue_hp_per_2pts',2) }}" step="1" min="0">
</div>
<div class="cfg-row">
<label>Survie activée</label>
<input type="checkbox" name="survival_enabled" {{ 'checked' if cfg.get('survival',{}).get('enabled',True) else '' }}>
</div>
</div>
<div class="cfg-block">
<h3>Rencontres</h3>
<div class="cfg-row">
<label>global_rate_multiplier</label>
<input type="number" name="encounter_rate" value="{{ cfg.get('encounter',{}).get('global_rate_multiplier',1.0) }}" step="0.1" min="0" max="5">
</div>
<div class="cfg-row">
<label>Rencontres activées</label>
<input type="checkbox" name="encounter_enabled" {{ 'checked' if cfg.get('encounter',{}).get('enabled',True) else '' }}>
</div>
</div>
<div class="cfg-block">
<h3>Économie</h3>
<div class="cfg-row">
<label>caps_global_multiplier</label>
<input type="number" name="caps_multiplier" value="{{ cfg.get('economy',{}).get('caps_global_multiplier',1.0) }}" step="0.1" min="0.1">
</div>
</div>
<button type="submit" class="btn btn-green">💾 Sauvegarder config</button>
<p style="margin-top:8px;font-size:12px;color:var(--muted)">
Prise en compte au prochain jour (J{{ (session.current_day or 0) + 1 if session else '?' }}).
Pour effet immédiat : STOP → relancer via terminal.
</p>
{% else %}
<p style="color:var(--red);font-size:13px">
Fichier <code>sim_{{ '%03d' % current_sid }}.json</code> introuvable dans <code>{{ sim_configs_dir }}</code>
</p>
<p style="color:var(--muted);font-size:12px;margin-top:6px">
Vérifier le mount Docker : /home/ubuntu/fallout-venice/src/config → /app/src/config
</p>
{% endif %}
</form>
</div>
<!-- Actions session -->
<div class="panel">
<h2>🔧 Gestion session #{{ current_sid }}</h2>
<div class="cfg-block">
<h3>Statut DB</h3>
<div style="display:flex;gap:8px;flex-wrap:wrap">
<form method="POST" action="/params/setstatus?sid={{ current_sid }}" style="display:inline">
<input type="hidden" name="status" value="active">
<button type="submit" class="btn btn-green">▶ Activer</button>
</form>
<form method="POST" action="/params/setstatus?sid={{ current_sid }}" style="display:inline">
<input type="hidden" name="status" value="paused">
<button type="submit" class="btn">⏸ Pause</button>
</form>
<form method="POST" action="/params/setstatus?sid={{ current_sid }}" style="display:inline">
<input type="hidden" name="status" value="stopped">
<button type="submit" class="btn btn-red">■ Stop</button>
</form>
</div>
<p style="margin-top:8px;font-size:12px;color:var(--muted)">
STOP → la sim s'arrête dans les 5 ticks suivants.
</p>
</div>
<div class="cfg-block">
<h3>Reset jour/tick</h3>
<form method="POST" action="/params/resetday?sid={{ current_sid }}">
<div class="cfg-row">
<label>Remettre au Jour</label>
<input type="number" name="day" value="1" min="1">
</div>
<div class="cfg-row">
<label>Tick</label>
<input type="number" name="tick" value="0" min="0" max="23">
</div>
<button type="submit" class="btn">⏮ Reset position</button>
</form>
</div>
<div class="cfg-block">
<h3>Modes disponibles</h3>
<table>
<tr><th>Mode</th><th>Drain</th><th>Encounters</th><th>Caps</th></tr>
{% for m_name, m_vals in modes.items() %}
<tr>
<td class="{{ 'tier1-text' if cfg and m_name == cfg.get('mode','') else '' }}">
{{ m_name }}{% if cfg and m_name == cfg.get('mode','') %} ◀{% endif %}</td>
<td style="color:var(--muted);font-size:12px">×{{ m_vals.get('survival',{}).get('drain_speed','—') }}</td>
<td style="color:var(--muted);font-size:12px">×{{ m_vals.get('encounter',{}).get('global_rate_multiplier','—') }}</td>
<td style="color:var(--muted);font-size:12px">×{{ m_vals.get('economy',{}).get('caps_global_multiplier','—') }}</td>
</tr>
{% endfor %}
</table>
</div>
<div class="cfg-block">
<h3>Commandes SSH (référence)</h3>
<div class="code-block">
<pre id="ssh_logs_cmd">tail -f ~/fallout_sim_s{{ current_sid }}.log</pre>
<button class="copy-btn" onclick="copyText('ssh_logs_cmd')">Copier</button>
</div>
</div>
</div>
</div>
<script>
function copyText(elementId) {
var el = document.getElementById(elementId);
navigator.clipboard.writeText(el.textContent.trim()).then(function() {
var btn = el.nextElementSibling;
if (btn) { btn.textContent = '✓ Copié'; setTimeout(function(){ btn.textContent = 'Copier'; }, 2000); }
});
}
</script>
{% endblock %}