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>
This commit is contained in:
parent
ed12280cf0
commit
aacd95012e
2 changed files with 39 additions and 1 deletions
|
|
@ -142,6 +142,29 @@ def update_blueprint_form(blueprint_id: int) -> Response:
|
|||
return redirect(f"/blueprints/{blueprint_id}")
|
||||
|
||||
|
||||
@bp.post("/blueprints/<int:blueprint_id>/rename")
|
||||
@require_login
|
||||
def rename_blueprint(blueprint_id: int) -> Response:
|
||||
user = current_user()
|
||||
assert user is not None
|
||||
name = request.form.get("name", "").strip()
|
||||
if not name:
|
||||
return Response("name is required", status=400)
|
||||
|
||||
with session_scope() as db:
|
||||
blueprint = db.scalar(
|
||||
select(BlueprintModel).where(
|
||||
BlueprintModel.id == blueprint_id,
|
||||
BlueprintModel.user_id == user.id,
|
||||
)
|
||||
)
|
||||
if blueprint is None:
|
||||
return Response(status=404)
|
||||
blueprint.name = name
|
||||
|
||||
return redirect(f"/blueprints/{blueprint_id}")
|
||||
|
||||
|
||||
def _delete_blueprint(db, user_id: int, blueprint_id: int) -> Response | None:
|
||||
blueprint = db.scalar(
|
||||
select(BlueprintModel).where(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
</div>
|
||||
<form method="post" action="/blueprints/{{ blueprint.id }}" class="stack">
|
||||
<input type="hidden" name="csrf_token" value="{{ session.get('csrf_token', '') }}">
|
||||
<label><span class="section-title">Name</span><input name="name" value="{{ blueprint.name }}" required></label>
|
||||
<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">
|
||||
|
|
@ -58,8 +58,23 @@
|
|||
|
||||
<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">×</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>
|
||||
|
|
|
|||
Loading…
Reference in a new issue