● feat(#1008): honour reprint dates in archive purge + clarify purge UX

Fix a silent correctness bug: archive purge used `created_at` which is
  pinned to the first print, so reprinting a two-year-old archive yesterday
  would still make it eligible for a 365-day purge. The preview and purge
  queries now age each archive by `COALESCE(completed_at, started_at,
  created_at)` — reprints refresh the clock.

  Also flesh out both purge modals (File Manager + Archives) with an
  explicit "What happens when you click Purge" effects list so users see
  upfront that library files go to Trash (reversible) while archives are
  hard-deleted (irreversible), plus what disk artefacts get removed.

  Backend:
  - services/archive_purge.py: `_last_activity_expr()` helper used by
    preview, purge, and sample query
  - tests/integration/test_archive_purge_api.py: new test covering the
    reprinted-archive case

  Frontend:
  - PurgeOldFilesModal / PurgeArchivesModal: new effects bullet list
  - i18n: reprint-aware ageLabel/description/warning and effects bullets
    across all 8 locales (en/de fully translated, rest English fallback)

  Docs:
  - wiki/features/archiving.md: "How old is measured" note + effects list
  - wiki/features/file-manager.md: "What happens when you click Purge"
    section + explicit age-rule breakdown
  - CHANGELOG: archive auto-purge entry rewritten to mention reprint
    semantics, `archives:purge` permission backfill, and updated test count
This commit is contained in:
maziggy
2026-04-23 17:38:41 +02:00
parent c3e4506275
commit 689bc04d7b
16 changed files with 209 additions and 75 deletions
@@ -99,6 +99,18 @@ export function PurgeArchivesModal({ onClose, initialDays }: PurgeArchivesModalP
</div>
</div>
<div className="rounded border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/30 p-3">
<div className="text-xs font-semibold uppercase tracking-wide text-gray-600 dark:text-gray-300 mb-2">
{t('archivePurge.effectsTitle')}
</div>
<ul className="text-xs text-gray-700 dark:text-gray-300 space-y-1 list-disc pl-4">
<li>{t('archivePurge.effect1')}</li>
<li>{t('archivePurge.effect2')}</li>
<li>{t('archivePurge.effect3')}</li>
<li>{t('archivePurge.effect4')}</li>
</ul>
</div>
<div className="rounded border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50 p-3">
{previewQuery.isLoading || previewQuery.isFetching ? (
<div className="flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400">
@@ -112,6 +112,18 @@ export function PurgeOldFilesModal({ onClose }: PurgeOldFilesModalProps) {
{t('libraryPurge.includeNeverPrinted')}
</label>
<div className="rounded border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/30 p-3">
<div className="text-xs font-semibold uppercase tracking-wide text-gray-600 dark:text-gray-300 mb-2">
{t('libraryPurge.effectsTitle')}
</div>
<ul className="text-xs text-gray-700 dark:text-gray-300 space-y-1 list-disc pl-4">
<li>{t('libraryPurge.effect1')}</li>
<li>{t('libraryPurge.effect2')}</li>
<li>{t('libraryPurge.effect3')}</li>
<li>{t('libraryPurge.effect4')}</li>
</ul>
</div>
<div className="rounded border border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50 p-3">
{previewQuery.isLoading || previewQuery.isFetching ? (
<div className="flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400">
+18 -8
View File
@@ -5196,15 +5196,20 @@ export default {
title: 'Alte Dateien entfernen',
headerButton: 'Alte entfernen',
headerTooltip: 'Alte Dateien im Block in den Papierkorb verschieben',
description: 'Dateien, die älter als die gewählte Schwelle sind, werden in den Papierkorb verschoben. Externe Ordner werden übersprungen. Vor dem automatischen Löschen können Dateien aus dem Papierkorb wiederhergestellt werden.',
description: 'Räume alte Dateien in einem Rutsch aus deiner Bibliothek. Dateien mit Druckverlauf werden nach dem letzten Druckdatum bewertet; nie gedruckte Dateien nach dem Upload-Datum.',
ageLabel: 'Dateien älter als',
days: 'Tage',
includeNeverPrinted: 'Dateien einbeziehen, die nie gedruckt wurden',
effectsTitle: 'Was passiert, wenn du auf „Entfernen" klickst',
effect1: 'Passende Dateien werden in den Papierkorb verschoben — noch nicht von der Festplatte gelöscht.',
effect2: 'Du kannst sie bis zum Ablauf der Aufbewahrungsfrist jederzeit wiederherstellen.',
effect3: 'Nach Ablauf der Frist löscht der Papierkorb-Sweeper sie endgültig von der Festplatte.',
effect4: 'Dateien in externen (verknüpften) Ordnern werden übersprungen — Bambuddy löscht keine Bytes, die ihm nicht gehören.',
previewLoading: 'Prüfe, wie viele Dateien passen…',
previewFailed: 'Vorschau konnte nicht geladen werden.',
previewSummary: '{{count}} Dateien · {{size}} würden in den Papierkorb verschoben',
andMore: '…und {{count}} weitere',
warning: 'Dateien werden nur in den Papierkorb verschoben — bis zum Ablauf der Aufbewahrungsfrist kannst du sie wiederherstellen.',
warning: 'Dateien im Papierkorb zählen weiterhin zum Speicher, bis die Aufbewahrungsfrist abgelaufen ist. Leere den Papierkorb danach, um sofort Speicher freizugeben.',
confirmCta: '{{count}} in den Papierkorb verschieben',
purging: 'Wird verschoben…',
toast: {
@@ -5225,14 +5230,19 @@ export default {
headerButton: 'Alte löschen',
headerTooltip: 'Alte Archive in einem Rutsch löschen',
title: 'Alte Archive löschen',
description: 'Archive, die älter als der Schwellenwert sind, werden dauerhaft gelöscht — inklusive Dateien, Vorschaubildern und Timelapses. Kann nicht rückgängig gemacht werden.',
ageLabel: 'Archive löschen, die älter sind als',
description: 'Räume alte Druckhistorie auf. Jedes Archiv wird nach seinem letzten abgeschlossenen Druck bewertet — ein erneuter Druck setzt die Frist zurück, aktive Arbeit bleibt sicher.',
ageLabel: 'Archive löschen, die zuletzt gedruckt wurden vor',
days: 'Tage',
effectsTitle: 'Was passiert, wenn du auf „Löschen" klickst',
effect1: 'Jedes passende Archiv wird endgültig aus der Datenbank entfernt.',
effect2: 'Die 3MF-Datei, Vorschau, Timelapse, Quell-3MF, F3D-Designdatei und der Foto-Ordner werden von der Festplatte gelöscht.',
effect3: 'Es gibt keinen Papierkorb für Archive — die Löschung ist sofort und unwiderruflich.',
effect4: 'Ein erneuter Druck setzt die Frist zurück, Archive, die du weiterhin nutzt, bleiben sicher.',
previewLoading: 'Prüfe passende Archive…',
previewFailed: 'Vorschau konnte nicht erstellt werden.',
previewSummary: '{{count}} Archive · {{size}} werden gelöscht',
andMore: '…und {{count}} weitere',
warning: 'Archive werden endgültig gelöscht — es gibt keinen Papierkorb für Archive. Lade wichtige Archive vorher herunter oder markiere sie als Favorit.',
warning: 'Dies ist endgültig. Lade wichtige Archive vorher herunter oder markiere sie als Favorit.',
confirmCta: '{{count}} Archiv(e) löschen',
purging: 'Lösche…',
toast: {
@@ -5242,9 +5252,9 @@ export default {
},
archiveAutoPurge: {
enableLabel: 'Alte Archive automatisch löschen',
enableDescription: 'Löscht einmal pro Tag Archive, die älter als der Schwellenwert sind, endgültig. Kein Papierkorb — die Löschung erfolgt sofort.',
ageLabel: 'Archive automatisch löschen, die älter sind als',
ageDescription: 'Minimum 7 Tage, Maximum 10 Jahre. Löscht Archiv, 3MF, Vorschaubild, Timelapse und Fotos.',
enableDescription: 'Löscht einmal pro Tag Archive endgültig, die im angegebenen Zeitraum nicht gedruckt wurden. Ein erneuter Druck setzt die Frist zurück. Kein Papierkorb — die Löschung erfolgt sofort.',
ageLabel: 'Archive automatisch löschen, die zuletzt gedruckt wurden vor',
ageDescription: 'Minimum 7 Tage, Maximum 10 Jahre. Basiert auf dem letzten abgeschlossenen Druck — ein erneuter Druck setzt die Frist zurück. Löscht Archiv, 3MF, Vorschaubild, Timelapse und Fotos.',
days: 'Tage',
runNow: 'Archive jetzt löschen',
saveFailed: 'Einstellungen konnten nicht gespeichert werden.',
+18 -8
View File
@@ -5204,15 +5204,20 @@ export default {
title: 'Purge old files',
headerButton: 'Purge old',
headerTooltip: 'Bulk-move old files to trash',
description: 'Files older than the threshold will be moved to the trash. External folders are skipped. You can restore from trash before auto-deletion.',
description: 'Sweep old files out of your library in one shot. Files with a print history are aged by their last-printed date; files that were never printed are aged by their upload date.',
ageLabel: 'Move files older than',
days: 'days',
includeNeverPrinted: 'Include files that have never been printed',
effectsTitle: 'What happens when you click Purge',
effect1: 'Matching files are moved to Trash — they are not deleted from disk yet.',
effect2: 'You can restore them from Trash at any time until the retention window expires.',
effect3: 'After retention, the trash sweeper permanently removes them from disk.',
effect4: 'Files in external (linked) folders are skipped — Bambuddy never deletes bytes it does not own.',
previewLoading: 'Checking how many files match…',
previewFailed: 'Could not preview the purge.',
previewSummary: '{{count}} files · {{size}} would move to trash',
andMore: '…and {{count}} more',
warning: 'Files are soft-deleted — you can restore them from Trash until the retention window expires.',
warning: 'Trashed files still count against storage until the retention window expires. Empty the Trash afterwards to free disk immediately.',
confirmCta: 'Move {{count}} to trash',
purging: 'Moving to trash…',
toast: {
@@ -5233,14 +5238,19 @@ export default {
headerButton: 'Purge old',
headerTooltip: 'Bulk-delete old archives',
title: 'Purge old archives',
description: 'Archives older than the threshold will be permanently deleted along with their files, thumbnails, and timelapses. This cannot be undone.',
ageLabel: 'Delete archives older than',
description: 'Clear out old print history. Each archive is aged by its most recent print completion — reprinting an archive refreshes its age, so active work is never purged.',
ageLabel: 'Delete archives not printed in the last',
days: 'days',
effectsTitle: 'What happens when you click Purge',
effect1: 'Each matching archive is permanently removed from the database.',
effect2: 'The 3MF, thumbnail, timelapse, source 3MF, F3D design file, and photo folder are all deleted from disk.',
effect3: 'There is no trash bin for archives — deletion is immediate and cannot be undone.',
effect4: 'Reprinting an archive refreshes its age clock, so archives you still use are safe.',
previewLoading: 'Checking how many archives match…',
previewFailed: 'Could not preview the purge.',
previewSummary: '{{count}} archives · {{size}} would be deleted',
andMore: '…and {{count}} more',
warning: 'Archives are hard-deleted — there is no trash bin for archives. Download or favourite anything you want to keep first.',
warning: 'This is permanent. Download or favourite anything you want to keep before continuing.',
confirmCta: 'Delete {{count}} archive(s)',
purging: 'Deleting…',
toast: {
@@ -5250,9 +5260,9 @@ export default {
},
archiveAutoPurge: {
enableLabel: 'Auto-purge old archives',
enableDescription: 'Once per day, permanently deletes archives older than the threshold. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives older than',
ageDescription: 'Minimum 7 days, maximum 10 years. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
enableDescription: 'Once per day, permanently deletes archives that have not been printed within the threshold. Reprinting an archive resets the clock. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives not printed in the last',
ageDescription: 'Minimum 7 days, maximum 10 years. Based on the most recent print completion — reprinting an archive refreshes its age. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
days: 'days',
runNow: 'Purge archives now',
saveFailed: 'Could not save auto-purge settings.',
+16 -7
View File
@@ -5113,7 +5113,11 @@ export default {
ageLabel: 'Déplacer les fichiers plus anciens que',
days: 'jours',
includeNeverPrinted: 'Inclure les fichiers jamais imprimés',
previewLoading: 'Vérification du nombre de fichiers concernés…',
effectsTitle: 'What happens when you click Purge',
effect1: 'Matching files are moved to Trash — they are not deleted from disk yet.',
effect2: 'You can restore them from Trash at any time until the retention window expires.',
effect3: 'After retention, the trash sweeper permanently removes them from disk.',
effect4: 'Files in external (linked) folders are skipped — Bambuddy never deletes bytes it does not own.', previewLoading: 'Vérification du nombre de fichiers concernés…',
previewFailed: 'Impossible de prévisualiser la purge.',
previewSummary: '{{count}} fichiers · {{size}} seraient déplacés vers la corbeille',
andMore: '…et {{count}} de plus',
@@ -5138,14 +5142,19 @@ export default {
headerButton: 'Purge old',
headerTooltip: 'Bulk-delete old archives',
title: 'Purge old archives',
description: 'Archives older than the threshold will be permanently deleted along with their files, thumbnails, and timelapses. This cannot be undone.',
ageLabel: 'Delete archives older than',
description: 'Clear out old print history. Each archive is aged by its most recent print completion — reprinting an archive refreshes its age, so active work is never purged.',
ageLabel: 'Delete archives not printed in the last',
days: 'days',
effectsTitle: 'What happens when you click Purge',
effect1: 'Each matching archive is permanently removed from the database.',
effect2: 'The 3MF, thumbnail, timelapse, source 3MF, F3D design file, and photo folder are all deleted from disk.',
effect3: 'There is no trash bin for archives — deletion is immediate and cannot be undone.',
effect4: 'Reprinting an archive refreshes its age clock, so archives you still use are safe.',
previewLoading: 'Checking how many archives match…',
previewFailed: 'Could not preview the purge.',
previewSummary: '{{count}} archives · {{size}} would be deleted',
andMore: '…and {{count}} more',
warning: 'Archives are hard-deleted — there is no trash bin for archives. Download or favourite anything you want to keep first.',
warning: 'This is permanent. Download or favourite anything you want to keep before continuing.',
confirmCta: 'Delete {{count}} archive(s)',
purging: 'Deleting…',
toast: {
@@ -5155,9 +5164,9 @@ export default {
},
archiveAutoPurge: {
enableLabel: 'Auto-purge old archives',
enableDescription: 'Once per day, permanently deletes archives older than the threshold. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives older than',
ageDescription: 'Minimum 7 days, maximum 10 years. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
enableDescription: 'Once per day, permanently deletes archives that have not been printed within the threshold. Reprinting an archive resets the clock. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives not printed in the last',
ageDescription: 'Minimum 7 days, maximum 10 years. Based on the most recent print completion — reprinting an archive refreshes its age. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
days: 'days',
runNow: 'Purge archives now',
saveFailed: 'Could not save auto-purge settings.',
+16 -7
View File
@@ -5112,7 +5112,11 @@ export default {
ageLabel: 'Sposta i file più vecchi di',
days: 'giorni',
includeNeverPrinted: 'Includi i file mai stampati',
previewLoading: 'Verifica quanti file corrispondono…',
effectsTitle: 'What happens when you click Purge',
effect1: 'Matching files are moved to Trash — they are not deleted from disk yet.',
effect2: 'You can restore them from Trash at any time until the retention window expires.',
effect3: 'After retention, the trash sweeper permanently removes them from disk.',
effect4: 'Files in external (linked) folders are skipped — Bambuddy never deletes bytes it does not own.', previewLoading: 'Verifica quanti file corrispondono…',
previewFailed: 'Impossibile mostrare l\'anteprima.',
previewSummary: '{{count}} file · {{size}} verrebbero spostati nel cestino',
andMore: '…e altri {{count}}',
@@ -5137,14 +5141,19 @@ export default {
headerButton: 'Purge old',
headerTooltip: 'Bulk-delete old archives',
title: 'Purge old archives',
description: 'Archives older than the threshold will be permanently deleted along with their files, thumbnails, and timelapses. This cannot be undone.',
ageLabel: 'Delete archives older than',
description: 'Clear out old print history. Each archive is aged by its most recent print completion — reprinting an archive refreshes its age, so active work is never purged.',
ageLabel: 'Delete archives not printed in the last',
days: 'days',
effectsTitle: 'What happens when you click Purge',
effect1: 'Each matching archive is permanently removed from the database.',
effect2: 'The 3MF, thumbnail, timelapse, source 3MF, F3D design file, and photo folder are all deleted from disk.',
effect3: 'There is no trash bin for archives — deletion is immediate and cannot be undone.',
effect4: 'Reprinting an archive refreshes its age clock, so archives you still use are safe.',
previewLoading: 'Checking how many archives match…',
previewFailed: 'Could not preview the purge.',
previewSummary: '{{count}} archives · {{size}} would be deleted',
andMore: '…and {{count}} more',
warning: 'Archives are hard-deleted — there is no trash bin for archives. Download or favourite anything you want to keep first.',
warning: 'This is permanent. Download or favourite anything you want to keep before continuing.',
confirmCta: 'Delete {{count}} archive(s)',
purging: 'Deleting…',
toast: {
@@ -5154,9 +5163,9 @@ export default {
},
archiveAutoPurge: {
enableLabel: 'Auto-purge old archives',
enableDescription: 'Once per day, permanently deletes archives older than the threshold. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives older than',
ageDescription: 'Minimum 7 days, maximum 10 years. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
enableDescription: 'Once per day, permanently deletes archives that have not been printed within the threshold. Reprinting an archive resets the clock. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives not printed in the last',
ageDescription: 'Minimum 7 days, maximum 10 years. Based on the most recent print completion — reprinting an archive refreshes its age. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
days: 'days',
runNow: 'Purge archives now',
saveFailed: 'Could not save auto-purge settings.',
+16 -7
View File
@@ -5151,7 +5151,11 @@ export default {
ageLabel: '次より古いファイルを移動',
days: '日',
includeNeverPrinted: '一度も印刷していないファイルも含める',
previewLoading: '対象ファイル数を確認中…',
effectsTitle: 'What happens when you click Purge',
effect1: 'Matching files are moved to Trash — they are not deleted from disk yet.',
effect2: 'You can restore them from Trash at any time until the retention window expires.',
effect3: 'After retention, the trash sweeper permanently removes them from disk.',
effect4: 'Files in external (linked) folders are skipped — Bambuddy never deletes bytes it does not own.', previewLoading: '対象ファイル数を確認中…',
previewFailed: 'プレビューを取得できませんでした。',
previewSummary: '{{count}} 件 · {{size}} がゴミ箱に移動されます',
andMore: '…ほか {{count}} 件',
@@ -5176,14 +5180,19 @@ export default {
headerButton: 'Purge old',
headerTooltip: 'Bulk-delete old archives',
title: 'Purge old archives',
description: 'Archives older than the threshold will be permanently deleted along with their files, thumbnails, and timelapses. This cannot be undone.',
ageLabel: 'Delete archives older than',
description: 'Clear out old print history. Each archive is aged by its most recent print completion — reprinting an archive refreshes its age, so active work is never purged.',
ageLabel: 'Delete archives not printed in the last',
days: 'days',
effectsTitle: 'What happens when you click Purge',
effect1: 'Each matching archive is permanently removed from the database.',
effect2: 'The 3MF, thumbnail, timelapse, source 3MF, F3D design file, and photo folder are all deleted from disk.',
effect3: 'There is no trash bin for archives — deletion is immediate and cannot be undone.',
effect4: 'Reprinting an archive refreshes its age clock, so archives you still use are safe.',
previewLoading: 'Checking how many archives match…',
previewFailed: 'Could not preview the purge.',
previewSummary: '{{count}} archives · {{size}} would be deleted',
andMore: '…and {{count}} more',
warning: 'Archives are hard-deleted — there is no trash bin for archives. Download or favourite anything you want to keep first.',
warning: 'This is permanent. Download or favourite anything you want to keep before continuing.',
confirmCta: 'Delete {{count}} archive(s)',
purging: 'Deleting…',
toast: {
@@ -5193,9 +5202,9 @@ export default {
},
archiveAutoPurge: {
enableLabel: 'Auto-purge old archives',
enableDescription: 'Once per day, permanently deletes archives older than the threshold. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives older than',
ageDescription: 'Minimum 7 days, maximum 10 years. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
enableDescription: 'Once per day, permanently deletes archives that have not been printed within the threshold. Reprinting an archive resets the clock. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives not printed in the last',
ageDescription: 'Minimum 7 days, maximum 10 years. Based on the most recent print completion — reprinting an archive refreshes its age. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
days: 'days',
runNow: 'Purge archives now',
saveFailed: 'Could not save auto-purge settings.',
+16 -7
View File
@@ -5126,7 +5126,11 @@ export default {
ageLabel: 'Mover arquivos mais antigos que',
days: 'dias',
includeNeverPrinted: 'Incluir arquivos que nunca foram impressos',
previewLoading: 'Verificando quantos arquivos correspondem…',
effectsTitle: 'What happens when you click Purge',
effect1: 'Matching files are moved to Trash — they are not deleted from disk yet.',
effect2: 'You can restore them from Trash at any time until the retention window expires.',
effect3: 'After retention, the trash sweeper permanently removes them from disk.',
effect4: 'Files in external (linked) folders are skipped — Bambuddy never deletes bytes it does not own.', previewLoading: 'Verificando quantos arquivos correspondem…',
previewFailed: 'Não foi possível pré-visualizar a limpeza.',
previewSummary: '{{count}} arquivos · {{size}} seriam movidos para a lixeira',
andMore: '…e mais {{count}}',
@@ -5151,14 +5155,19 @@ export default {
headerButton: 'Purge old',
headerTooltip: 'Bulk-delete old archives',
title: 'Purge old archives',
description: 'Archives older than the threshold will be permanently deleted along with their files, thumbnails, and timelapses. This cannot be undone.',
ageLabel: 'Delete archives older than',
description: 'Clear out old print history. Each archive is aged by its most recent print completion — reprinting an archive refreshes its age, so active work is never purged.',
ageLabel: 'Delete archives not printed in the last',
days: 'days',
effectsTitle: 'What happens when you click Purge',
effect1: 'Each matching archive is permanently removed from the database.',
effect2: 'The 3MF, thumbnail, timelapse, source 3MF, F3D design file, and photo folder are all deleted from disk.',
effect3: 'There is no trash bin for archives — deletion is immediate and cannot be undone.',
effect4: 'Reprinting an archive refreshes its age clock, so archives you still use are safe.',
previewLoading: 'Checking how many archives match…',
previewFailed: 'Could not preview the purge.',
previewSummary: '{{count}} archives · {{size}} would be deleted',
andMore: '…and {{count}} more',
warning: 'Archives are hard-deleted — there is no trash bin for archives. Download or favourite anything you want to keep first.',
warning: 'This is permanent. Download or favourite anything you want to keep before continuing.',
confirmCta: 'Delete {{count}} archive(s)',
purging: 'Deleting…',
toast: {
@@ -5168,9 +5177,9 @@ export default {
},
archiveAutoPurge: {
enableLabel: 'Auto-purge old archives',
enableDescription: 'Once per day, permanently deletes archives older than the threshold. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives older than',
ageDescription: 'Minimum 7 days, maximum 10 years. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
enableDescription: 'Once per day, permanently deletes archives that have not been printed within the threshold. Reprinting an archive resets the clock. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives not printed in the last',
ageDescription: 'Minimum 7 days, maximum 10 years. Based on the most recent print completion — reprinting an archive refreshes its age. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
days: 'days',
runNow: 'Purge archives now',
saveFailed: 'Could not save auto-purge settings.',
+16 -7
View File
@@ -5190,7 +5190,11 @@ export default {
ageLabel: '移动早于以下天数的文件',
days: '天',
includeNeverPrinted: '包括从未打印过的文件',
previewLoading: '正在检查匹配的文件数量…',
effectsTitle: 'What happens when you click Purge',
effect1: 'Matching files are moved to Trash — they are not deleted from disk yet.',
effect2: 'You can restore them from Trash at any time until the retention window expires.',
effect3: 'After retention, the trash sweeper permanently removes them from disk.',
effect4: 'Files in external (linked) folders are skipped — Bambuddy never deletes bytes it does not own.', previewLoading: '正在检查匹配的文件数量…',
previewFailed: '无法预览清理结果。',
previewSummary: '{{count}} 个文件 · {{size}} 将被移至回收站',
andMore: '…还有 {{count}} 个',
@@ -5215,14 +5219,19 @@ export default {
headerButton: 'Purge old',
headerTooltip: 'Bulk-delete old archives',
title: 'Purge old archives',
description: 'Archives older than the threshold will be permanently deleted along with their files, thumbnails, and timelapses. This cannot be undone.',
ageLabel: 'Delete archives older than',
description: 'Clear out old print history. Each archive is aged by its most recent print completion — reprinting an archive refreshes its age, so active work is never purged.',
ageLabel: 'Delete archives not printed in the last',
days: 'days',
effectsTitle: 'What happens when you click Purge',
effect1: 'Each matching archive is permanently removed from the database.',
effect2: 'The 3MF, thumbnail, timelapse, source 3MF, F3D design file, and photo folder are all deleted from disk.',
effect3: 'There is no trash bin for archives — deletion is immediate and cannot be undone.',
effect4: 'Reprinting an archive refreshes its age clock, so archives you still use are safe.',
previewLoading: 'Checking how many archives match…',
previewFailed: 'Could not preview the purge.',
previewSummary: '{{count}} archives · {{size}} would be deleted',
andMore: '…and {{count}} more',
warning: 'Archives are hard-deleted — there is no trash bin for archives. Download or favourite anything you want to keep first.',
warning: 'This is permanent. Download or favourite anything you want to keep before continuing.',
confirmCta: 'Delete {{count}} archive(s)',
purging: 'Deleting…',
toast: {
@@ -5232,9 +5241,9 @@ export default {
},
archiveAutoPurge: {
enableLabel: 'Auto-purge old archives',
enableDescription: 'Once per day, permanently deletes archives older than the threshold. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives older than',
ageDescription: 'Minimum 7 days, maximum 10 years. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
enableDescription: 'Once per day, permanently deletes archives that have not been printed within the threshold. Reprinting an archive resets the clock. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives not printed in the last',
ageDescription: 'Minimum 7 days, maximum 10 years. Based on the most recent print completion — reprinting an archive refreshes its age. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
days: 'days',
runNow: 'Purge archives now',
saveFailed: 'Could not save auto-purge settings.',
+16 -7
View File
@@ -5190,7 +5190,11 @@ export default {
ageLabel: '移動早於以下天數的檔案',
days: '天',
includeNeverPrinted: '包括從未列印過的檔案',
previewLoading: '正在檢查符合的檔案數量…',
effectsTitle: 'What happens when you click Purge',
effect1: 'Matching files are moved to Trash — they are not deleted from disk yet.',
effect2: 'You can restore them from Trash at any time until the retention window expires.',
effect3: 'After retention, the trash sweeper permanently removes them from disk.',
effect4: 'Files in external (linked) folders are skipped — Bambuddy never deletes bytes it does not own.', previewLoading: '正在檢查符合的檔案數量…',
previewFailed: '無法預覽清理結果。',
previewSummary: '{{count}} 個檔案 · {{size}} 將被移至資源回收筒',
andMore: '…還有 {{count}} 個',
@@ -5215,14 +5219,19 @@ export default {
headerButton: 'Purge old',
headerTooltip: 'Bulk-delete old archives',
title: 'Purge old archives',
description: 'Archives older than the threshold will be permanently deleted along with their files, thumbnails, and timelapses. This cannot be undone.',
ageLabel: 'Delete archives older than',
description: 'Clear out old print history. Each archive is aged by its most recent print completion — reprinting an archive refreshes its age, so active work is never purged.',
ageLabel: 'Delete archives not printed in the last',
days: 'days',
effectsTitle: 'What happens when you click Purge',
effect1: 'Each matching archive is permanently removed from the database.',
effect2: 'The 3MF, thumbnail, timelapse, source 3MF, F3D design file, and photo folder are all deleted from disk.',
effect3: 'There is no trash bin for archives — deletion is immediate and cannot be undone.',
effect4: 'Reprinting an archive refreshes its age clock, so archives you still use are safe.',
previewLoading: 'Checking how many archives match…',
previewFailed: 'Could not preview the purge.',
previewSummary: '{{count}} archives · {{size}} would be deleted',
andMore: '…and {{count}} more',
warning: 'Archives are hard-deleted — there is no trash bin for archives. Download or favourite anything you want to keep first.',
warning: 'This is permanent. Download or favourite anything you want to keep before continuing.',
confirmCta: 'Delete {{count}} archive(s)',
purging: 'Deleting…',
toast: {
@@ -5232,9 +5241,9 @@ export default {
},
archiveAutoPurge: {
enableLabel: 'Auto-purge old archives',
enableDescription: 'Once per day, permanently deletes archives older than the threshold. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives older than',
ageDescription: 'Minimum 7 days, maximum 10 years. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
enableDescription: 'Once per day, permanently deletes archives that have not been printed within the threshold. Reprinting an archive resets the clock. No trash bin — deletion is immediate.',
ageLabel: 'Auto-delete archives not printed in the last',
ageDescription: 'Minimum 7 days, maximum 10 years. Based on the most recent print completion — reprinting an archive refreshes its age. Deletes the archive, 3MF, thumbnail, timelapse, and photos.',
days: 'days',
runNow: 'Purge archives now',
saveFailed: 'Could not save auto-purge settings.',