GA RT (ManagerZone)

Portado de la extensión de Chrome "Asistente RT ManagerZone". iniciarRT(): inyecta el botón "🔎 Investigar" en la bandeja de request-tracker, parsea el asunto del ticket y abre las solapas de control (bifurca report_cheater vs. transferencias). autocompletarBusquedaPlayer(): en control, autocompleta y envía el buscador cuando llega con action_type=player. Ambas se auto-gatean por hostname. Sin dependencias (no usa jQuery ni ga-core).

このスクリプトは単体で利用できません。右のようなメタデータを含むスクリプトから、ライブラリとして読み込まれます: // @require https://update.greasyfork.org/scripts/588187/1882753/GA%20RT%20%28ManagerZone%29.js

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         GA RT (ManagerZone)
// @namespace    https://control.managerzone.com/ga
// @version      1.1.0
// @description  Portado de la extensión de Chrome "Asistente RT ManagerZone", con lupas en 3 puntos: tabla con "Coger" (original), tabla de mayor Prioridad (sin "Coger") y página del ticket (debajo del messagebody). La lógica de parseo/apertura está extraída en rtInvestigar() y el botón en crearLupa(): los tres puntos comparten el MISMO comportamiento. autocompletarBusquedaPlayer() actúa en control. Auto-gateadas por hostname. Sin dependencias.
// ==/UserScript==

(function () {
    'use strict';
    window.GA = window.GA || {};
    const GA = window.GA;

    // ==========================================
    // PARTE 1: LÓGICA PARA LA BANDEJA DE RT
    // ==========================================
    GA.iniciarRT = function () {
        if (!window.location.hostname.includes("request-tracker")) return;

    // ------------------------------------------------------------------
    //  crearLupa()  — EXTRAÍDO del handler original, sin cambios.
    //  Devuelve el <a> "🔎 Investigar" con el mismo aspecto de siempre.
    // ------------------------------------------------------------------
    function crearLupa() {
        const btnInvestigar = document.createElement('a');
        btnInvestigar.innerText = '🔎 Investigar';
        btnInvestigar.className = 'mz-investigate-btn';
        btnInvestigar.href = '#';
        
        btnInvestigar.style.cursor = 'pointer';
        btnInvestigar.style.color = '#487048';
        btnInvestigar.style.fontWeight = 'bold';
        btnInvestigar.style.textDecoration = 'none';
        return btnInvestigar;
    }

    // ------------------------------------------------------------------
    //  rtInvestigar(textoAsunto)  — EXTRAÍDO del handler original.
    //  Es el MISMO código que corría dentro del botón: decide si el
    //  ticket es report_cheater o transferencia y abre las solapas.
    //  Ahora lo comparten los tres puntos de inyección.
    // ------------------------------------------------------------------
    function rtInvestigar(textoAsunto) {
        // ==========================================
        // BIFURCACIÓN: ¿Qué tipo de ticket es?
        // ==========================================
        if (textoAsunto.includes('report_cheater')) {
            
            // --- CASO 1: REPORT CHEATER ---
            const match = textoAsunto.match(/\((\d+)\)/);
            
            if (match && match[1]) {
                const userId = match[1];
                const searchUrl = `https://control.managerzone.com/?p=ga_admin&sub=searchresult&searchtype=user&searchstr=${userId}&searchtype-reference=user&searchstr-reference=`;
                window.open(searchUrl, '_blank');
            } else {
                alert("GA-Assistant: No se pudo extraer el ID del usuario del ticket report_cheater.");
            }

        } else {
            
            // --- CASO 2: TRANSFERENCIAS (Tu código original) ---
            const deporteMatch = textoAsunto.match(/(soccer|hockey)/i);
            const deporte = deporteMatch ? deporteMatch[1].toLowerCase() : "";

            const userIdsMatch = textoAsunto.match(/\((\d+)\).*?\((\d+)\)/);
            const vendedorId = userIdsMatch ? userIdsMatch[1] : "";
            const compradorId = userIdsMatch ? userIdsMatch[2] : "";

            const playerIdMatch = textoAsunto.match(/Player ID\s*(\d+)/i);
            const playerId = playerIdMatch ? playerIdMatch[1] : "";

            if (deporte && vendedorId && compradorId) {
                
                // Pestaña 1: Búsqueda del Jugador en CheatNow
                const urlCheatNow = `https://control.managerzone.com/?p=ga_admin&sub=cheatnow&sport=${deporte}&user1=${vendedorId}&user2=${compradorId}&player=${playerId}&action_type=player`;
                window.open(urlCheatNow, '_blank');
                
                // Pestaña 2: Ficha del Vendedor con cruce de referencia al Comprador
                const urlVendedor = `https://control.managerzone.com/?p=ga_admin&sub=searchresult&searchtype=user&searchstr=${vendedorId}&searchtype-reference=user&searchstr-reference=${compradorId}`;
                window.open(urlVendedor, '_blank');
                
                // Pestaña 3: Ficha del Comprador con cruce de referencia al Vendedor
                const urlComprador = `https://control.managerzone.com/?p=ga_admin&sub=searchresult&searchtype=user&searchstr=${compradorId}&searchtype-reference=user&searchstr-reference=${vendedorId}`;
                window.open(urlComprador, '_blank');

            } else {
                alert("La estructura del asunto no coincide con el formato esperado. Faltan datos.");
            }
        }
    }

    function injectDashboardButtons() {
        const takeLinks = document.querySelectorAll('a[href*="Action=Take"]');

        takeLinks.forEach(link => {
            const parentTd = link.parentElement;
            if (parentTd.querySelector('.mz-investigate-btn')) return;

            const btnInvestigar = crearLupa();

            btnInvestigar.addEventListener('click', (e) => {
                e.preventDefault();
                const ticketRow = link.closest('tbody.list-item');
                
                const celdas = ticketRow.querySelectorAll('td');
                let textoAsunto = "";
                if (celdas.length > 1) {
                    textoAsunto = celdas[1].innerText.trim(); 
                }

                rtInvestigar(textoAsunto);
            });

            link.after(' | ', btnInvestigar);
        });
    }

    // ------------------------------------------------------------------
    //  injectPrioridadButtons()  — NUEVO.
    //  La tabla "N° | Asunto | Prioridad | Cola | Estado" NO trae link
    //  "Coger", por eso injectDashboardButtons (que se cuelga de
    //  a[href*="Action=Take"]) nunca la alcanza. Acá recorremos los
    //  tbody.list-item que no tienen "Coger" y les colgamos la lupa en
    //  la celda del Asunto (esa tabla no tiene columna de acciones).
    // ------------------------------------------------------------------
    function injectPrioridadButtons() {
        const filas = document.querySelectorAll('tbody.list-item');

        filas.forEach(fila => {
            if (fila.querySelector('.mz-investigate-btn')) return;
            if (fila.querySelector('a[href*="Action=Take"]')) return;

            // La celda del Asunto NO está siempre en el mismo índice:
            //   vistazo/prioridad -> N° | Asunto | Prioridad | Cola | Estado   (índice 1)
            //   lista lateral     -> N° | Propietario | Asunto | Estado        (índice 2)
            // Por eso se detecta por contexto, no por posición: es la primera
            // celda con link al ticket cuyo texto no sean sólo dígitos (la de
            // sólo dígitos es la del número de ticket).
            let celdaAsunto = null;
            fila.querySelectorAll('td').forEach(td => {
                if (celdaAsunto) return;
                if (!td.querySelector('a[href*="Ticket/Display.html"]')) return;
                const t = td.innerText.trim();
                if (!t || /^\d+$/.test(t)) return;
                celdaAsunto = td;
            });
            if (!celdaAsunto) return;

            // Se lee ANTES de insertar la lupa: como el botón queda dentro
            // de esta misma celda, leerlo después ensuciaría el asunto.
            const textoAsunto = celdaAsunto.innerText.trim();
            if (!textoAsunto) return;

            const btnInvestigar = crearLupa();
            btnInvestigar.addEventListener('click', (e) => {
                e.preventDefault();
                rtInvestigar(textoAsunto);
            });

            celdaAsunto.append(' | ', btnInvestigar);
        });
    }

    // ------------------------------------------------------------------
    //  injectTicketDisplayButton()  — NUEVO.
    //  En la página del ticket el asunto está en #header h1, con el
    //  formato "#565574: PL - soccer - koral(2393336) - ...". Se le saca
    //  el "#nnnnn: " del principio para dejarlo igual que en la tabla.
    //  La lupa va justo debajo del .messagebody.
    // ------------------------------------------------------------------
    function injectTicketDisplayButton() {
        if (document.getElementById('mz-investigate-ticket')) return;

        const cuerpo = document.querySelector('.messagebody');
        if (!cuerpo) return;

        const h1 = document.querySelector('#header h1');
        if (!h1) return;

        const textoAsunto = h1.innerText.trim().replace(/^#\d+:\s*/, '');
        if (!textoAsunto) return;

        const cont = document.createElement('div');
        cont.id = 'mz-investigate-ticket';
        cont.style.padding = '8px 0';
        cont.style.borderTop = '1px solid #ccc';
        cont.style.textAlign = 'right';

        const btnInvestigar = crearLupa();
        btnInvestigar.style.fontSize = '14px';
        btnInvestigar.addEventListener('click', (e) => {
            e.preventDefault();
            rtInvestigar(textoAsunto);
        });

        cont.appendChild(btnInvestigar);
        cuerpo.after(cont);
    }

    function inyectarTodo() {
        injectDashboardButtons();
        injectPrioridadButtons();
        injectTicketDisplayButton();
    }

    inyectarTodo();
    setInterval(inyectarTodo, 2000);
    };

    // PARTE 2: LÓGICA PARA LA PÁGINA DE CONTROL
    // ==========================================
    GA.autocompletarBusquedaPlayer = function () {
        if (!window.location.hostname.includes("control.managerzone.com")) return;

    const urlParams = new URLSearchParams(window.location.search);
    const actionType = urlParams.get('action_type');
    const playerId = urlParams.get('player');

    if (actionType === 'player' && playerId) {
        const cajaTexto = document.querySelector('input[name="search_string"]');
        const menuDesplegable = document.querySelector('select[name="search_type"]');

        if (cajaTexto && menuDesplegable && cajaTexto.value === "") {
            
            cajaTexto.value = playerId;
            menuDesplegable.value = 'player_id';

            const formulario = cajaTexto.closest('form');
            if (formulario) {
                formulario.submit();
            } else {
                const btnSearch = document.querySelector('input[value="Search"], input[type="submit"]');
                if (btnSearch) btnSearch.click();
            }
        }
    }
    };

})();