Adds the script type to the create-overlay modal (with an admin-only system-wide checkbox) and a script-section to the detail page: textarea for the bash body, Save / Rebuild / Wipe buttons, last_build_status badge, latest-build-job link, and a Wipe confirm modal. Removes the GlobalOverlaySource block. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
178 lines
6.4 KiB
HTML
178 lines
6.4 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Overlay {{ overlay.name }} | left4me{% endblock %}
|
|
|
|
{% block content %}
|
|
<section class="panel">
|
|
<div class="page-heading">
|
|
<h1>Overlay: {{ overlay.name }}</h1>
|
|
{% set can_edit = g.user.admin or (overlay.type in ['workshop', 'script'] and overlay.user_id == g.user.id) %}
|
|
{% if can_edit %}
|
|
<button type="button" class="danger" data-modal-open="delete-overlay-modal">Delete</button>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if can_edit %}
|
|
<form method="post" action="/overlays/{{ overlay.id }}" class="stack">
|
|
<input type="hidden" name="csrf_token" value="{{ session.get('csrf_token', '') }}">
|
|
<label>Name <input name="name" value="{{ overlay.name }}" required></label>
|
|
<div>
|
|
<button type="submit">Save</button>
|
|
</div>
|
|
</form>
|
|
{% endif %}
|
|
|
|
<table class="definition-table">
|
|
<tbody>
|
|
<tr><th>Type</th><td>{{ overlay.type }}</td></tr>
|
|
<tr><th>Scope</th><td>{% if overlay.user_id %}private{% else %}system{% endif %}</td></tr>
|
|
<tr><th>Path</th><td class="muted">{{ overlay.path }}</td></tr>
|
|
<tr>
|
|
<th>Last build</th>
|
|
<td>
|
|
{% if overlay.last_build_status == 'ok' %}
|
|
<span class="badge badge-ok">ok</span>
|
|
{% elif overlay.last_build_status == 'failed' %}
|
|
<span class="badge badge-error">failed</span>
|
|
{% else %}
|
|
<span class="badge badge-muted">never</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</section>
|
|
|
|
{% if overlay.type == 'script' %}
|
|
<section class="panel">
|
|
<div class="page-heading">
|
|
<h2>Script</h2>
|
|
{% if can_edit %}
|
|
<div class="inline-form-group">
|
|
<form method="post" action="/overlays/{{ overlay.id }}/build" class="inline-form">
|
|
<input type="hidden" name="csrf_token" value="{{ session.get('csrf_token', '') }}">
|
|
<button type="submit" class="button-secondary">Rebuild</button>
|
|
</form>
|
|
<button type="button" class="danger" data-modal-open="wipe-overlay-modal">Wipe</button>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if can_edit %}
|
|
<form method="post" action="/overlays/{{ overlay.id }}/script" class="stack">
|
|
<input type="hidden" name="csrf_token" value="{{ session.get('csrf_token', '') }}">
|
|
<label>Bash script
|
|
<textarea name="script" rows="20" spellcheck="false">{{ overlay.script or "" }}</textarea>
|
|
</label>
|
|
<p class="muted">Runs sandboxed against the overlay directory mounted at <code>/overlay</code>. Saving auto-enqueues a build.</p>
|
|
<div>
|
|
<button type="submit">Save</button>
|
|
</div>
|
|
</form>
|
|
{% else %}
|
|
<pre class="script-preview">{{ overlay.script or "" }}</pre>
|
|
{% endif %}
|
|
|
|
{% if latest_build_job %}
|
|
<p>
|
|
Latest build: <a href="/jobs/{{ latest_build_job.id }}">job #{{ latest_build_job.id }}</a>
|
|
— state: <strong>{{ latest_build_job.state }}</strong>
|
|
</p>
|
|
{% endif %}
|
|
</section>
|
|
{% endif %}
|
|
|
|
{% if overlay.type == 'workshop' %}
|
|
<section class="panel">
|
|
<div class="page-heading">
|
|
<h2>Workshop items</h2>
|
|
{% if can_edit %}
|
|
<form method="post" action="/overlays/{{ overlay.id }}/build" class="inline-form">
|
|
<input type="hidden" name="csrf_token" value="{{ session.get('csrf_token', '') }}">
|
|
<button type="submit" class="button-secondary">Rebuild</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
|
|
{% if can_edit %}
|
|
<form method="post" action="/overlays/{{ overlay.id }}/items" class="stack">
|
|
<input type="hidden" name="csrf_token" value="{{ session.get('csrf_token', '') }}">
|
|
<fieldset class="workshop-input-mode">
|
|
<legend>Input mode</legend>
|
|
<label><input type="radio" name="input_mode" value="items" checked> Items (paste IDs or URLs; one or many)</label>
|
|
<label><input type="radio" name="input_mode" value="collection"> Collection (one ID or URL)</label>
|
|
</fieldset>
|
|
<label>Workshop input <textarea name="input" rows="3" placeholder="123456789 https://steamcommunity.com/sharedfiles/filedetails/?id=987654321"></textarea></label>
|
|
<div>
|
|
<button type="submit">Add</button>
|
|
</div>
|
|
</form>
|
|
{% endif %}
|
|
|
|
<div id="overlay-item-table">
|
|
{% include "_overlay_item_table.html" with context %}
|
|
</div>
|
|
</section>
|
|
|
|
{% if latest_build_job %}
|
|
<section class="panel">
|
|
<h2>Latest build</h2>
|
|
<p>
|
|
<a href="/jobs/{{ latest_build_job.id }}">job #{{ latest_build_job.id }}</a>
|
|
— state: <strong>{{ latest_build_job.state }}</strong>
|
|
</p>
|
|
</section>
|
|
{% endif %}
|
|
{% endif %}
|
|
|
|
<section class="panel">
|
|
<h2>Used by</h2>
|
|
{% if using_blueprints %}
|
|
<ul class="used-by-list">
|
|
{% for blueprint in using_blueprints %}
|
|
<li><a href="/blueprints/{{ blueprint.id }}">{{ blueprint.name }}</a></li>
|
|
{% endfor %}
|
|
</ul>
|
|
{% else %}
|
|
<p class="muted">Not used by any blueprint.</p>
|
|
{% endif %}
|
|
</section>
|
|
|
|
{% if can_edit %}
|
|
<dialog id="delete-overlay-modal" class="modal" aria-labelledby="delete-overlay-title">
|
|
<div class="modal-header">
|
|
<h2 id="delete-overlay-title">Delete overlay "{{ overlay.name }}"?</h2>
|
|
<button type="button" class="modal-close" data-modal-close aria-label="Close">×</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>This cannot be undone. Overlays in use by a blueprint cannot be deleted.</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="button-secondary" data-modal-close>Cancel</button>
|
|
<form method="post" action="/overlays/{{ overlay.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>
|
|
|
|
{% if overlay.type == 'script' %}
|
|
<dialog id="wipe-overlay-modal" class="modal" aria-labelledby="wipe-overlay-title">
|
|
<div class="modal-header">
|
|
<h2 id="wipe-overlay-title">Wipe overlay "{{ overlay.name }}"?</h2>
|
|
<button type="button" class="modal-close" data-modal-close aria-label="Close">×</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Empties the overlay directory. Use Rebuild afterward to repopulate.</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="button-secondary" data-modal-close>Cancel</button>
|
|
<form method="post" action="/overlays/{{ overlay.id }}/wipe" class="inline-form">
|
|
<input type="hidden" name="csrf_token" value="{{ session.get('csrf_token', '') }}">
|
|
<button class="danger" type="submit">Wipe</button>
|
|
</form>
|
|
</div>
|
|
</dialog>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% endblock %}
|