diff --git a/client/src/App.vue b/client/src/App.vue index 712b802..6c80a96 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -2381,17 +2381,35 @@ async function openVCenterImport() { async function previewVCenterImport(payload) { vcenterImportLoading.value = true; vcenterImportError.value = ''; + vcenterTraceEntries.value = [{ + info: true, + message: 'vCenter preview request is running.', + details: { + filter: payload.filter, + limit: payload.limit, + startedAt: new Date().toISOString() + } + }]; + vcenterTraceOpen.value = true; try { const result = await api.post('/api/hosts/import/vcenter/preview', payload); vcenterImportStatus.value = result.status; vcenterImportDiagnostics.value = result.diagnostics || null; - vcenterTraceEntries.value = result.trace || []; + vcenterTraceEntries.value = result.trace?.length ? result.trace : [{ + info: true, + message: 'Preview completed, but the API returned no trace entries.', + details: { count: result.count || 0, diagnostics: result.diagnostics || null } + }]; vcenterPreviewRows.value = result.candidates || []; - if (vcenterTraceEntries.value.length) vcenterTraceOpen.value = true; + vcenterTraceOpen.value = true; notify(`Found ${result.count || 0} vCenter host candidate(s) from ${result.diagnostics?.totalFromVCenter ?? 'unknown'} VM(s)`); } catch (err) { - vcenterTraceEntries.value = err.payload?.trace || []; - if (vcenterTraceEntries.value.length) vcenterTraceOpen.value = true; + vcenterTraceEntries.value = err.payload?.trace?.length ? err.payload.trace : [{ + info: true, + message: 'Preview failed before a vCenter HTTP trace could be captured.', + details: { error: err.message, status: err.status || null } + }]; + vcenterTraceOpen.value = true; vcenterImportError.value = err.message; notify(err.message, 'error'); } finally { @@ -2402,9 +2420,15 @@ async function previewVCenterImport(payload) { async function importVCenterHosts(payload) { vcenterImportLoading.value = true; vcenterImportError.value = ''; + vcenterTraceEntries.value = [{ + info: true, + message: 'vCenter import request is running.', + details: { vmIds: payload.vmIds, startedAt: new Date().toISOString() } + }]; + vcenterTraceOpen.value = true; try { const result = await api.post('/api/hosts/import/vcenter', payload); - vcenterTraceEntries.value = result.trace || vcenterTraceEntries.value; + vcenterTraceEntries.value = result.trace?.length ? result.trace : vcenterTraceEntries.value; await refreshAll(); vcenterPreviewRows.value = []; vcenterImportDiagnostics.value = null; @@ -2413,8 +2437,12 @@ async function importVCenterHosts(payload) { const skipped = result.skipped?.length || 0; notify(`Imported ${result.imported?.length || 0} host(s)${skipped ? `, skipped ${skipped} duplicate(s)` : ''}`); } catch (err) { - vcenterTraceEntries.value = err.payload?.trace || []; - if (vcenterTraceEntries.value.length) vcenterTraceOpen.value = true; + vcenterTraceEntries.value = err.payload?.trace?.length ? err.payload.trace : [{ + info: true, + message: 'Import failed before a vCenter HTTP trace could be captured.', + details: { error: err.message, status: err.status || null } + }]; + vcenterTraceOpen.value = true; vcenterImportError.value = err.message; notify(err.message, 'error'); } finally { diff --git a/client/src/style.css b/client/src/style.css index 34c6f45..92c136e 100644 --- a/client/src/style.css +++ b/client/src/style.css @@ -6212,6 +6212,10 @@ input:read-only { animation: modalBackdropIn .18s ease both; } +.modal-backdrop:has(.vcenter-trace-modal) { + z-index: 120; +} + .form-modal { background: linear-gradient(145deg, rgba(25, 29, 63, .995), rgba(5, 13, 32, .995));