* JavaScript for FileArchiv Document Browser */ if (!defined('NOTOKENRENEWAL')) { define('NOTOKENRENEWAL', '1'); } if (!defined('NOLOGIN')) { define('NOLOGIN', '1'); } if (!defined('NOCSRFCHECK')) { define('NOCSRFCHECK', '1'); } // Load Dolibarr environment for translations $res = 0; if (!$res && file_exists("../../main.inc.php")) { $res = @include "../../main.inc.php"; } if (!$res && file_exists("../../../main.inc.php")) { $res = @include "../../../main.inc.php"; } if (!$res && file_exists("../../../../main.inc.php")) { $res = @include "../../../../main.inc.php"; } header('Content-Type: application/javascript; charset=UTF-8'); // Load translations $langs->load('filearchiv@filearchiv'); $ajaxUrl = dol_buildpath('/filearchiv/ajax/getdocuments.php', 1); $addFileUrl = dol_buildpath('/filearchiv/ajax/addfile.php', 1); ?> /** * FileArchiv Document Browser * Injects document browser into email presend forms */ (function() { 'use strict'; // Only run on presend pages if (window.location.href.indexOf('action=presend') === -1) { return; } // Configuration var config = { ajaxUrl: '', addFileUrl: '', token: '', element: '', id: 0, trackid: '', translations: { browseDocuments: 'trans("BrowseRelatedDocuments")); ?>', selectDocuments: 'trans("SelectDocumentsToAttach")); ?>', loading: 'trans("Loading")); ?>', noDocuments: 'trans("NoRelatedDocumentsFound")); ?>', errorLoading: 'trans("ErrorLoadingDocuments")); ?>', filesSelected: 'trans("FilesSelected")); ?>', cancel: 'trans("Cancel")); ?>', addSelected: 'trans("AddSelectedFiles")); ?>', adding: 'trans("Adding")); ?>', errorAdding: 'trans("ErrorAddingFiles")); ?>' } }; // Detect element type and ID from URL function detectContext() { var url = window.location.href; var params = new URLSearchParams(window.location.search); config.id = parseInt(params.get('id')) || 0; config.token = typeof token !== 'undefined' ? token : ''; // Detect element type from URL path if (url.indexOf('/comm/propal/') !== -1) { config.element = 'propal'; } else if (url.indexOf('/commande/') !== -1) { config.element = 'commande'; } else if (url.indexOf('/compta/facture/') !== -1) { config.element = 'facture'; } else if (url.indexOf('/expedition/') !== -1) { config.element = 'expedition'; } else if (url.indexOf('/fourn/commande/') !== -1) { config.element = 'order_supplier'; } else if (url.indexOf('/fourn/facture/') !== -1) { config.element = 'invoice_supplier'; } // Get trackid from form var trackidInput = document.querySelector('input[name="trackid"]'); if (trackidInput) { config.trackid = trackidInput.value; } // Get token from form var tokenInput = document.querySelector('input[name="token"]'); if (tokenInput) { config.token = tokenInput.value; } } // Create and inject the document browser UI function injectDocumentBrowser() { // Find the mail form var mailForm = document.getElementById('mailform'); if (!mailForm) { mailForm = document.querySelector('form[name="mailform"]'); } if (!mailForm) { return; } // Find attachment section (look for file input or attachment table) var attachSection = mailForm.querySelector('input[name="addedfile"]'); if (!attachSection) { attachSection = mailForm.querySelector('.linked-medias'); } if (!attachSection) { // Try to find any file-related section attachSection = mailForm.querySelector('table.liste'); } // Create button container var buttonHtml = '
' + '
' + ' ' + config.translations.browseDocuments + '
' + '' + '
'; // Create modal var modalHtml = '
' + '
' + '
' + '

' + config.translations.selectDocuments + '

