(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 = '