Merge: remove Billing-Referenz UI + add Notizen (description) field

This commit is contained in:
m
2026-04-20 17:17:18 +02:00
5 changed files with 47 additions and 10 deletions

View File

@@ -59,6 +59,12 @@ export function renderAktenDetail(): string {
</div>
</header>
<div className="akten-detail-description">
<h3 data-i18n="projekte.detail.description.heading">Notizen</h3>
<p id="akte-description-display" className="akten-detail-description-text" />
<textarea id="akte-description-edit" className="akten-detail-description-input" rows={4} style="display:none" />
</div>
<nav className="akten-tabs" id="akte-tabs">
<a className="akten-tab" data-tab="verlauf" href="#" data-i18n="projekte.detail.tab.verlauf">Verlauf</a>
<a className="akten-tab" data-tab="team" href="#" data-i18n="projekte.detail.tab.team">Team</a>

View File

@@ -125,10 +125,6 @@ export function renderAktenNeu(): string {
<input type="text" id="akte-country" maxLength={2} placeholder="DE" />
</div>
</div>
<div className="form-field">
<label htmlFor="akte-billing" data-i18n="projekte.field.billing_reference">Billing-Referenz</label>
<input type="text" id="akte-billing" />
</div>
</div>
{/* Patent-specific */}
@@ -163,6 +159,11 @@ export function renderAktenNeu(): string {
</div>
</div>
<div className="form-field">
<label htmlFor="akte-description" data-i18n="projekte.field.description">Notizen</label>
<textarea id="akte-description" rows={4} placeholder="Kurznotizen zum Projekt (optional)..." data-i18n-placeholder="projekte.field.description.placeholder" />
</div>
<div className="form-field">
<label htmlFor="akte-status" data-i18n="projekte.field.status">Status</label>
<select id="akte-status">

View File

@@ -460,6 +460,18 @@ function renderHeader() {
(document.getElementById("akte-title-edit") as HTMLInputElement).value = akte.title;
(document.getElementById("akte-ref-display") as HTMLElement).textContent = akte.reference || "";
const descDisplay = document.getElementById("akte-description-display") as HTMLElement;
const descEdit = document.getElementById("akte-description-edit") as HTMLTextAreaElement;
const description = (akte as Akte & { description?: string | null }).description ?? "";
descDisplay.textContent = description;
descEdit.value = description;
const descWrap = document.querySelector<HTMLElement>(".akten-detail-description");
if (descWrap) {
// Hide the whole Notizen block when there is nothing to show AND we're
// not in edit mode — toggled by initTitleEdit on edit/save.
descWrap.dataset.empty = description ? "0" : "1";
}
const typeChip = document.getElementById("akte-type-chip")!;
typeChip.className = `akten-type-chip akten-type-${akte.type}`;
typeChip.textContent = t(`projekte.type.${akte.type}`) || akte.type;
@@ -681,12 +693,16 @@ function initTabs() {
function initTitleEdit() {
const display = document.getElementById("akte-title-display")!;
const editInput = document.getElementById("akte-title-edit") as HTMLInputElement;
const descDisplay = document.getElementById("akte-description-display") as HTMLElement;
const descEdit = document.getElementById("akte-description-edit") as HTMLTextAreaElement;
const editBtn = document.getElementById("akte-edit-btn") as HTMLButtonElement;
const saveBtn = document.getElementById("akte-save-btn") as HTMLButtonElement;
editBtn.addEventListener("click", () => {
display.style.display = "none";
editInput.style.display = "";
descDisplay.style.display = "none";
descEdit.style.display = "";
saveBtn.style.display = "";
editBtn.style.display = "none";
editInput.focus();
@@ -696,16 +712,23 @@ function initTitleEdit() {
saveBtn.addEventListener("click", async () => {
if (!akte) return;
const newTitle = editInput.value.trim();
if (!newTitle || newTitle === akte.title) {
const newDesc = descEdit.value.trim();
const oldDesc = (akte as Akte & { description?: string | null }).description ?? "";
const titleUnchanged = !newTitle || newTitle === akte.title;
const descUnchanged = newDesc === oldDesc;
if (titleUnchanged && descUnchanged) {
cancelEdit();
return;
}
saveBtn.disabled = true;
try {
const body: Record<string, unknown> = {};
if (!titleUnchanged) body.title = newTitle;
if (!descUnchanged) body.description = newDesc;
const resp = await fetch(`/api/projekte/${akte.id}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: newTitle }),
body: JSON.stringify(body),
});
if (resp.ok) {
akte = await resp.json();
@@ -722,6 +745,8 @@ function initTitleEdit() {
function cancelEdit() {
display.style.display = "";
editInput.style.display = "none";
descDisplay.style.display = "";
descEdit.style.display = "none";
saveBtn.style.display = "none";
editBtn.style.display = "";
}

View File

@@ -115,9 +115,10 @@ function submitForm() {
if (ind) payload.industry = ind;
const cty = ($("akte-country") as HTMLInputElement).value.trim();
if (cty) payload.country = cty;
const bill = ($("akte-billing") as HTMLInputElement).value.trim();
if (bill) payload.billing_reference = bill;
}
const desc = ($("akte-description") as HTMLTextAreaElement).value.trim();
if (desc) payload.description = desc;
if (type === "patent") {
const pat = ($("akte-patent-number") as HTMLInputElement).value.trim();
if (pat) payload.patent_number = pat;

View File

@@ -772,7 +772,9 @@ const translations: Record<Lang, Record<string, string>> = {
"projekte.field.netdocuments_url": "netDocuments-URL (optional)",
"projekte.field.industry": "Branche",
"projekte.field.country": "Land (ISO-2)",
"projekte.field.billing_reference": "Billing-Referenz",
"projekte.field.description": "Notizen",
"projekte.field.description.placeholder": "Kurznotizen zum Projekt (optional)...",
"projekte.detail.description.heading": "Notizen",
"projekte.field.patent_number": "Patentnummer",
"projekte.field.filing_date": "Anmeldetag",
"projekte.field.grant_date": "Erteilungstag",
@@ -1773,7 +1775,9 @@ const translations: Record<Lang, Record<string, string>> = {
"projekte.field.netdocuments_url": "netDocuments URL (optional)",
"projekte.field.industry": "Industry",
"projekte.field.country": "Country (ISO-2)",
"projekte.field.billing_reference": "Billing reference",
"projekte.field.description": "Notes",
"projekte.field.description.placeholder": "Short notes about the project (optional)...",
"projekte.detail.description.heading": "Notes",
"projekte.field.patent_number": "Patent number",
"projekte.field.filing_date": "Filing date",
"projekte.field.grant_date": "Grant date",