Ticket-Details: Repo und klickbare Ticket-Nummer in der Ueberschrift, Beschreibung auf 10 Zeilen gekuerzt
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
32e405252b
commit
5a00a668ec
4 changed files with 72 additions and 9 deletions
|
|
@ -741,7 +741,17 @@ header.office-header h1 {
|
|||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.office-modal-item .office-modal-description {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
.office-modal-repo {
|
||||
color: #64748b;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.office-modal-item-heading {
|
||||
flex-wrap: wrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
|
|
|
|||
|
|
@ -1419,6 +1419,23 @@ function renderTicketModalBody(body, content) {
|
|||
|
||||
const heading = document.createElement("div");
|
||||
heading.className = "office-modal-item-heading";
|
||||
if (item.repo) {
|
||||
const repoEl = document.createElement("span");
|
||||
repoEl.className = "office-modal-repo";
|
||||
repoEl.textContent = item.repo;
|
||||
heading.appendChild(repoEl);
|
||||
}
|
||||
if (item.number) {
|
||||
const numEl = item.link ? document.createElement("a") : document.createElement("span");
|
||||
numEl.className = "office-modal-ticket-number";
|
||||
numEl.textContent = `#${item.number}`;
|
||||
if (item.link) {
|
||||
numEl.href = item.link;
|
||||
numEl.target = "_blank";
|
||||
numEl.rel = "noopener noreferrer";
|
||||
}
|
||||
heading.appendChild(numEl);
|
||||
}
|
||||
const titleEl = document.createElement("strong");
|
||||
titleEl.textContent = item.title;
|
||||
heading.appendChild(titleEl);
|
||||
|
|
@ -1433,17 +1450,10 @@ function renderTicketModalBody(body, content) {
|
|||
|
||||
if (item.description) {
|
||||
const desc = document.createElement("p");
|
||||
desc.className = "office-modal-description";
|
||||
desc.textContent = item.description;
|
||||
li.appendChild(desc);
|
||||
}
|
||||
if (item.link) {
|
||||
const a = document.createElement("a");
|
||||
a.href = item.link;
|
||||
a.target = "_blank";
|
||||
a.rel = "noopener noreferrer";
|
||||
a.textContent = "Auf Codeberg öffnen";
|
||||
li.appendChild(a);
|
||||
}
|
||||
list.appendChild(li);
|
||||
}
|
||||
body.appendChild(list);
|
||||
|
|
|
|||
|
|
@ -190,6 +190,22 @@ export function groupTicketsByColumn(tickets = []) {
|
|||
return groups;
|
||||
}
|
||||
|
||||
// Issue #88: Beschreibungen im Ticket-Modal werden auf diese Zeilenzahl gekuerzt.
|
||||
export const TICKET_DESCRIPTION_MAX_LINES = 10;
|
||||
|
||||
/**
|
||||
* Kuerzt einen Text auf maxLines Zeilen; ist er laenger, ersetzt "..." den Rest.
|
||||
*
|
||||
* @param {string} text
|
||||
* @param {number} [maxLines]
|
||||
* @returns {string}
|
||||
*/
|
||||
export function truncateDescriptionLines(text, maxLines = TICKET_DESCRIPTION_MAX_LINES) {
|
||||
const lines = String(text || "").replace(/\s+$/, "").split(/\r?\n/);
|
||||
if (lines.length <= maxLines) return lines.join("\n");
|
||||
return `${lines.slice(0, maxLines).join("\n")}\n...`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Baut das Inhaltsmodell fuer das Board-Spalten-Modal (Visualization.md 4.2/4.5): echter
|
||||
* Titel/Beschreibung je Ticket, plus Link auf die Codeberg-Quelle sofern das Ticket per
|
||||
|
|
@ -210,9 +226,15 @@ export function buildTicketModalContent(columnKey, tickets = [], opts = {}) {
|
|||
items: tickets.map((ticket) => ({
|
||||
id: ticket.id,
|
||||
title: ticket.title,
|
||||
description: ticket.description || "",
|
||||
description: truncateDescriptionLines(ticket.description),
|
||||
type: ticket.type || null,
|
||||
color: ticket.color || null,
|
||||
// Issue #88: Repo und Ticket-Nummer stehen in der Ueberschrift, die Nummer ist der Link.
|
||||
repo:
|
||||
ticket.source === "codeberg" && ticket.external_ref
|
||||
? ticket.repo || `${codebergOwner}/${codebergRepo}`
|
||||
: null,
|
||||
number: ticket.source === "codeberg" && ticket.external_ref ? String(ticket.external_ref) : null,
|
||||
link:
|
||||
ticket.source === "codeberg" && ticket.external_ref
|
||||
? `https://codeberg.org/${ticket.repo || `${codebergOwner}/${codebergRepo}`}/issues/${ticket.external_ref}`
|
||||
|
|
|
|||
|
|
@ -904,3 +904,24 @@ test("systemsWithoutHostConfig kommt ohne Hosts und ohne system_ids zurecht", ()
|
|||
assert.deepEqual(systemsWithoutHostConfig([{ id: "a" }], [{ hostname: "a" }]), [{ id: "a" }]);
|
||||
assert.deepEqual(systemsWithoutHostConfig(), []);
|
||||
});
|
||||
|
||||
test("buildTicketModalContent liefert Repo und Ticket-Nummer fuer die Ueberschrift (Issue #88)", () => {
|
||||
const content = buildTicketModalContent("backlog", [
|
||||
{ id: 1, title: "A", source: "codeberg", external_ref: "3", repo: "fds2610/Steuerkram" },
|
||||
{ id: 2, title: "B", source: "api", external_ref: null },
|
||||
]);
|
||||
assert.equal(content.items[0].repo, "fds2610/Steuerkram");
|
||||
assert.equal(content.items[0].number, "3");
|
||||
assert.equal(content.items[1].repo, null);
|
||||
assert.equal(content.items[1].number, null);
|
||||
});
|
||||
|
||||
test("buildTicketModalContent kuerzt Beschreibungen auf 10 Zeilen mit '...' (Issue #88)", () => {
|
||||
const lines = Array.from({ length: 12 }, (_, i) => `Zeile ${i + 1}`);
|
||||
const [long, exact] = buildTicketModalContent("backlog", [
|
||||
{ id: 1, title: "A", description: lines.join("\n") },
|
||||
{ id: 2, title: "B", description: lines.slice(0, 10).join("\n") },
|
||||
]).items;
|
||||
assert.equal(long.description, `${lines.slice(0, 10).join("\n")}\n...`);
|
||||
assert.equal(exact.description, lines.slice(0, 10).join("\n"));
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue