diff --git a/web/src/locales/de.json b/web/src/locales/de.json index d26d3f0..6a3d831 100644 --- a/web/src/locales/de.json +++ b/web/src/locales/de.json @@ -360,7 +360,9 @@ "removeEntryConfirm": "Den Verlaufs-Eintrag „{{file}}“ entfernen? Die Buchungen sind bereits zurückgenommen.", "reconMixedHint": "Enthält die Datei mehrere Konten oder Produkte? Revolut legt Giro, Erspartes und Anlagekonto in EINE Datei, jedes mit eigener Kontostand-Spalte. Dann greift der Abgleich erst, wenn du oben den Zeilenfilter setzt (z. B. Produkt = Giro) und die übrigen Produkte einzeln einliest.", "filterTitle": "Diese Datei enthält mehrere Konten", - "filterValueOption": "{{value}} ({{count}} Zeilen)" + "filterValueOption": "{{value}} ({{count}} Zeilen)", + "removeAllUndone": "Rückgängig gemachte entfernen", + "removeAllUndoneConfirm": "{{n}} rückgängig gemachte Einträge aus dem Verlauf entfernen? Die Buchungen sind bereits weg, es verschwindet nur der Eintrag." }, "password": { "show": "Passwort anzeigen", diff --git a/web/src/locales/en.json b/web/src/locales/en.json index c653268..6fb0b99 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -360,7 +360,9 @@ "removeEntryConfirm": "Remove the history entry “{{file}}”? Its transactions have already been undone.", "reconMixedHint": "Does the file hold several accounts or products? Revolut puts current, savings and investment into ONE file, each with its own balance column. The check only works once you set the row filter above (e.g. Product = Current) and import the other products separately.", "filterTitle": "This file holds several accounts", - "filterValueOption": "{{value}} ({{count}} rows)" + "filterValueOption": "{{value}} ({{count}} rows)", + "removeAllUndone": "Remove undone entries", + "removeAllUndoneConfirm": "Remove {{n}} undone entries from the history? The bookings are already gone; only the entry disappears." }, "password": { "show": "Show password", diff --git a/web/src/pages/Import.jsx b/web/src/pages/Import.jsx index ec29261..2cdf8be 100644 --- a/web/src/pages/Import.jsx +++ b/web/src/pages/Import.jsx @@ -206,6 +206,22 @@ export default function Import() { try { await api.removeImportBatch(b.id); loadStamm(); } catch (e) { toast(e.message, "error"); } } + // Nach einer Reihe von Versuchen stehen schnell zwanzig rueckgaengig gemachte + // Importe im Verlauf. Die einzeln wegzuklicken ist Fleissarbeit ohne Nutzen. + async function alleErledigtenEntfernen() { + const weg = batches.filter((b) => b.status === "undone"); + if (!weg.length) return; + if (!(await confirm({ + title: t("import.removeAllUndone"), + message: t("import.removeAllUndoneConfirm", { n: weg.length }), + danger: true, confirmLabel: t("common.delete"), + }))) return; + try { + for (const b of weg) await api.removeImportBatch(b.id); + loadStamm(); + } catch (e) { toast(e.message, "error"); } + } + async function undo(b) { if (!(await confirm({ title: t("import.undo"), message: t("import.undoConfirm", { file: b.filename }), danger: true, confirmLabel: t("import.undo") }))) return; try { await api.undoImportBatch(b.id); loadStamm(); } catch (e) { toast(e.message, "error"); } @@ -336,7 +352,7 @@ export default function Import() { render: (b) => {t("import.importedCount", { n: b.imported_count })}, }, { - key: "action", header: "", width: 168, fixed: true, + key: "action", header: "", width: 196, fixed: true, render: (b) => (b.status === "committed" ? ( + )} +