Merge pull request 'Kanban-Board: Ticket-Nummer auf den Zetteln' (#92) from fds2610-bot/monitor:main into main
Reviewed-on: https://codeberg.org/fds2610/monitor/pulls/92
This commit is contained in:
commit
191baa767c
4 changed files with 48 additions and 1 deletions
|
|
@ -212,6 +212,17 @@ header.office-header h1 {
|
||||||
stroke: rgba(15, 23, 42, 0.35);
|
stroke: rgba(15, 23, 42, 0.35);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Issue #91: Ticket-Nummer auf dem Zettel; heller Rand haelt sie auf dunklen Projektfarben lesbar. */
|
||||||
|
.note-number {
|
||||||
|
fill: #0f172a;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 700;
|
||||||
|
paint-order: stroke;
|
||||||
|
stroke: rgba(255, 255, 255, 0.8);
|
||||||
|
stroke-width: 3px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.note-stack-badge {
|
.note-stack-badge {
|
||||||
fill: var(--color-note-stack-badge);
|
fill: var(--color-note-stack-badge);
|
||||||
stroke: #92400e;
|
stroke: #92400e;
|
||||||
|
|
|
||||||
|
|
@ -299,6 +299,16 @@ function renderBoard(ticketCounts, groupedTickets, onColumnClick, onReloadClick)
|
||||||
column.noteColors[i]
|
column.noteColors[i]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
if (column.noteNumbers?.[i]) {
|
||||||
|
colGroup.appendChild(
|
||||||
|
text(column.noteNumbers[i], {
|
||||||
|
x: noteX + NOTE_W / 2,
|
||||||
|
y: noteY + NOTE_H / 2 + 6,
|
||||||
|
class: "note-number",
|
||||||
|
"text-anchor": "middle",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
noteY += NOTE_STEP_Y;
|
noteY += NOTE_STEP_Y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ export const NOTE_STACK_LAYERS = 3;
|
||||||
* @param {Record<string, Array<object>>} groupedTickets - Tickets je Spalte in derselben
|
* @param {Record<string, Array<object>>} groupedTickets - Tickets je Spalte in derselben
|
||||||
* Reihenfolge wie gezaehlt (siehe groupTicketsByColumn()).
|
* Reihenfolge wie gezaehlt (siehe groupTicketsByColumn()).
|
||||||
* @returns {Array<{key: string, label: string, count: number, visibleNotes: number,
|
* @returns {Array<{key: string, label: string, count: number, visibleNotes: number,
|
||||||
* stackCount: number, noteColors: Array<string|null>, stackColors: Array<string>}>}
|
* stackCount: number, noteColors: Array<string|null>, noteNumbers: Array<string|null>, stackColors: Array<string>}>}
|
||||||
*/
|
*/
|
||||||
export function buildBoardColumnLayout(ticketCounts = {}, groupedTickets = {}) {
|
export function buildBoardColumnLayout(ticketCounts = {}, groupedTickets = {}) {
|
||||||
return BOARD_COLUMNS.map(({ key, label }) => {
|
return BOARD_COLUMNS.map(({ key, label }) => {
|
||||||
|
|
@ -64,6 +64,7 @@ export function buildBoardColumnLayout(ticketCounts = {}, groupedTickets = {}) {
|
||||||
visibleNotes,
|
visibleNotes,
|
||||||
stackCount,
|
stackCount,
|
||||||
noteColors: noteColors(tickets.slice(0, visibleNotes), visibleNotes),
|
noteColors: noteColors(tickets.slice(0, visibleNotes), visibleNotes),
|
||||||
|
noteNumbers: noteNumbers(tickets.slice(0, visibleNotes), visibleNotes),
|
||||||
stackColors: stackCount > 0 ? stackLayerColors(tickets.slice(visibleNotes)) : [],
|
stackColors: stackCount > 0 ? stackLayerColors(tickets.slice(visibleNotes)) : [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -85,6 +86,15 @@ function noteColors(tickets, length) {
|
||||||
return Array.from({ length }, (_, i) => tickets[i]?.color ?? null);
|
return Array.from({ length }, (_, i) => tickets[i]?.color ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #91: Ticket-Nummer auf dem Zettel (nur Codeberg-Tickets haben eine); null bei
|
||||||
|
// Tickets ohne Nummer und im Demo-Modus. Der Stapel zeigt bewusst keine Nummern.
|
||||||
|
function noteNumbers(tickets, length) {
|
||||||
|
return Array.from({ length }, (_, i) => {
|
||||||
|
const ticket = tickets[i];
|
||||||
|
return ticket?.source === "codeberg" && ticket.external_ref ? `#${ticket.external_ref}` : null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Ein Stapel steht fuer viele Tickets, aber nur fuer NOTE_STACK_LAYERS Zettel: er zeigt
|
// Ein Stapel steht fuer viele Tickets, aber nur fuer NOTE_STACK_LAYERS Zettel: er zeigt
|
||||||
// deshalb die ersten verschiedenen Projektfarben darin, statt eine davon dreimal zu
|
// deshalb die ersten verschiedenen Projektfarben darin, statt eine davon dreimal zu
|
||||||
// wiederholen. So ist auch an "Done" (immer ein Stapel) zu sehen, aus welchen Projekten die
|
// wiederholen. So ist auch an "Done" (immer ein Stapel) zu sehen, aus welchen Projekten die
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,22 @@ test("buildBoardColumnLayout faerbt jeden Zettel in der Farbe seines Projekts (I
|
||||||
assert.deepEqual(bereit.noteColors, ["#fbca04", "#28a745", "#fbca04"]);
|
assert.deepEqual(bereit.noteColors, ["#fbca04", "#28a745", "#fbca04"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("buildBoardColumnLayout liefert Ticket-Nummern fuer Zettel, nicht fuer den Stapel (Issue #91)", () => {
|
||||||
|
const tickets = Array.from({ length: 7 }, (_, i) => ({
|
||||||
|
column_name: "bereit",
|
||||||
|
source: "codeberg",
|
||||||
|
external_ref: String(i + 1),
|
||||||
|
}));
|
||||||
|
tickets[1] = { column_name: "bereit", source: "api" };
|
||||||
|
const bereit = buildBoardColumnLayout(
|
||||||
|
aggregateTicketsByColumn(tickets),
|
||||||
|
groupTicketsByColumn(tickets)
|
||||||
|
).find((c) => c.key === "bereit");
|
||||||
|
|
||||||
|
assert.deepEqual(bereit.noteNumbers, ["#1", null, "#3", "#4"]);
|
||||||
|
assert.equal(bereit.stackCount, 3);
|
||||||
|
});
|
||||||
|
|
||||||
test("buildBoardColumnLayout laesst Zettel ohne Projektfarbe ungefaerbt", () => {
|
test("buildBoardColumnLayout laesst Zettel ohne Projektfarbe ungefaerbt", () => {
|
||||||
const tickets = [{ column_name: "qa" }, { column_name: "qa", color: "#0366d6" }];
|
const tickets = [{ column_name: "qa" }, { column_name: "qa", color: "#0366d6" }];
|
||||||
const qa = buildBoardColumnLayout(
|
const qa = buildBoardColumnLayout(
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue