add missing translation for export

This commit is contained in:
2026-05-12 19:26:18 +02:00
parent 56339222e7
commit 35d2d0a8d3
6 changed files with 74 additions and 10 deletions

View File

@@ -1402,8 +1402,10 @@
const exportProgressContainer = document.getElementById('export-progress-container');
const exportProgressBar = document.getElementById('export-progress-bar');
const exportStatusText = document.getElementById('export-status-text');
const exportStatusMsg = document.getElementById('export-status-msg');
const chkExportUploads = document.getElementById('export_uploads');
const chkExportFavorites = document.getElementById('export_favorites');
const exportAnimatedDots = document.getElementById('export-animated-dots');
if (btnStartExport) {
btnStartExport.addEventListener('click', async () => {
@@ -1411,14 +1413,14 @@
const exportFavorites = chkExportFavorites.checked;
if (!exportUploads && !exportFavorites) {
alert('Please select at least one option to export.');
alert(exportStatusText.dataset.selectOption || 'Please select at least one option to export.');
return;
}
btnStartExport.disabled = true;
exportProgressContainer.style.display = 'block';
exportProgressBar.style.width = '0%';
exportStatusText.textContent = 'Fetching data list...';
exportStatusMsg.textContent = exportStatusText.dataset.fetching || 'Fetching data list...';
try {
const res = await fetch('/settings/export-data');
@@ -1433,7 +1435,7 @@
}
if (filesToDownload.length === 0) {
alert('No data found to export.');
alert(exportStatusText.dataset.noData || 'No data found to export.');
btnStartExport.disabled = false;
exportProgressContainer.style.display = 'none';
return;
@@ -1463,7 +1465,10 @@
completed++;
const percent = Math.round((completed / total) * 100);
exportProgressBar.style.width = percent + '%';
exportStatusText.textContent = `Processing files: ${completed} / ${total}`;
const msg = (exportStatusText.dataset.processing || 'Processing files: {completed} / {total}')
.replace('{completed}', completed)
.replace('{total}', total);
exportStatusMsg.textContent = msg;
return;
}
@@ -1478,7 +1483,10 @@
completed++;
const percent = Math.round((completed / total) * 100);
exportProgressBar.style.width = percent + '%';
exportStatusText.textContent = `Processing files: ${completed} / ${total}`;
const msg = (exportStatusText.dataset.processing || 'Processing files: {completed} / {total}')
.replace('{completed}', completed)
.replace('{total}', total);
exportStatusMsg.textContent = msg;
}
};
@@ -1489,7 +1497,8 @@
await Promise.all(batch.map(downloadFile));
}
exportStatusText.textContent = 'Generating ZIP file...';
exportStatusMsg.textContent = exportStatusText.dataset.generating || 'Generating ZIP file';
exportAnimatedDots.style.display = 'inline';
const content = await new Promise((resolve, reject) => {
const chunks = [];
zip.generateInternalStream({ type: 'uint8array', compression: 'DEFLATE', compressionOptions: { level: 6 } })
@@ -1504,6 +1513,7 @@
})
.resume();
});
exportAnimatedDots.style.display = 'none';
const link = document.createElement('a');
link.href = URL.createObjectURL(content);
@@ -1512,13 +1522,13 @@
link.click();
document.body.removeChild(link);
exportStatusText.textContent = 'Export complete!';
exportStatusMsg.textContent = exportStatusText.dataset.complete || 'Export complete!';
btnStartExport.disabled = false;
} catch (err) {
console.error('Export failed:', err);
alert('Export failed. See console for details.');
alert(exportStatusText.dataset.failedAlert || 'Export failed. See console for details.');
btnStartExport.disabled = false;
exportStatusText.textContent = 'Export failed.';
exportStatusMsg.textContent = exportStatusText.dataset.failed || 'Export failed.';
}
});
}

View File

