您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Añade un panel lateral para gestionar órdenes y rellenar datos, con lista de trabajadores personalizable.
// ==UserScript== // @name Asistente de Formularios APEX (Panel Fijo) // @namespace Violentmonkey Scripts // @match http://192.168.100.83:8080/apex/f* // @grant none // @version 2.1 // @author IKAROS // @description Añade un panel lateral para gestionar órdenes y rellenar datos, con lista de trabajadores personalizable. // ==/UserScript== (function() { 'use strict'; // --- CONFIGURACIÓN --- const APEX_APP_ID = '100'; const APEX_PAGE_ID = '2010'; const APEX_GO_BACK_PAGE = '2300'; const APEX_STATUS_SELECT_ID = 'P2010_TA1R250_CODIGO'; const APEX_TEXT_AREA_ID = 'P2010_RESPUESTA'; const APEX_STATUS_VALUE_TO_SET = 'RES'; const DEFAULT_TRABAJADORES = ['AGUILERA','BUSTAMANTE','MENDOZA','MERCAU','MERCAU L','MUÑOZ','OJEDA','PEREYRA','PINO','RODRIGUEZ','ROSALES','SALINAS']; // --- FIN DE LA CONFIGURACIÓN --- const SESSION_DATE_KEY = 'gm_apex_form_date'; const SESSION_WORKERS_KEY = 'gm_apex_form_workers'; const LOCAL_WORKER_LIST_KEY = 'gm_apex_worker_list'; let toastTimer; function addStyles() { const panelWidth = 'auto'; const styles = ` body { margin-right: ${panelWidth} !important; } #gm-side-panel { position: fixed; top: 0; right: 0; width: ${panelWidth}; height: 100vh; background-color: #f7f9fc; border-left: 1px solid #dfe3e8; box-shadow: -3px 0 15px rgba(0,0,0,0.08); z-index: 9999; padding: 15px; overflow-y: auto; font-family: Arial, sans-serif; box-sizing: border-box; transition: opacity 0.3s ease, display 0.3s ease; } #gm-side-panel.hidden { opacity: 0; pointer-events: none; } #gm-side-panel h2 { margin: 0; padding-bottom: 10px; color: #333; border-bottom: 2px solid #007bff; text-align: center; font-size: 18px; margin-bottom: 15px; } #gm-side-panel .gm-section { background-color: #fff; border: 1px solid #dfe3e8; border-radius: 8px; padding: 15px; margin-bottom: 15px; } #gm-side-panel label { display: block; margin-bottom: 5px; font-weight: bold; color: #555; } #gm-side-panel input[type="date"], #gm-side-panel input[type="number"], #gm-side-panel input[type="text"], #gm-side-panel textarea { width: 100%; padding: 10px; border-radius: 4px; border: 1px solid #ccc; box-sizing: border-box; } #gm-side-panel button { width: 100%; padding: 12px 15px; border: none; border-radius: 5px; cursor: pointer; font-weight: bold; font-size: 14px; margin-top: 10px; } .gm-input-group { display: flex; gap: 10px; } #gm-trabajadores-list { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 5px; } #gm-trabajadores-list label { font-weight: normal; display: flex; align-items: center; justify-content: space-between; } .gm-worker-controls { display: none; } /* Oculto por defecto */ .gm-worker-controls button { background: none; border: none; cursor: pointer; font-weight: bold; padding: 2px 5px; } .gm-edit-worker-btn { color: #007bff; padding: 5px !important; } .gm-remove-worker-btn { color: #dc3545; padding: 5px !important; } .gm-save-worker-btn { color: #28a745; } .gm-cancel-edit-btn { color: #6c757d; } #gm-worker-add-group { display: none; } /* Oculto por defecto */ #gm-manage-worker-section.gm-edit-mode #gm-worker-add-group, #gm-manage-worker-section.gm-edit-mode .gm-worker-controls { display: flex; /* Se muestra en modo edición */ } #gm-btn-cargar-orden { background-color: #17a2b8; color: white; } #gm-btn-colectora { background-color: #28a745; color: white; } #gm-btn-anexar { background-color: #007bff; color: white; } #gm-btn-perdida { background-color: #fd7e14; color: white; } #gm-btn-toggle-worker-edit { background-color: #6c757d; color: white; } #gm-btn-add-worker { background-color: #007bff; color: white; } #gm-toast-notification { visibility: hidden; opacity: 0; position: fixed; bottom: 20px; left: 50%; transform: translate(-50%, 20px); background-color: #2c3e50; color: white; padding: 16px 30px; border-radius: 8px; box-shadow: 0 4px 15px rgba(0,0,0,0.2); transition: all 0.4s ease-in-out; z-index: 10002; } #gm-toast-notification.gm-toast-show { visibility: visible; opacity: 1; transform: translate(-50%, 0); } `; const styleSheet = document.createElement("style"); styleSheet.innerText = styles; document.head.appendChild(styleSheet); } function createUI() { const sidePanel = document.createElement('div'); sidePanel.id = 'gm-side-panel'; sidePanel.innerHTML = ` <div class="gm-section"> <label for="gm-orden-input">Cargar Orden</label> <input type="number" id="gm-orden-input" placeholder="N° de orden..."> <button id="gm-btn-cargar-orden">Cargar Orden</button> </div> <div id="gm-manage-worker-section" class="gm-section"> <label>1. Generar Suceso</label> <input type="date" id="gm-fecha-input" style="margin-bottom: 15px;"> <div id="gm-trabajadores-list"></div> <div id="gm-worker-add-group" class="gm-input-group" style="margin-top: 15px;"> <input type="text" id="gm-new-worker-input" placeholder="Añadir nombre..."> <button id="gm-btn-add-worker" style="margin-top:0; width:auto; padding:0 15px;">Añadir</button> </div> <button id="gm-btn-toggle-worker-edit">Editar Lista</button> </div> <div class="gm-section"> <label>2. Aplicar a Página</label> <div class="gm-input-group" style="margin-top:0;"> <button id="gm-btn-colectora" style="margin-top:0;">Colectora</button> <button id="gm-btn-anexar" style="margin-top:0;">Reiterado</button> <button id="gm-btn-perdida" style="margin-top:0;">Pérdida</button> </div> </div> `; document.body.appendChild(sidePanel); const toast = document.createElement('div'); toast.id = 'gm-toast-notification'; document.body.appendChild(toast); rebuildWorkerUI(); } // --- Lógica de Trabajadores --- function getWorkers() { const d=localStorage.getItem(LOCAL_WORKER_LIST_KEY); if(d)return JSON.parse(d); localStorage.setItem(LOCAL_WORKER_LIST_KEY,JSON.stringify(DEFAULT_TRABAJADORES)); return DEFAULT_TRABAJADORES; } function saveWorkerList(workers) { localStorage.setItem(LOCAL_WORKER_LIST_KEY,JSON.stringify(workers)); } function rebuildWorkerUI() { const workerListDiv = document.getElementById('gm-trabajadores-list'); workerListDiv.innerHTML = ''; getWorkers().forEach(name => { const workerLabel = document.createElement('label'); const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.value = name; checkbox.style.marginRight = '8px'; const nameSpan = document.createElement('span'); nameSpan.textContent = name; nameSpan.style.flexGrow = '1'; const controlsDiv = document.createElement('div'); controlsDiv.className = 'gm-worker-controls'; const editBtn = document.createElement('button'); editBtn.className = 'gm-edit-worker-btn'; editBtn.innerHTML = '✏️'; editBtn.title = `Editar ${name}`; editBtn.onclick = () => handleEditWorker(name); const removeBtn = document.createElement('button'); removeBtn.className = 'gm-remove-worker-btn'; removeBtn.innerHTML = '✖️'; removeBtn.title = `Quitar a ${name}`; removeBtn.onclick = () => { if (confirm(`¿Está seguro que desea eliminar a ${name}?`)) { saveWorkerList(getWorkers().filter(w => w !== name)); rebuildWorkerUI(); } }; controlsDiv.appendChild(editBtn); controlsDiv.appendChild(removeBtn); workerLabel.appendChild(checkbox); workerLabel.appendChild(nameSpan); workerLabel.appendChild(controlsDiv); workerListDiv.appendChild(workerLabel); }); loadPersistedData(); } function handleEditWorker(originalName) { rebuildWorkerUI(); const targetLabel = Array.from(document.querySelectorAll('#gm-trabajadores-list label')).find(label => label.querySelector('span').textContent === originalName); if (!targetLabel) return; const nameSpan = targetLabel.querySelector('span'); const controlsDiv = targetLabel.querySelector('.gm-worker-controls'); const editInput = document.createElement('input'); editInput.type = 'text'; editInput.value = originalName; editInput.style.width = '100px'; const saveBtn = document.createElement('button'); saveBtn.className = 'gm-save-worker-btn'; saveBtn.innerHTML = '✔️'; saveBtn.title = 'Guardar'; saveBtn.onclick = () => { const newName = editInput.value.trim().toUpperCase(); if (!newName) return; const workers = getWorkers(); if (workers.includes(newName) && newName !== originalName) { showToast(`El nombre "${newName}" ya existe.`); return; } saveWorkerList(workers.map(w => w === originalName ? newName : w)); rebuildWorkerUI(); }; const cancelBtn = document.createElement('button'); cancelBtn.className = 'gm-cancel-edit-btn'; cancelBtn.innerHTML = '✖️'; cancelBtn.title = 'Cancelar'; cancelBtn.onclick = () => rebuildWorkerUI(); nameSpan.style.display = 'none'; controlsDiv.innerHTML = ''; controlsDiv.appendChild(saveBtn); controlsDiv.appendChild(cancelBtn); targetLabel.insertBefore(editInput, controlsDiv); editInput.focus(); } // --- Lógica Principal y de Utilidad --- function loadOrderPage() { const d=document.getElementById("gm-orden-input").value.trim(); if(!d){showToast("Por favor, ingrese un número de orden.");return}const e=document.getElementById("pInstance")?.value; if(!e){showToast("Error: No se pudo encontrar el ID de sesión de APEX.");return}const f=`/apex/f?p=${APEX_APP_ID}:${APEX_PAGE_ID}:${e}:UPDATE:NO:${APEX_PAGE_ID}:P${APEX_PAGE_ID}_NUMERO,P${APEX_PAGE_ID}_GO_BACK:${d},${APEX_GO_BACK_PAGE}`; window.location.href=f; } function applyValuesToPage(text, append = false) { const statusSelect = document.getElementById(APEX_STATUS_SELECT_ID); const descriptionTextarea = document.getElementById(APEX_TEXT_AREA_ID); if (statusSelect) { statusSelect.value = APEX_STATUS_VALUE_TO_SET; statusSelect.dispatchEvent(new Event('change', { bubbles: true })); statusSelect.style.color = 'red'; } if (descriptionTextarea) { if (append && descriptionTextarea.value.trim() !== '') { descriptionTextarea.value += `\n${text}`; } else { descriptionTextarea.value = text; } descriptionTextarea.dispatchEvent(new Event('input', { bubbles: true })); descriptionTextarea.style.color = 'red'; } showToast('✅ ¡Texto aplicado!'); } function generateColectoraText() { const fechaInput = document.getElementById('gm-fecha-input').value; if (!fechaInput) { showToast('Por favor, seleccione una fecha.'); return null; } const checkboxes = document.querySelectorAll('#gm-trabajadores-list input:checked'); if (checkboxes.length === 0) { showToast('Seleccione al menos un trabajador.'); return null; } const fecha = new Date(fechaInput + 'T00:00:00'); const fechaFormateada = fecha.toLocaleDateString('es-AR', { day: '2-digit', month: '2-digit', year: 'numeric' }); const nombres = Array.from(checkboxes).map(cb => cb.value).join(', '); return `COLECTORA NORMALIZADA - ${nombres} ${fechaFormateada}.`; } function generatePerdidaText() { const fechaInput = document.getElementById('gm-fecha-input').value; if (!fechaInput) { showToast('Por favor, seleccione una fecha.'); return null; } const checkboxes = document.querySelectorAll('#gm-trabajadores-list input:checked'); if (checkboxes.length === 0) { showToast('Seleccione al menos un trabajador.'); return null; } const fecha = new Date(fechaInput + 'T00:00:00'); const fechaFormateada = fecha.toLocaleDateString('es-AR', { day: '2-digit', month: '2-digit', year: 'numeric' }); const nombres = Array.from(checkboxes).map(cb => cb.value).join(', '); return `PERDIDA DE AGUA - ${nombres} ${fechaFormateada}.`; } function handleColectora() { const textoFinal = generateColectoraText(); if (textoFinal) { applyValuesToPage(textoFinal, false); // Sobrescribir } } function handleAnexar() { const textoFinal = generateColectoraText(); if (textoFinal) { applyValuesToPage(textoFinal, true); // Anexar } } function handlePerdida() { const textoFinal = generatePerdidaText(); applyValuesToPage(textoFinal, false); // Sobrescribir } function showToast(message) { const e=document.getElementById("gm-toast-notification"); e.textContent=message; e.classList.add("gm-toast-show"); clearTimeout(toastimer); toastimer=setTimeout(()=>{e.classList.remove("gm-toast-show")},3e3); } function saveDate() { sessionStorage.setItem(SESSION_DATE_KEY,document.getElementById("gm-fecha-input").value); } function saveWorkersSelection() { const d=Array.from(document.querySelectorAll("#gm-trabajadores-list input:checked")).map(e=>e.value); sessionStorage.setItem(SESSION_WORKERS_KEY,JSON.stringify(d)); } function loadPersistedData() { const d=sessionStorage.getItem(SESSION_DATE_KEY); if(d)document.getElementById("gm-fecha-input").value=d; const e=sessionStorage.getItem(SESSION_WORKERS_KEY); if(e){const f=JSON.parse(e); document.querySelectorAll("#gm-trabajadores-list input").forEach(g=>{g.checked=f.includes(g.value)})} } // --- Event Listeners --- function addEventListeners() { document.getElementById('gm-btn-cargar-orden').addEventListener('click', loadOrderPage); document.getElementById('gm-orden-input').addEventListener('keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); loadOrderPage(); } }); document.getElementById('gm-btn-colectora').addEventListener('click', handleColectora); document.getElementById('gm-btn-anexar').addEventListener('click', handleAnexar); document.getElementById('gm-btn-perdida').addEventListener('click', handlePerdida); const manageSection = document.getElementById('gm-manage-worker-section'); const toggleBtn = document.getElementById('gm-btn-toggle-worker-edit'); toggleBtn.addEventListener('click', () => { manageSection.classList.toggle('gm-edit-mode'); if (manageSection.classList.contains('gm-edit-mode')) { toggleBtn.textContent = 'Finalizar Edición'; toggleBtn.style.backgroundColor = '#28a745'; } else { toggleBtn.textContent = 'Editar Lista'; toggleBtn.style.backgroundColor = '#6c757d'; rebuildWorkerUI(); } }); document.getElementById('gm-btn-add-worker').addEventListener('click', () => { const input = document.getElementById('gm-new-worker-input'); const newName = input.value.trim().toUpperCase(); if (newName) { const workers = getWorkers(); if (workers.includes(newName)) { showToast(`"${newName}" ya existe.`); } else { workers.push(newName); saveWorkerList(workers); rebuildWorkerUI(); input.value = ''; showToast(`"${newName}" fue añadido.`); } } }); document.getElementById('gm-fecha-input').addEventListener('change', saveDate); document.getElementById('gm-trabajadores-list').addEventListener('change', saveWorkersSelection); } // --- Ejecución Principal con Detección de Logout --- function main() { addStyles(); createUI(); addEventListeners(); const sidePanel = document.getElementById('gm-side-panel'); if (!sidePanel) return; const checkLogoutLink = () => { const logoutLinks = Array.from(document.querySelectorAll('a[href]')) .filter(a => a.href.includes('apex_authentication.logout')); if (logoutLinks.length > 0) { sidePanel.classList.remove('hidden'); sidePanel.style.display = 'block'; } else { sidePanel.classList.add('hidden'); setTimeout(() => { sidePanel.style.display = 'none'; }, 300); } }; checkLogoutLink(); const observer = new MutationObserver(() => { checkLogoutLink(); }); observer.observe(document.body, { childList: true, subtree: true, attributes: false, characterData: false }); window.addEventListener('popstate', checkLogoutLink); window.addEventListener('hashchange', checkLogoutLink); } main(); })();