fixed db stream upload
All checks were successful
Deploy Nyla Frontend to Production / deploy (push) Successful in 43s
All checks were successful
Deploy Nyla Frontend to Production / deploy (push) Successful in 43s
This commit is contained in:
parent
8d24d57719
commit
036e6a38db
1 changed files with 28 additions and 40 deletions
|
|
@ -957,24 +957,37 @@ const MigrationTab: React.FC = () => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Restore: Validate ---
|
// --- Restore: Validate (uploads file to server, streams to disk) ---
|
||||||
|
const importTokenRef = useRef('');
|
||||||
|
|
||||||
const _validateFile = async (file: File) => {
|
const _validateFile = async (file: File) => {
|
||||||
setValidating(true);
|
setValidating(true);
|
||||||
setValidation(null);
|
setValidation(null);
|
||||||
|
importTokenRef.current = '';
|
||||||
try {
|
try {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
const res = await api.post('/api/admin/database-health/migration/validate', formData, {
|
const res = await api.post('/api/admin/database-health/migration/upload-import', formData, {
|
||||||
headers: { 'Content-Type': 'multipart/form-data' },
|
headers: { 'Content-Type': 'multipart/form-data' },
|
||||||
|
timeout: 0,
|
||||||
|
});
|
||||||
|
importTokenRef.current = res.data.token || '';
|
||||||
|
setValidation({
|
||||||
|
valid: res.data.valid,
|
||||||
|
summary: (res.data.databases || []).map((d: any) => ({
|
||||||
|
database: d.database,
|
||||||
|
tableCount: d.tableCount,
|
||||||
|
recordCount: d.recordCount,
|
||||||
|
registered: true,
|
||||||
|
})),
|
||||||
|
warnings: res.data.warnings || [],
|
||||||
|
systemObjectsFound: res.data.systemObjectsFound || [],
|
||||||
});
|
});
|
||||||
setValidation(res.data);
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
const detail = err?.response?.data?.detail;
|
const detail = err?.response?.data?.detail;
|
||||||
setValidation({
|
setValidation({
|
||||||
valid: false,
|
valid: false, summary: [], systemObjectsFound: [],
|
||||||
summary: [],
|
warnings: [typeof detail === 'string' ? detail : t('Upload oder Validierung fehlgeschlagen')],
|
||||||
warnings: [typeof detail === 'string' ? detail : t('Validierung fehlgeschlagen')],
|
|
||||||
systemObjectsFound: [],
|
|
||||||
});
|
});
|
||||||
} finally {
|
} finally {
|
||||||
setValidating(false);
|
setValidating(false);
|
||||||
|
|
@ -989,7 +1002,7 @@ const MigrationTab: React.FC = () => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const _startImport = async () => {
|
const _startImport = async () => {
|
||||||
if (!uploadedFile || !validation?.valid) return;
|
if (!importTokenRef.current || !validation?.valid) return;
|
||||||
|
|
||||||
const modeLabel = importMode === 'replace'
|
const modeLabel = importMode === 'replace'
|
||||||
? t('Neu (Datenbank leeren und importieren)')
|
? t('Neu (Datenbank leeren und importieren)')
|
||||||
|
|
@ -1004,39 +1017,13 @@ const MigrationTab: React.FC = () => {
|
||||||
setImporting(true);
|
setImporting(true);
|
||||||
setImportLog([]);
|
setImportLog([]);
|
||||||
|
|
||||||
_addImportLog(t('Vorbereitung: Datei wird hochgeladen und validiert...'));
|
const token = importTokenRef.current;
|
||||||
|
const dbList = validation.summary.filter(s => s.registered);
|
||||||
let token = '';
|
const totalDbs = dbList.length;
|
||||||
let dbList: Array<{ database: string; tableCount: number; recordCount: number }> = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append('file', uploadedFile);
|
|
||||||
const prepRes = await api.post('/api/admin/database-health/migration/prepare-import', formData, {
|
|
||||||
headers: { 'Content-Type': 'multipart/form-data' },
|
|
||||||
});
|
|
||||||
token = prepRes.data.token;
|
|
||||||
dbList = prepRes.data.databases || [];
|
|
||||||
const warnings: string[] = prepRes.data.warnings || [];
|
|
||||||
for (const w of warnings) {
|
|
||||||
_addImportLog(t('Warnung: {msg}', { msg: w }), 'error');
|
|
||||||
}
|
|
||||||
_addImportLog(
|
|
||||||
t('Validierung OK: {count} Datenbanken bereit', { count: dbList.length }),
|
|
||||||
'success',
|
|
||||||
);
|
|
||||||
} catch (err: any) {
|
|
||||||
const detail = err?.response?.data?.detail;
|
|
||||||
const msg = typeof detail === 'string' ? detail : detail?.message || t('Vorbereitung fehlgeschlagen');
|
|
||||||
_addImportLog(msg, 'error');
|
|
||||||
toast.showError(msg);
|
|
||||||
setImporting(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let totalRecords = 0;
|
let totalRecords = 0;
|
||||||
let errors = 0;
|
let errors = 0;
|
||||||
const totalDbs = dbList.length;
|
|
||||||
|
_addImportLog(t('Import gestartet: {count} Datenbanken', { count: totalDbs }));
|
||||||
|
|
||||||
for (let i = 0; i < dbList.length; i++) {
|
for (let i = 0; i < dbList.length; i++) {
|
||||||
const dbInfo = dbList[i];
|
const dbInfo = dbList[i];
|
||||||
|
|
@ -1074,7 +1061,6 @@ const MigrationTab: React.FC = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up server-side cache
|
|
||||||
try { await api.post('/api/admin/database-health/migration/import-done', { token }); } catch { /* ignore */ }
|
try { await api.post('/api/admin/database-health/migration/import-done', { token }); } catch { /* ignore */ }
|
||||||
|
|
||||||
_addImportLog(
|
_addImportLog(
|
||||||
|
|
@ -1089,12 +1075,14 @@ const MigrationTab: React.FC = () => {
|
||||||
} else {
|
} else {
|
||||||
toast.showSuccess(t('{count} Datensaetze erfolgreich importiert', { count: totalRecords }));
|
toast.showSuccess(t('{count} Datensaetze erfolgreich importiert', { count: totalRecords }));
|
||||||
}
|
}
|
||||||
|
importTokenRef.current = '';
|
||||||
setImporting(false);
|
setImporting(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const _resetUpload = () => {
|
const _resetUpload = () => {
|
||||||
setUploadedFile(null);
|
setUploadedFile(null);
|
||||||
setValidation(null);
|
setValidation(null);
|
||||||
|
importTokenRef.current = '';
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue