Add HTML5 project deletion flow
CI / python (push) Has been cancelled
CI / rust (push) Has been cancelled

This commit is contained in:
2026-05-16 21:50:42 +03:00
parent a721478ff9
commit c3193b8211
3 changed files with 34 additions and 1 deletions
+12 -1
View File
@@ -452,6 +452,17 @@ def _project_row(project: object) -> str:
<td>
<a class="button" href="/html5/projects/{quote(project_id)}/editor">IDE</a>
<a class="button" href="/html5/projects/{quote(project_id)}/setup">Setup</a>
<form
class="delete-project"
method="post"
action="/html5/projects/{quote(project_id)}/delete"
hx-post="/html5/projects/{quote(project_id)}/delete"
hx-target="[data-html5-projects-body]"
hx-swap="innerHTML"
>
<input name="confirmation" value="{escape(project_id)}" aria-label="confirmation" />
<button type="submit">Удалить</button>
</form>
</td>
</tr>"""
@@ -605,7 +616,7 @@ def _css() -> str:
:root{color-scheme:light;--bg:#f7f8fb;--card:#fff;--text:#17202a;--muted:#687385;--line:#dce2ea;--brand:#2457d6;--ok:#168457;--warn:#a16207}
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--text);font:14px/1.45 system-ui,-apple-system,Segoe UI,sans-serif}a{color:inherit}
.shell{min-height:100vh;padding:32px}.hero{display:flex;justify-content:space-between;gap:24px;align-items:end;margin:0 auto 24px;max-width:1180px}.hero h1{margin:0;font-size:36px;letter-spacing:0}.lead{max-width:640px;color:var(--muted);font-size:16px}.eyebrow{margin:0 0 8px;color:var(--brand);font-size:12px;font-weight:800;text-transform:uppercase}.hero-metrics{min-width:160px;border:1px solid var(--line);background:var(--card);padding:18px}.hero-metrics strong{display:block;font-size:34px}.hero-metrics span,.muted{color:var(--muted)}
.band,.panel,.editor{border:1px solid var(--line);background:var(--card)}.band{max-width:1180px;margin:auto;padding:18px}.section-title,.topbar,.editor-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.button,button{display:inline-flex;align-items:center;justify-content:center;height:32px;border:1px solid var(--line);background:#fff;padding:0 12px;text-decoration:none;font-weight:700;cursor:pointer}table{width:100%;border-collapse:collapse}th,td{border-top:1px solid var(--line);padding:12px;text-align:left}td small{display:block;color:var(--muted)}
.band,.panel,.editor{border:1px solid var(--line);background:var(--card)}.band{max-width:1180px;margin:auto;padding:18px}.section-title,.topbar,.editor-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.button,button{display:inline-flex;align-items:center;justify-content:center;height:32px;border:1px solid var(--line);background:#fff;padding:0 12px;text-decoration:none;font-weight:700;cursor:pointer}table{width:100%;border-collapse:collapse}th,td{border-top:1px solid var(--line);padding:12px;text-align:left}td small{display:block;color:var(--muted)}td .button,td form{margin-right:6px}.delete-project{display:inline-flex;gap:4px;vertical-align:middle}.delete-project input{height:32px;width:120px;border:1px solid var(--line);padding:0 6px}
.workspace{min-height:100vh;padding-bottom:34px}.topbar{position:sticky;top:0;z-index:2;height:54px;border-bottom:1px solid var(--line);background:rgba(255,255,255,.94);padding:0 14px}.brand{font-weight:900;text-decoration:none;color:var(--brand)}.project-nav{display:flex;gap:6px;overflow:auto;flex:1}.project-link{white-space:nowrap;text-decoration:none;border:1px solid var(--line);padding:6px 10px;background:#fff}.project-link.active{background:var(--brand);border-color:var(--brand);color:#fff}
.layout{display:grid;grid-template-columns:280px minmax(0,1fr)320px;height:calc(100vh - 88px)}.panel{overflow:auto}.panel-title{padding:12px;border-bottom:1px solid var(--line);font-size:12px;font-weight:900;text-transform:uppercase;color:var(--muted)}.tree-item{display:block;padding:10px 12px;border-bottom:1px solid var(--line);text-decoration:none}.tree-item span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tree-item small{color:var(--muted)}
.editor{min-width:0;overflow:hidden;border-top:0;border-bottom:0}.editor-head{height:72px;border-bottom:1px solid var(--line);padding:0 14px}.editor-head h1{margin:0;font-size:18px}.search{display:flex;gap:6px}.search input{height:32px;width:260px;border:1px solid var(--line);padding:0 10px}.code{height:calc(100% - 72px);margin:0;overflow:auto;padding:16px;background:#fbfaf7;font:13px/1.55 ui-monospace,SFMono-Regular,Consolas,monospace;white-space:pre-wrap}
@@ -1601,6 +1601,17 @@ async def html5_create_project(request: Request) -> Response:
)
@app.post("/html5/projects/{project_id}/delete")
async def html5_delete_project(project_id: str, request: Request) -> Response:
form = await _html5_form_data(request)
confirmation = _form_value(form, "confirmation") or ""
await delete_project(project_id, ProjectDeleteRequest(confirmation=confirmation))
return Response(
render_html5_project_rows(_project_summaries()),
media_type="text/html; charset=utf-8",
)
@app.get("/html5/projects/{project_id}/editor")
async def html5_project_editor(project_id: str, q: str = "") -> Response:
try: