import { translate } from '../utils/i18nHelpers.js'; /** * Escape HTML entities in a string to prevent injection when interpolating into innerHTML. * @param {string} str - The string to escape * @returns {string} - The escaped string */ function _escapeHtml(str) { if (str === null || str === undefined) return ''; const div = document.createElement('div'); div.textContent = String(str); return div.innerHTML.replace(/"/g, '"').replace(/'/g, '''); } /** * Show the sidecar migration summary modal after a migration completes. * Mirrors the Metadata Fetch Summary / Batch Download Summary lifecycle: the * modal element is appended directly to document.body and removed on close; * it is not registered with ModalManager. * @param {Object} options - Summary options * @param {Object} options.result - Migration result payload from /api/lm/sidecars/migrate * @param {Function} options.onClose - Callback invoked after the modal is dismissed * @param {Function} [options.onOpenLocation] - Callback for the "Open Folder" action; the modal stays open */ export function showSidecarMigrationSummary({ result, onClose, onOpenLocation }) { const errorCount = result.error_count || 0; const errors = Array.isArray(result.errors) ? result.errors : []; const moved = result.moved || 0; const modelsMoved = result.models_moved || 0; const modelsTotal = result.models_total || 0; const skipped = result.skipped || 0; const conflicts = result.conflicts || 0; const showLocation = result.direction !== 'to_alongside' && !!result.sidecar_root; // 3-state summary header semantics (mirrors DownloadBatchSummaryModal) let headerState; let headerIcon; let headerText; if (errorCount > 0) { headerState = 'warning'; headerIcon = 'fa-exclamation-circle'; headerText = translate('modals.sidecarMigrationResult.completedWithErrors', { count: errorCount }, 'Completed with ' + errorCount + ' error(s)'); } else { headerState = 'success'; headerIcon = 'fa-check-circle'; headerText = translate('modals.sidecarMigrationResult.completedSuccessfully', {}, 'Migration completed successfully'); } const failureRows = errors.map((entry, i) => { const name = entry?.model || 'Unknown'; const error = entry?.error ? String(entry.error) : 'Unknown error'; return `