feat: Kategorie als eigene Spalte in der Buchungsliste
Die Auswahl sass unter dem Buchungstext. Damit wurden die Zeilen unterschiedlich hoch, die Spalte franste aus, und vergleichen liess sich nichts – genau das, wofuer eine Tabelle da ist. Jetzt zwei Spalten: 'Buchung' mit dem Text und darunter dem Verwendungszweck, 'Kategorie' mit der Auswahl. Ein Uebertrag zeigt dort einen Strich – er ordnet kein Geld ein, er verschiebt es. Die Spaltenliste hat sich damit geaendert, deshalb eine neue Kennung fuer die Tabelle: Die gespeicherte Reihenfolge kennt die neue Spalte nicht und haette die Textspalte ans Ende geschoben. Einmalig sind damit Breiten und Filter dieser Tabelle zurueckgesetzt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+5
-13
@@ -1308,18 +1308,10 @@ tr.row-dup {
|
||||
}
|
||||
}
|
||||
|
||||
/* Kategorie-Auswahl in einer Tabellenzeile. Sie steht dort, wo bisher nur der
|
||||
Name der Kategorie stand – also klein und gedeckelt, nicht über die ganze
|
||||
(wachsende) Spalte. */
|
||||
.zeilen-kategorie {
|
||||
max-width: 240px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.zeilen-kategorie .catsel-btn {
|
||||
/* Kategorie-Auswahl in einer Tabellenzeile: eigene Spalte, also volle
|
||||
Zellenbreite – aber ohne den Abstand, den sie im Formular unter ihrer
|
||||
Beschriftung braucht. Der verschöbe sie gegen die übrigen Zellen. */
|
||||
.datatable td .catsel-btn {
|
||||
margin-top: 0;
|
||||
padding: 3px 6px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
.zeilen-kategorie .catsel-value {
|
||||
font-weight: 500;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
|
||||
@@ -253,7 +253,8 @@
|
||||
"amountRequired": "Bitte einen Betrag eingeben.",
|
||||
"accountRequired": "Bitte ein Konto wählen.",
|
||||
"budgetAsSavings": "Als Sparen ins Budget zählen",
|
||||
"budgetCategory": "Budget-Kategorie"
|
||||
"budgetCategory": "Budget-Kategorie",
|
||||
"subject": "Buchung"
|
||||
},
|
||||
"budget": {
|
||||
"title": "Budget",
|
||||
|
||||
@@ -253,7 +253,8 @@
|
||||
"amountRequired": "Please enter an amount.",
|
||||
"accountRequired": "Please choose an account.",
|
||||
"budgetAsSavings": "Count as savings in the budget",
|
||||
"budgetCategory": "Budget category"
|
||||
"budgetCategory": "Budget category",
|
||||
"subject": "Subject"
|
||||
},
|
||||
"budget": {
|
||||
"title": "Budget",
|
||||
|
||||
@@ -234,7 +234,10 @@ export default function Transactions() {
|
||||
icon: cat?.icon || "more-horizontal",
|
||||
color: cat?.color || "#6b7480",
|
||||
title: zweck || cat?.name || t("transactions.uncategorized"),
|
||||
sub: zweck ? (cat?.name || t("transactions.uncategorized")) : "",
|
||||
// Der Verwendungszweck, falls er neben dem Empfänger noch etwas sagt.
|
||||
// Die Kategorie steht in ihrer eigenen Spalte.
|
||||
sub: tx.payee && tx.description && tx.description !== tx.payee
|
||||
? tx.description : "",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -245,7 +248,8 @@ export default function Transactions() {
|
||||
render: (tx) => <span className="nowrap">{formatDate(tx.date)}</span>,
|
||||
},
|
||||
{
|
||||
key: "category", header: t("transactions.category"), grow: true, min: 200,
|
||||
// Wofür die Zahlung war – danach sucht man in der Liste.
|
||||
key: "text", header: t("transactions.subject"), grow: true, min: 220,
|
||||
filterText: (tx) => rowLabel(tx).title,
|
||||
sortValue: (tx) => rowLabel(tx).title,
|
||||
render: (tx) => {
|
||||
@@ -255,21 +259,7 @@ export default function Transactions() {
|
||||
<IconChip name={l.icon} color={l.color} size={26} />
|
||||
<div className="named-text">
|
||||
<div className="ellipsis">{l.title}</div>
|
||||
{/* Die Kategorie direkt in der Zeile ändern – dafür musste man
|
||||
vorher jede Buchung einzeln zum Bearbeiten öffnen. Ein
|
||||
Übertrag bekommt keine, dort bleibt der Text stehen. */}
|
||||
{tx.type === "transfer" ? (
|
||||
l.sub && <div className="named-sub ellipsis">{l.sub}</div>
|
||||
) : (
|
||||
<div className="zeilen-kategorie">
|
||||
<CategorySelect
|
||||
groups={tx.type === "income" ? incomeGroups : expenseGroups}
|
||||
value={tx.category_id}
|
||||
onChange={(id) => kategorieSetzen(tx, id)}
|
||||
placeholder={t("transactions.uncategorized")}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{l.sub && <div className="named-sub ellipsis">{l.sub}</div>}
|
||||
{/* Verknüpft heisst: zählt nicht als Ausgabe oder Einnahme.
|
||||
Ohne das Gegenkonto sagt „Übertrag" nichts. */}
|
||||
{links[String(tx.id)] && (
|
||||
@@ -284,6 +274,26 @@ export default function Transactions() {
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
// Eigene Spalte, damit die Auswahl in der Zeile steht und nicht unter dem
|
||||
// Text – gestapelt wurden die Zeilen hoch und die Spalte ausgefranst.
|
||||
key: "category", header: t("transactions.category"), width: 210,
|
||||
filterText: (tx) => (tx.category_id ? categoryById[tx.category_id]?.name : "") || "",
|
||||
sortValue: (tx) => (tx.category_id ? categoryById[tx.category_id]?.name : "") || "",
|
||||
render: (tx) => (
|
||||
// Ein Übertrag bekommt keine Kategorie – er ordnet kein Geld ein.
|
||||
tx.type === "transfer" ? (
|
||||
<span className="muted">—</span>
|
||||
) : (
|
||||
<CategorySelect
|
||||
groups={tx.type === "income" ? incomeGroups : expenseGroups}
|
||||
value={tx.category_id}
|
||||
onChange={(id) => kategorieSetzen(tx, id)}
|
||||
placeholder={t("transactions.uncategorized")}
|
||||
/>
|
||||
)
|
||||
),
|
||||
},
|
||||
{
|
||||
key: "account", header: t("transactions.account"), width: 150,
|
||||
filterText: (tx) => accountById[tx.account_id]?.name || "",
|
||||
@@ -353,7 +363,7 @@ export default function Transactions() {
|
||||
|
||||
<div className="card">
|
||||
<DataTable
|
||||
id="transactions"
|
||||
id="transactions-v2"
|
||||
rows={txns}
|
||||
getRowKey={(tx) => tx.id}
|
||||
empty={t("transactions.empty")}
|
||||
|
||||
Reference in New Issue
Block a user