u
This commit is contained in:
@@ -70,8 +70,9 @@ const EXPORT_OPTIONS = [
|
||||
id: 'company',
|
||||
label: 'Gesamtsicherung / Mandant (ZIP)',
|
||||
desc: 'Vollständiger Datenbestand (Artikel, Kategorien, Kunden, Belege und Medien).',
|
||||
endpoint: '/api/company/export.zip',
|
||||
endpoint: '/api/company/export',
|
||||
defaultFilename: 'mandant-gesamtsicherung.zip',
|
||||
isSse: true,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -83,6 +84,7 @@ export default class ImportExportSettingsPanel extends Component {
|
||||
exportType: 'articles',
|
||||
downloading: false,
|
||||
downloadProgress: null, // null = unknown, number 0-100
|
||||
downloadStatus: null,
|
||||
downloadLoaded: 0,
|
||||
downloadTotal: 0,
|
||||
downloadError: null,
|
||||
@@ -138,6 +140,45 @@ export default class ImportExportSettingsPanel extends Component {
|
||||
|
||||
this.abortController = new AbortController();
|
||||
|
||||
if (option.isSse || option.id === 'company') {
|
||||
try {
|
||||
await company.exportCatalog(
|
||||
{
|
||||
onStatus: (message) => {
|
||||
this.setState({ downloadStatus: message });
|
||||
},
|
||||
onProgress: (progress) => {
|
||||
const percent = typeof progress?.percent === 'number' ? progress.percent : null;
|
||||
const stage = progress?.stage;
|
||||
this.setState((prev) => ({
|
||||
downloadProgress: percent ?? prev.downloadProgress,
|
||||
downloadStatus: stage
|
||||
? `Verarbeite ${stage} (${percent != null ? `${percent}%` : '...'})`
|
||||
: prev.downloadStatus,
|
||||
}));
|
||||
},
|
||||
onError: (errMessage) => {
|
||||
this.setState({ downloadError: errMessage });
|
||||
},
|
||||
},
|
||||
{ signal: this.abortController.signal, triggerDownload: true }
|
||||
);
|
||||
|
||||
enqueueSnackbar(`${option.label} erfolgreich heruntergeladen.`, { variant: 'success' });
|
||||
this.setState({ downloading: false, downloadProgress: 100, downloadStatus: null });
|
||||
} catch (err) {
|
||||
if (err.name === 'AbortError') {
|
||||
enqueueSnackbar('Download abgebrochen.', { variant: 'info' });
|
||||
} else {
|
||||
this.setState({ downloadError: err.message || String(err) });
|
||||
}
|
||||
} finally {
|
||||
this.setState({ downloading: false });
|
||||
this.abortController = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(option.endpoint, {
|
||||
method: 'GET',
|
||||
@@ -354,6 +395,7 @@ export default class ImportExportSettingsPanel extends Component {
|
||||
exportType,
|
||||
downloading,
|
||||
downloadProgress,
|
||||
downloadStatus,
|
||||
downloadLoaded,
|
||||
downloadTotal,
|
||||
downloadError,
|
||||
@@ -454,7 +496,9 @@ export default class ImportExportSettingsPanel extends Component {
|
||||
<Box sx={{ mb: 2, p: 1.5, bgcolor: 'action.hover', borderRadius: 1.5 }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', mb: 0.5 }}>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
{downloadProgress != null
|
||||
{downloadStatus
|
||||
? (downloadProgress != null ? `${downloadStatus} (${downloadProgress}%)` : downloadStatus)
|
||||
: downloadProgress != null
|
||||
? `${downloadProgress}% (${formatBytes(downloadLoaded)} von ${formatBytes(downloadTotal)})`
|
||||
: `${formatBytes(downloadLoaded)} geladen (wird gestreamt...)`}
|
||||
</Typography>
|
||||
|
||||
Reference in New Issue
Block a user