feat(agent): log answer comments

This commit is contained in:
2026-09-17 00:02:31 +02:00
parent b42c326d7f
commit af8bfcaa6a
10 changed files with 241 additions and 55 deletions
+57 -42
View File
@@ -139,60 +139,75 @@ function followUpPanel(question) {
function ratingPanel(answerRequestId) {
const panel = node("div", "rating-panel");
panel.append(node("strong", "", "War diese Antwort hilfreich?"));
panel.append(node("strong", "", "Antwort bewerten oder kommentieren"));
const actions = node("div", "rating-actions");
const up = node("button", "secondary rating-choice", "👍 Ja");
const down = node("button", "secondary rating-choice", "👎 Nein");
const up = node("button", "secondary rating-choice", "👍 Hilfreich");
const down = node("button", "secondary rating-choice", "👎 Nicht hilfreich");
const ratingStatus = node("span", "rating-status");
up.type = "button";
down.type = "button";
actions.append(up, down);
actions.append(up, down, ratingStatus);
panel.append(actions);
const form = node("div", "rating-form");
form.hidden = true;
const feedback = node("textarea", "rating-feedback");
feedback.rows = 2;
feedback.maxLength = 1000;
feedback.placeholder = "Optional: Was war hilfreich oder was hat gefehlt?";
const send = node("button", "primary", "Bewertung senden");
send.type = "button";
const status = node("span", "rating-status");
form.append(feedback, send, status);
panel.append(form);
let selection = null;
const select = (value, selected, other) => {
selection = value;
selected.classList.add("is-selected");
other.classList.remove("is-selected");
form.hidden = false;
feedback.focus();
};
up.addEventListener("click", () => select("up", up, down));
down.addEventListener("click", () => select("down", down, up));
send.addEventListener("click", async () => {
if (!selection) return;
send.disabled = true;
status.textContent = "Wird gespeichert …";
const sendRating = async (value, selected, other) => {
up.disabled = true;
down.disabled = true;
ratingStatus.textContent = "Wird gespeichert …";
try {
const response = await fetch("/v1/ratings", {
method: "POST",
headers: apiHeaders(),
body: JSON.stringify({
request_id: answerRequestId,
rating: selection,
feedback: feedback.value.trim() || null,
}),
body: JSON.stringify({ request_id: answerRequestId, rating: value }),
});
if (!response.ok) throw new Error(await errorDetail(response));
status.textContent = "Danke, Bewertung gespeichert.";
up.disabled = true;
down.disabled = true;
feedback.disabled = true;
send.hidden = true;
selected.classList.add("is-selected");
other.classList.remove("is-selected");
ratingStatus.textContent = "Bewertung gespeichert.";
} catch (error) {
status.textContent = error.message || "Bewertung konnte nicht gespeichert werden.";
send.disabled = false;
ratingStatus.textContent = error.message || "Bewertung konnte nicht gespeichert werden.";
} finally {
up.disabled = false;
down.disabled = false;
}
};
up.addEventListener("click", () => sendRating("up", up, down));
down.addEventListener("click", () => sendRating("down", down, up));
const commentForm = node("div", "comment-form");
const comment = node("textarea", "comment-input");
comment.rows = 3;
comment.maxLength = 2000;
comment.placeholder = "Kommentar zu dieser Antwort …";
comment.setAttribute("aria-label", "Kommentar zu dieser Antwort");
const sendComment = node("button", "primary", "Kommentar speichern");
sendComment.type = "button";
const commentStatus = node("span", "comment-status");
commentForm.append(comment, sendComment, commentStatus);
panel.append(commentForm);
sendComment.addEventListener("click", async () => {
const text = comment.value.trim();
if (!text) {
commentStatus.textContent = "Bitte zuerst einen Kommentar eingeben.";
comment.focus();
return;
}
sendComment.disabled = true;
commentStatus.textContent = "Wird gespeichert …";
try {
const response = await fetch("/v1/comments", {
method: "POST",
headers: apiHeaders(),
body: JSON.stringify({ request_id: answerRequestId, comment: text }),
});
if (!response.ok) throw new Error(await errorDetail(response));
comment.value = "";
commentStatus.textContent = "Kommentar gespeichert. Weitere Kommentare sind möglich.";
} catch (error) {
commentStatus.textContent = error.message || "Kommentar konnte nicht gespeichert werden.";
} finally {
sendComment.disabled = false;
}
});
return panel;