Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Edit issue and change details in place

802e0e52533746522b3e65b953e5cc0141aa70b9 · Keenan Nemetz · 5d ago · parent 90f1ab59

Edit issue and change details in place

Put the title pencil beside the heading and the description menu on its card, matching the comment editor. Each control saves only its own field: the title response is the heading and the description response is the card, so an open draft in the other field is not replaced. The standalone /edit page stays as the fallback.

Prefilled edit fields size themselves to their content and remain vertically resizable. Prose copied from a menu is query-escaped in the attribute, so untrusted markdown in an issue or comment cannot appear verbatim in the page.

server/web/templates/requests.html +57−15

@@ -354,10 +354,26 @@
354 354 </tr>
355 355 {{end}}
356 356
357 {{define "request_head"}}
358 <div class="page-head">
357 {{define "request_title_head"}}
358 <div class="page-head" id="request-head">
359 359 <div class="page-head-main">
360 <h1><span class="page-num">{{num .Number}}</span>{{.Request.Title}}</h1>
360 <div class="details-title">
361 <span class="page-num">{{num .Number}}</span>
362 <h1 class="details-title-view" data-details-title-view{{if .Details.Title.Active}} hidden{{end}}>{{.Request.Title}}</h1>
363 {{if .CanEdit}}
364 <a class="title-edit-toggle" href="/r/{{.Name}}/requests/{{.Request.ID}}/edit"{{if .Details.Inline}} data-title-edit{{end}}{{if .Details.Title.Active}} hidden{{end}} aria-label="Edit title" title="Edit title">{{icon "pencil"}}</a>
365 {{if .Details.Inline}}
366 <form class="title-edit-form" data-title-edit-form method="post" action="/r/{{.Name}}/requests/{{.Request.ID}}/edit" hx-post="/r/{{.Name}}/requests/{{.Request.ID}}/edit" hx-target="#request-head" hx-swap="outerHTML" hx-disabled-elt="find button[type='submit']"{{if not .Details.Title.Active}} hidden{{end}}>
367 <input type="hidden" name="csrf" value="{{.CSRF}}">
368 <input type="hidden" name="field" value="title">
369 <input class="details-title-input" type="text" name="title" required maxlength="200" aria-label="Title" value="{{if .Details.Title.Active}}{{.Details.Title.Value}}{{else}}{{.Request.Title}}{{end}}" data-title-edit-input{{if .Details.Title.Active}} autofocus{{end}}>
370 <button class="secondary" type="button" data-title-edit-cancel>Cancel</button>
371 <button type="submit">{{icon "check"}}Save</button>
372 </form>
373 {{end}}
374 {{end}}
375 </div>
376 {{if .Details.Title.Error}}<p class="error">{{.Details.Title.Error}}</p>{{end}}
361 377 <p class="page-sub">
362 378 <span class="state {{.Request.State}}">{{.Request.State}}</span>
363 379 · by {{template "userlink" (user .Request.Author)}} {{since .Request.Created.Unix}}
@@ -370,6 +386,10 @@
370 386 {{template "request_actions" .}}
371 387 {{template "request_merge_note" .}}
372 388 </div>
389 {{end}}
390
391 {{define "request_head"}}
392 {{template "request_title_head" .}}
373 393 {{template "request_alert" .}}
374 394 {{end}}
375 395
@@ -378,7 +398,7 @@
378 398 {{end}}
379 399
380 400 {{define "request_actions"}}
381 {{if or .CanApprove .CanClose .CanEdit .CanMerge .MergeArmed .ContributorCI .Live}}
401 {{if or .CanApprove .CanClose .CanMerge .MergeArmed .ContributorCI .Live}}
382 402 <div id="request-actions" class="page-head-actions"{{if .Live}} hx-swap-oob="outerHTML"{{end}}>
383 403 {{with .ContributorCI}}{{if .CanAllow}}
384 404 <form method="post" action="/r/{{$.Name}}/ci/allow">
@@ -388,7 +408,6 @@
388 408 <button class="warn" type="submit">{{icon "play"}}Allow CI</button>
389 409 </form>
390 410 {{end}}{{end}}
391 {{if .CanEdit}}<a class="button secondary" href="/r/{{.Name}}/requests/{{.Request.ID}}/edit">{{icon "pencil"}}Edit</a>{{end}}
392 411 {{if .CanApprove}}
393 412 <form method="post" action="/r/{{.Name}}/requests/{{.Request.ID}}/approve" hx-post="/r/{{.Name}}/requests/{{.Request.ID}}/approve" hx-swap="none" hx-disabled-elt="find button[type='submit']">
394 413 <input type="hidden" name="csrf" value="{{.CSRF}}">
@@ -427,6 +446,38 @@
427 446 </nav>
428 447 {{end}}
429 448
449 {{define "request_description"}}
450 <article class="comment{{if .Details.Description.Active}} editing{{end}}" id="request-description">
451 <header class="comment-head">
452 {{$u := user .Request.Author}}
453 <span class="comment-author">{{template "userlink" $u}}</span>
454 <span class="muted">opened this {{since .Request.Created.Unix}}</span>
455 <div class="comment-menu" data-comment-menu>
456 <button type="button" class="comment-menu-toggle" data-comment-menu-toggle aria-haspopup="menu" aria-expanded="false" aria-label="Description actions">&#8943;</button>
457 <div class="comment-menu-list" data-comment-menu-list role="menu" hidden>
458 <button type="button" role="menuitem" data-copy-query="{{urlquery .Request.Description}}">Copy text</button>
459 {{if .CanEdit}}<button type="button" role="menuitem" data-comment-edit>Edit</button>{{end}}
460 </div>
461 </div>
462 </header>
463 <div class="comment-body md">
464 {{if .Description}}{{.Description}}{{else}}<p class="muted">No description.</p>{{end}}
465 </div>
466 {{if .CanEdit}}
467 <form class="comment-edit-form details-edit-form" data-comment-edit-form method="post" action="/r/{{.Name}}/requests/{{.Request.ID}}/edit" hx-post="/r/{{.Name}}/requests/{{.Request.ID}}/edit" hx-target="#request-description" hx-swap="outerHTML" hx-disabled-elt="find button[type='submit']"{{if not .Details.Description.Active}} hidden{{end}}>
468 <input type="hidden" name="csrf" value="{{.CSRF}}">
469 <input type="hidden" name="field" value="body">
470 {{if .Details.Description.Error}}<p class="error">{{.Details.Description.Error}}</p>{{end}}
471 <textarea name="body" data-autosize aria-label="Description">{{if .Details.Description.Active}}{{.Details.Description.Value}}{{else}}{{.Request.Description}}{{end}}</textarea>
472 <div class="form-actions">
473 <button class="secondary" type="button" data-comment-edit-cancel>Cancel</button>
474 <button type="submit">{{icon "check"}}Save</button>
475 </div>
476 </form>
477 {{end}}
478 </article>
479 {{end}}
480
430 481 {{define "request"}}
431 482 {{template "header" .}}
432 483 {{template "repohead" (nav .Page "requests")}}
@@ -435,16 +486,7 @@
435 486
436 487 <div class="thread">
437 488 <div class="thread-main">
438 <article class="comment">
439 <header class="comment-head">
440 {{$u := user .Request.Author}}
441 <span class="comment-author">{{template "userlink" $u}}</span>
442 <span class="muted">opened this {{since .Request.Created.Unix}}</span>
443 </header>
444 <div class="comment-body md">
445 {{if .Description}}{{.Description}}{{else}}<p class="muted">No description.</p>{{end}}
446 </div>
447 </article>
489 {{template "request_description" .}}
448 490
449 491 {{template "comment_thread" .Thread}}
450 492 </div>