feat: Schlagwörter je Kategorie + auf-/zuklappbares Kategorie-Dropdown
- Manuelle Schlagwörter je Kategorie (Popup mit Chips, Doppelklick zum Bearbeiten) - Treffer über Empfänger ODER Verwendungszweck; längstes Schlagwort gewinnt; Kind-Filter (Ausgabe/Einnahme); wirken nur bei künftigen Importen - Lernende Korrektur-Erkennung: ab 5 Anwendungen und >= 1/3 Korrekturen erscheint eine Prüf-Meldung in den Einstellungen (Behalten/Entfernen) - Neue CategorySelect-Komponente (Baum + Suche, per Portal) ersetzt die nativen optgroup-Selects in Buchungen und Import-Prüfansicht - Migration 0006 (source/applied_count/overridden_count/confirmed, match_field any) - Endpunkte, i18n DE/EN, Tests (test_keywords: 7 neu, gesamt 27 grün) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import Icon from "../components/Icon";
|
||||
import IconChip from "../components/IconChip";
|
||||
import Money from "../components/Money";
|
||||
import Modal from "../components/Modal";
|
||||
import CategorySelect from "../components/CategorySelect";
|
||||
import { centsToInput, parseAmountToCents, todayIso } from "../format";
|
||||
|
||||
const TYPES = ["expense", "income", "transfer"];
|
||||
@@ -321,14 +322,14 @@ export default function Transactions() {
|
||||
) : (
|
||||
<label>
|
||||
<span>{t("transactions.category")}</span>
|
||||
<select value={form.category_id} onChange={(e) => setForm({ ...form, category_id: e.target.value })}>
|
||||
<option value="">{t("transactions.uncategorized")}</option>
|
||||
{catOptions.map((g) => (
|
||||
<optgroup key={g.id} label={g.name}>
|
||||
{g.categories.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
|
||||
</optgroup>
|
||||
))}
|
||||
</select>
|
||||
<CategorySelect
|
||||
groups={catOptions}
|
||||
value={form.category_id}
|
||||
onChange={(id) => setForm({ ...form, category_id: id != null ? String(id) : "" })}
|
||||
allowNone
|
||||
noneLabel={t("transactions.uncategorized")}
|
||||
placeholder={t("transactions.uncategorized")}
|
||||
/>
|
||||
</label>
|
||||
)}
|
||||
|
||||
@@ -357,13 +358,12 @@ export default function Transactions() {
|
||||
{form.budget_as_expense && (
|
||||
<label>
|
||||
<span>{t("transactions.budgetCategory")}</span>
|
||||
<select value={form.budget_category_id} onChange={(e) => setForm({ ...form, budget_category_id: e.target.value })}>
|
||||
{expenseGroups.map((g) => (
|
||||
<optgroup key={g.id} label={g.name}>
|
||||
{g.categories.map((c) => <option key={c.id} value={c.id}>{c.name}</option>)}
|
||||
</optgroup>
|
||||
))}
|
||||
</select>
|
||||
<CategorySelect
|
||||
groups={expenseGroups}
|
||||
value={form.budget_category_id}
|
||||
onChange={(id) => setForm({ ...form, budget_category_id: id != null ? String(id) : "" })}
|
||||
placeholder={t("transactions.budgetCategory")}
|
||||
/>
|
||||
</label>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user