@@ -213,6 +213,14 @@
"export_uploads": "Meine Uploads",
"export_favorites": "Meine Favoriten",
"export_preparing": "Wird vorbereitet...",
"export_fetching_data": "Datenliste wird abgerufen...",
"export_processing_files": "Dateien werden verarbeitet: {completed} / {total}",
"export_generating_zip": "ZIP-Datei wird generiert",
"export_complete": "Export abgeschlossen!",
"export_failed": "Export fehlgeschlagen.",
"export_select_option": "Bitte wähle mindestens eine Option zum Exportieren aus.",
"export_no_data": "Keine Daten zum Exportieren gefunden.",
"export_failed_alert": "Export fehlgeschlagen. Details findest du in der Konsole.",
"start_export": "Export generieren (ZIP)"
},
"filter": {

View File

@@ -213,6 +213,14 @@
"export_uploads": "My Uploads",
"export_favorites": "My Favorites",
"export_preparing": "Preparing...",
"export_fetching_data": "Fetching data list...",
"export_processing_files": "Processing files: {completed} / {total}",
"export_generating_zip": "Generating ZIP file",
"export_complete": "Export complete!",
"export_failed": "Export failed.",
"export_select_option": "Please select at least one option to export.",
"export_no_data": "No data found to export.",
"export_failed_alert": "Export failed. See console for details.",
"start_export": "Generate Export (ZIP)"
},
"filter": {

View File

@@ -213,6 +213,14 @@
"export_uploads": "Jouw uploads",
"export_favorites": "Jouw favorieten",
"export_preparing": "Voorbereiden...",
"export_fetching_data": "Gegevenslijst ophalen...",
"export_processing_files": "Bestanden verwerken: {completed} / {total}",
"export_generating_zip": "ZIP-bestand genereren",
"export_complete": "Export voltooid!",
"export_failed": "Export mislukt.",
"export_select_option": "Selecteer ten minste één optie om te exporteren.",
"export_no_data": "Geen gegevens gevonden om te exporteren.",
"export_failed_alert": "Export mislukt. Zie console voor details.",
"start_export": "Export genereren (ZIP)"
},
"filter": {

View File

@@ -212,6 +212,14 @@
"export_uploads": "Meine Aufladungen",
"export_favorites": "Meine Favorisierungen",
"export_preparing": "Vorbereitung wird getroffen...",
"export_fetching_data": "Holt die ganze Liste...",
"export_processing_files": "Verpackt Dateien: {completed} / {total}",
"export_generating_zip": "Paket wird geschnürt...",
"export_complete": "Paket fertig!",
"export_failed": "Paket kaputt.",
"export_select_option": "Bitte wählen Sie etwas zum verpacken aus.",
"export_no_data": "Nix da zum verpacken.",
"export_failed_alert": "Auf dem Weg gestorben :(",
"start_export": "Paket schnüren"
},
"filter": {

View File

@@ -278,7 +278,17 @@
<div class="progress-bar-wrapper" style="height: 20px; background: rgba(255,255,255,0.1); border-radius: 10px; overflow: hidden; margin-bottom: 5px;">
<div id="export-progress-bar" style="height: 100%; width: 0%; background: var(--accent); transition: width 0.3s;"></div>
</div>
<div id="export-status-text" style="font-size: 0.9em; color: var(--text-muted);">{{ t('settings.export_preparing') || 'Preparing...' }}</div>
<div id="export-status-text"
style="font-size: 0.9em; color: var(--text-muted);"
data-fetching="{{ t('settings.export_fetching_data') }}"
data-processing="{{ t('settings.export_processing_files') }}"
data-generating="{{ t('settings.export_generating_zip') }}"
data-complete="{{ t('settings.export_complete') }}"
data-failed="{{ t('settings.export_failed') }}"
data-select-option="{{ t('settings.export_select_option') }}"
data-no-data="{{ t('settings.export_no_data') }}"
data-failed-alert="{{ t('settings.export_failed_alert') }}"
><span id="export-status-msg">{{ t('settings.export_preparing') || 'Preparing...' }}</span><span class="export-dots" id="export-animated-dots" style="display:none;"><span>.</span><span>.</span><span>.</span></span></div>
</div>
<button type="button" id="btn-start-export" class="button button-primary">
@@ -387,6 +397,18 @@
</div>
@endif
<style>
@keyframes exportDotBounce {
0%, 80%, 100% { transform: translateY(0); opacity: 0.3; }
40% { transform: translateY(-5px); opacity: 1; }
}
.export-dots span {
display: inline-block;
animation: exportDotBounce 1.2s infinite ease-in-out;
}
.export-dots span:nth-child(2) { animation-delay: 0.2s; }
.export-dots span:nth-child(3) { animation-delay: 0.4s; }
</style>
<script src="/s/js/jszip.min.js"></script>
<script src="/s/js/settings.js?v=@mtime(/public/s/js/settings.js)"></script>
</div>