(function () { document.documentElement.classList.remove('oo-open'); var emptyLabel = 'или перетащите сюда / в список'; function dropRoot(el) { return el && el.closest ? el.closest('.nc-drop') : null; } function browserDropRoot(el) { return el && el.closest ? el.closest('.nc-browser-drop[data-nc-upload="1"]') : null; } function findUploadForm(fromEl) { var browser = browserDropRoot(fromEl); if (browser) { var f = browser.querySelector('form.nc-drop'); if (f) return f; } return dropRoot(fromEl); } function uploadFilesViaForm(form, fileList) { if (!form || !fileList || !fileList.length) return; var files = Array.prototype.slice.call(fileList); var url = form.getAttribute('hx-post') || form.getAttribute('action'); var targetSel = form.getAttribute('hx-target') || '#documents-browser'; var swap = form.getAttribute('hx-swap') || 'innerHTML'; function next() { if (!files.length) return; var file = files.shift(); var fd = new FormData(form); fd.set('file', file, file.name); fetch(url, { method: 'POST', body: fd, credentials: 'same-origin', headers: { 'HX-Request': 'true' }, }).then(function (r) { return r.text().then(function (html) { var target = document.querySelector(targetSel); if (target) { if (typeof htmx !== 'undefined' && htmx.swap) { htmx.swap(target, html, { swapStyle: swap }); } else { target.innerHTML = html; } // после swap форма пересоздана — продолжаем очередь form = target.querySelector('form.nc-drop') || form; } if (files.length) next(); }); }).catch(function () { /* ignore */ }); } next(); } document.addEventListener('change', function (e) { if (!e.target || !e.target.classList.contains('nc-drop-input')) return; var drop = dropRoot(e.target); var nameEl = drop && drop.querySelector('.nc-drop-name'); if (!nameEl) return; var files = e.target.files; if (!files || !files.length) { nameEl.textContent = emptyLabel; return; } nameEl.textContent = files.length === 1 ? files[0].name : (files.length + ' файлов'); }); document.addEventListener('dragover', function (e) { var zone = browserDropRoot(e.target) || dropRoot(e.target); if (!zone) return; e.preventDefault(); e.dataTransfer.dropEffect = 'copy'; zone.classList.add('is-drag'); }); document.addEventListener('dragleave', function (e) { var zone = browserDropRoot(e.target) || dropRoot(e.target); if (!zone) return; if (e.relatedTarget && zone.contains(e.relatedTarget)) return; zone.classList.remove('is-drag'); }); document.addEventListener('drop', function (e) { var browser = browserDropRoot(e.target); var drop = dropRoot(e.target); var zone = browser || drop; if (!zone) return; e.preventDefault(); zone.classList.remove('is-drag'); if (!e.dataTransfer || !e.dataTransfer.files.length) return; var form = findUploadForm(e.target); if (!form) return; // автозагрузка сразу (без кнопки «Загрузить») uploadFilesViaForm(form, e.dataTransfer.files); }); // Несколько файлов через кнопку «Загрузить» — по одному, как при DnD document.addEventListener('submit', function (e) { var form = e.target; if (!form || !form.classList || !form.classList.contains('nc-drop')) return; var input = form.querySelector('.nc-drop-input'); if (!input || !input.files || input.files.length <= 1) return; e.preventDefault(); uploadFilesViaForm(form, input.files); }, true); document.addEventListener('htmx:afterSwap', function (e) { if (!e.detail || !e.detail.target || e.detail.target.id !== 'main-content') return; document.documentElement.classList.remove('oo-open'); }); // ── Модальный предпросмотр PDF / изображений ─────────────────────────── function ensurePreviewModal() { var existing = document.getElementById('doc-preview-modal'); if (existing) return existing; var overlay = document.createElement('div'); overlay.id = 'doc-preview-overlay'; overlay.className = 'doc-preview-overlay'; overlay.style.display = 'none'; overlay.addEventListener('click', docPreviewClose); var modal = document.createElement('div'); modal.id = 'doc-preview-modal'; modal.className = 'doc-preview-modal'; modal.setAttribute('role', 'dialog'); modal.setAttribute('aria-modal', 'true'); modal.style.display = 'none'; modal.addEventListener('click', docPreviewClose); modal.innerHTML = '
' + '
' + '
' + ' ' + '
' + '
' + '
'; document.body.appendChild(overlay); document.body.appendChild(modal); document.getElementById('doc-preview-close').addEventListener('click', docPreviewClose); return modal; } function downloadUrlFromInline(url) { try { var u = new URL(url, window.location.origin); u.searchParams.delete('inline'); return u.pathname + u.search; } catch (err) { return String(url || '').replace(/([?&])inline=1(&|$)/, function (_, a, b) { return a === '?' && b === '&' ? '?' : (b === '&' ? a : ''); }); } } window.docPreviewOpen = function (elOrUrl, title, kind) { var url, name, previewKind; if (typeof elOrUrl === 'string') { url = elOrUrl; name = title || ''; previewKind = kind || 'image'; } else if (elOrUrl && elOrUrl.getAttribute) { url = elOrUrl.getAttribute('href') || ''; name = elOrUrl.getAttribute('data-doc-title') || elOrUrl.textContent || ''; previewKind = elOrUrl.getAttribute('data-doc-kind') || 'image'; } else { return false; } if (!url) return false; ensurePreviewModal(); var overlay = document.getElementById('doc-preview-overlay'); var modal = document.getElementById('doc-preview-modal'); var body = document.getElementById('doc-preview-body'); var titleEl = document.getElementById('doc-preview-title'); var dl = document.getElementById('doc-preview-download'); var full = document.getElementById('doc-preview-full'); if (titleEl) { titleEl.textContent = name; titleEl.title = name; } if (dl) { dl.href = downloadUrlFromInline(url); dl.setAttribute('download', name || ''); } if (full) { var fullHref = (elOrUrl && elOrUrl.getAttribute && elOrUrl.getAttribute('data-doc-full')) || url; full.href = fullHref; } body.innerHTML = ''; if (previewKind === 'pdf') { var frame = document.createElement('iframe'); frame.className = 'doc-preview-dialog-frame'; frame.title = name || 'PDF'; frame.src = url; body.appendChild(frame); } else { var wrap = document.createElement('div'); wrap.className = 'doc-preview-dialog-image-wrap'; var img = document.createElement('img'); img.className = 'doc-preview-dialog-image'; img.alt = name || ''; img.src = url; wrap.appendChild(img); body.appendChild(wrap); } overlay.style.display = 'block'; modal.style.display = 'flex'; document.body.style.overflow = 'hidden'; return false; }; window.docPreviewClose = function () { var overlay = document.getElementById('doc-preview-overlay'); var modal = document.getElementById('doc-preview-modal'); var body = document.getElementById('doc-preview-body'); if (overlay) overlay.style.display = 'none'; if (modal) modal.style.display = 'none'; if (body) body.innerHTML = ''; document.body.style.overflow = ''; }; document.addEventListener('keydown', function (ev) { if (ev.key !== 'Escape') return; var modal = document.getElementById('doc-preview-modal'); if (modal && modal.style.display === 'flex') docPreviewClose(); }); })();