left4me/l4d2web/templates/blueprint_detail.html
mwiegand aacd95012e
feat(l4d2-web): blueprint rename moves to footer modal — matches overlay/server pattern
Drops the inline Name input from the blueprint edit form. A Rename link
sits next to Delete in the page footer; clicking opens a one-line modal
that posts to a new POST /blueprints/<id>/rename route. The main edit
form keeps the current name as a hidden input so its full Save still
works unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 01:37:29 +02:00

95 lines
4.8 KiB
HTML
Raw 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.

{% extends "base.html" %}
{% block title %}Blueprint {{ blueprint.name }} | left4me{% endblock %}
{% block content %}
<section class="panel">
<div class="page-heading">
<h1>Blueprint: {{ blueprint.name }}</h1>
</div>
<form method="post" action="/blueprints/{{ blueprint.id }}" class="stack">
<input type="hidden" name="csrf_token" value="{{ session.get('csrf_token', '') }}">
<input type="hidden" name="name" value="{{ blueprint.name }}">
<label><span class="section-title">Arguments</span><textarea name="arguments" rows="2" spellcheck="false">{{ arguments | join('\n') }}</textarea></label>
<span class="section-title">Overlays</span>
<div class="overlay-picker">
<ol class="overlay-picker-list" data-overlay-list>
{% for overlay in selected_overlays %}
<li class="overlay-picker-row" draggable="true" data-overlay-id="{{ overlay.id }}" data-overlay-name="{{ overlay.name }}">
<span class="overlay-picker-handle" aria-hidden="true">⋮⋮</span>
<span class="overlay-picker-name">{{ overlay.name }}</span>
<label class="overlay-picker-expose" title="Auto-load this overlay's server.cfg before your blueprint config">
<input type="checkbox" name="expose_server_cfg_ids" value="{{ overlay.id }}"
{% if overlay_expose_state.get(overlay.id) %}checked{% endif %}>
exec <code>server.cfg</code>
</label>
<button type="button" class="overlay-picker-remove" data-action="remove" aria-label="Remove {{ overlay.name }}">×</button>
<input type="hidden" name="overlay_ids" value="{{ overlay.id }}">
</li>
{% endfor %}
</ol>
<p class="overlay-picker-empty muted" data-overlay-empty {% if selected_overlays %}hidden{% endif %}>No overlays selected. Pick one below to add.</p>
<div class="overlay-picker-add">
<select data-overlay-add aria-label="Add overlay">
<option value="">Add overlay…</option>
{% for overlay in available_overlays %}
<option value="{{ overlay.id }}" data-overlay-name="{{ overlay.name }}">{{ overlay.name }}</option>
{% endfor %}
</select>
</div>
</div>
{% set exposed = [] %}
{# Source `exec` is last-wins. First overlay in the list = topmost =
highest precedence, so its exec runs LAST. Iterate the picker list in
reverse to render the preview in actual execution order. #}
{% for overlay in selected_overlays | reverse %}{% if overlay_expose_state.get(overlay.id) %}{{ exposed.append(overlay) or '' }}{% endif %}{% endfor %}
<label><span class="section-title">Config</span>
<div class="config-shell">
{% if exposed %}
<pre class="config-preview" aria-label="Auto-loaded overlay configs">{% for o in exposed %}exec {{ o.name }}.cfg
{% endfor %}</pre>
{% endif %}
<textarea name="config" rows="8" spellcheck="false">{{ config_lines | join('\n') }}</textarea>
</div>
</label>
<button type="submit">Save blueprint</button>
</form>
</section>
<div class="page-footer-actions">
<button type="button" class="danger-outline" data-modal-open="delete-blueprint-modal">Delete blueprint</button>
<a href="#" class="link-button" data-modal-open="rename-blueprint-modal">Rename</a>
</div>
<dialog id="rename-blueprint-modal" class="modal" aria-labelledby="rename-blueprint-title">
<div class="modal-header">
<h2 id="rename-blueprint-title">Rename blueprint</h2>
<button type="button" class="modal-close" data-modal-close aria-label="Close">&times;</button>
</div>
<div class="modal-body">
<form method="post" action="/blueprints/{{ blueprint.id }}/rename" class="inline-save">
<input type="hidden" name="csrf_token" value="{{ session.get('csrf_token', '') }}">
<input name="name" value="{{ blueprint.name }}" required autofocus>
<button type="submit">Save</button>
</form>
</div>
</dialog>
<dialog id="delete-blueprint-modal" class="modal" aria-labelledby="delete-blueprint-title">
<div class="modal-header">
<h2 id="delete-blueprint-title">Delete blueprint "{{ blueprint.name }}"?</h2>
<button type="button" class="modal-close" data-modal-close aria-label="Close">&times;</button>
</div>
<div class="modal-body">
<p>This cannot be undone. Blueprints in use by a server cannot be deleted.</p>
</div>
<div class="modal-footer">
<button type="button" class="button-secondary" data-modal-close>Cancel</button>
<form method="post" action="/blueprints/{{ blueprint.id }}/delete" class="inline-form">
<input type="hidden" name="csrf_token" value="{{ session.get('csrf_token', '') }}">
<button class="danger" type="submit">Delete</button>
</form>
</div>
</dialog>
<script src="{{ url_for('static', filename='js/blueprint-overlay-picker.js') }}" defer></script>
{% endblock %}