' + '×' + '
' + '
' + '
' + '' + '
' + config.translations.loading + '...
' + '
' + '
' + '' + '
' + '
'; // Insert button before attachment section or at end of form var container = document.createElement('div'); container.innerHTML = buttonHtml; if (attachSection && attachSection.parentNode) { attachSection.parentNode.insertBefore(container.firstChild, attachSection); } else { // Insert before submit button var submitBtn = mailForm.querySelector('input[type="submit"], button[type="submit"]'); if (submitBtn && submitBtn.parentNode) { submitBtn.parentNode.insertBefore(container.firstChild, submitBtn); } else { mailForm.appendChild(container.firstChild); } } // Add modal to body document.body.insertAdjacentHTML('beforeend', modalHtml); } // Document Browser Controller window.FileArchivDocBrowser = { loaded: false, selectedFiles: [], open: function() { document.getElementById('filearchiv-docbrowser-modal').classList.add('active'); document.body.style.overflow = 'hidden'; if (!this.loaded) { this.loadDocuments(); } }, close: function() { document.getElementById('filearchiv-docbrowser-modal').classList.remove('active'); document.body.style.overflow = ''; }, loadDocuments: function() { var self = this; var url = config.ajaxUrl + '?element=' + config.element + '&id=' + config.id + '&token=' + config.token; fetch(url) .then(function(response) { return response.json(); }) .then(function(data) { self.loaded = true; self.renderDocuments(data); }) .catch(function(error) { console.error('Error loading documents:', error); document.getElementById('filearchiv-docbrowser-content').innerHTML = '
' + config.translations.errorLoading + '
'; }); }, renderDocuments: function(data) { var self = this; var container = document.getElementById('filearchiv-docbrowser-content'); if (!data.success || !data.categories || data.categories.length === 0) { container.innerHTML = '

' + config.translations.noDocuments + '
'; return; } var html = ''; data.categories.forEach(function(category, catIndex) { html += '
'; html += '
'; html += ''; html += '' + self.escapeHtml(category.title) + ''; html += '' + category.files.length + ''; html += ''; html += '
'; html += '
'; category.files.forEach(function(file, fileIndex) { var fileId = 'file-' + catIndex + '-' + fileIndex; html += '
'; html += ''; html += ''; html += '
'; html += '
' + self.escapeHtml(file.name) + '
'; html += '
' + file.size_formatted + ' - ' + file.date + '
'; if (file.product_ref) { html += '' + self.escapeHtml(file.product_ref) + ': ' + self.escapeHtml(file.product_label) + ''; } else if (file.object_ref) { html += '' + self.escapeHtml(file.object_ref) + ''; } html += '
'; html += '
'; }); html += '
'; }); container.innerHTML = html; }, escapeHtml: function(text) { if (!text) return ''; var div = document.createElement('div'); div.textContent = text; return div.innerHTML; }, toggleCategory: function(index) { var cat = document.getElementById('cat-' + index); cat.classList.toggle('open'); }, toggleFile: function(checkbox, filepath, filename) { if (checkbox.checked) { this.selectedFiles.push({ path: filepath, name: filename }); } else { this.selectedFiles = this.selectedFiles.filter(function(f) { return f.path !== filepath; }); } this.updateSelectedCount(); }, updateSelectedCount: function() { document.getElementById('filearchiv-selected-num').textContent = this.selectedFiles.length; document.getElementById('filearchiv-add-btn').disabled = this.selectedFiles.length === 0; }, addSelected: function() { if (this.selectedFiles.length === 0) return; var self = this; var addBtn = document.getElementById('filearchiv-add-btn'); addBtn.disabled = true; addBtn.innerHTML = ' ' + config.translations.adding + '...'; var promises = this.selectedFiles.map(function(file) { return fetch(config.addFileUrl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'filepath=' + encodeURIComponent(file.path) + '&filename=' + encodeURIComponent(file.name) + '&trackid=' + encodeURIComponent(config.trackid) + '&token=' + encodeURIComponent(config.token) }); }); Promise.all(promises) .then(function() { window.location.reload(); }) .catch(function(error) { console.error('Error adding files:', error); addBtn.disabled = false; addBtn.innerHTML = ' ' + config.translations.addSelected; alert(config.translations.errorAdding); }); } }; // Initialize on DOM ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', function() { detectContext(); if (config.element && config.id) { injectDocumentBrowser(); } }); } else { detectContext(); if (config.element && config.id) { injectDocumentBrowser(); } } // Close modal on Escape document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { var modal = document.getElementById('filearchiv-docbrowser-modal'); if (modal && modal.classList.contains('active')) { FileArchivDocBrowser.close(); } } }); })();