๐ (issues): Set the issue description off in a surface card
Changes
3 files changed, +43 -21
MODIFY
src/main/resources/META-INF/resources/shark.css
+22 -6
@@ -837,14 +837,30 @@
837
837
font-size: 13px;
838
838
}
839
839
840
-.issue-desc {
841
- margin: var(--s3) 0 var(--s5);
842
- word-break: break-word;
840
+/* single management bar under the issue body: edit, status transitions, delete pushed right */
841
+.issue-manage {
842
+ display: flex;
843
+ align-items: center;
844
+ flex-wrap: wrap;
845
+ gap: var(--s3);
846
+ margin-top: var(--s5);
847
+ padding-top: var(--s4);
848
+ border-top: 1px solid var(--border-soft);
843
849
}
844
850
845
-/* rendered markdown reuses .readme-body typography; undo its card padding outside the README card */
846
-.issue-desc.readme-body {
847
- padding: 0;
851
+.issue-manage .issue-actions {
852
+ margin: 0;
853
+}
854
+
855
+.issue-manage .issue-remove {
856
+ margin-left: auto;
857
+}
858
+
859
+/* the issue description sits in its own surface card (same look as the README card) so the
860
+ content stands out from the page background */
861
+.issue-desc {
862
+ margin: var(--s4) 0 var(--s5);
863
+ word-break: break-word;
848
864
}
849
865
850
866
.md-toggle {
MODIFY
src/main/resources/templates/IssueResource/issue.html
+16 -12
@@ -10,22 +10,26 @@
10
10
<span class="muted">opened by {#avatar user=issue.author /} {issue.author.username}</span>
11
11
</p>
12
12
{#if descriptionHtml}
13
- <div class="issue-desc readme-body">{descriptionHtml.raw}</div>
13
+ <div class="panel issue-desc">
14
+ <div class="readme-body">{descriptionHtml.raw}</div>
15
+ </div>
14
16
{#else}
15
17
<p class="muted">No description provided.</p>
16
18
{/if}
17
19
{#if owner}
18
- <p><a class="btn btn-secondary btn-sm" href="/repos/{repo.owner.username}/{repo.name}/issues/{issue.number}/edit">Edit issue</a></p>
19
- <form class="issue-actions" method="post" action="/repos/{repo.owner.username}/{repo.name}/issues/{issue.number}/status">
20
- <span class="lbl">Move to</span>
21
- {#for status in statuses}
22
- <button type="submit" class="btn btn-secondary btn-sm" name="status" value="{status}"{#if status == issue.status} disabled{/if}>{status.label}</button>
23
- {/for}
24
- </form>
25
- <form method="post" action="/repos/{repo.owner.username}/{repo.name}/issues/{issue.number}/delete"
26
- onsubmit="return confirm('Delete this issue? This cannot be undone.')">
27
- <button type="submit" class="btn btn-danger">Delete issue</button>
28
- </form>
20
+ <div class="issue-manage">
21
+ <a class="btn btn-secondary btn-sm" href="/repos/{repo.owner.username}/{repo.name}/issues/{issue.number}/edit">Edit issue</a>
22
+ <form class="issue-actions" method="post" action="/repos/{repo.owner.username}/{repo.name}/issues/{issue.number}/status">
23
+ <span class="lbl">Move to</span>
24
+ {#for status in statuses}
25
+ <button type="submit" class="btn btn-secondary btn-sm" name="status" value="{status}"{#if status == issue.status} disabled{/if}>{status.label}</button>
26
+ {/for}
27
+ </form>
28
+ <form class="issue-remove" method="post" action="/repos/{repo.owner.username}/{repo.name}/issues/{issue.number}/delete"
29
+ onsubmit="return confirm('Delete this issue? This cannot be undone.')">
30
+ <button type="submit" class="btn btn-danger btn-sm">Delete issue</button>
31
+ </form>
32
+ </div>
29
33
{/if}
30
34
</section>
31
35
</div>
MODIFY
src/test/java/de/workaround/web/IssueUiTest.java
+5 -3
@@ -82,9 +82,10 @@
82
82
Issue issue = issueService.create(owner, repo, "Styled",
83
83
"Some **bold** text\n\n<script>alert('xss')</script>");
84
84
85
- // markdown is rendered to HTML; embedded raw HTML stays escaped
85
+ // markdown is rendered to HTML inside a surface card; embedded raw HTML stays escaped
86
86
given().when().get("/repos/" + owner.username + "/mdesc/issues/" + issue.number)
87
87
.then().statusCode(200)
88
+ .body(containsString("class=\"panel issue-desc\""))
88
89
.body(containsString("<strong>bold</strong>"))
89
90
.body(not(containsString("<script>alert('xss')</script>")));
90
91
}
@@ -225,10 +226,11 @@
225
226
String base = "/repos/" + owner.username + "/editable/issues";
226
227
String editUrl = base + "/" + issue.number + "/edit";
227
228
228
- // the detail page links to the edit form
229
+ // the detail page links to the edit form from a single management bar
229
230
given().when().get(base + "/" + issue.number)
230
231
.then().statusCode(200)
231
- .body(containsString(editUrl));
232
+ .body(containsString(editUrl))
233
+ .body(containsString("class=\"issue-manage\""));
232
234
233
235
// the edit form is pre-filled with the current title and description
234
236
given().when().get(editUrl)