Ir para o conteúdo

MediaWiki:Common.js: mudanças entre as edições

De Base de Conhecimento
Sem resumo de edição
Sem resumo de edição
Linha 127: Linha 127:
             <div id="custom-file-navbar">
             <div id="custom-file-navbar">
         <div class="navbar-logo-container">
         <div class="navbar-logo-container">
             <img class="mw-logo-icon" src="/basedeconhecimento/resources/assets/logo.png" alt="" aria-hidden="true" height="50" width="50">
             <img src="/basedeconhecimento/resources/assets/logo.png" alt="" aria-hidden="true" height="50px" width="50px">
         </div>
         </div>



Edição das 12h05min de 6 de janeiro de 2026

/* Código Javascript colocado aqui será carregado para todos os utilizadores em cada carregamento de página */
 
 



mw.loader.using(['mediawiki.util', 'jquery'], function() {
    
    // 1. Carregar Dependências (Bootstrap e Ícones)
    if (!$('link[href*="bootstrap.min.css"]').length) {
        $('head').append('<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">');
    }
    if (!$('link[href*="bootstrap-icons.css"]').length) {
        $('head').append('<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">');
    }

    // 2. Injetar o CSS (Estilo Ficheiro)
    mw.util.addCSS(`
        /* Remove margens padrão do body para a barra colar no teto */
        body {
            margin-top: 0 !important;
        }

        /* Container Azul da Barra (Fundo das pastas) */
        #custom-file-navbar {
            background-color: #FFF; /* Sua cor principal */
            border-bottom: 4px solid #0000ff; /* Linha branca que conecta com o site */
            width: 100%;
            position: relative;
            z-index: 9999; /* Garante que fique acima de tudo */
            display: block;
        }

        .folder-tabs-nav {
            display: flex;
            align-items: flex-end;
            gap: 4px;
            padding-top: 12px; /* Altura da barra azul acima das abas */
            padding-left: 20px;
             margin: 0 auto; /* Centraliza o conteúdo se a tela for muito grande */
    justify-content: flex-end;
    padding-right: 15px;

        }

        /* O Estilo da "Orelha" da Pasta */
        

        

        /* Aba Ativa (Branca) */
        .folder-tab.active {
            background-color: #ffffff;
            color: #fff ; /* Texto Azul */
            font-weight: 800;
            padding-top: 12px; /* Fica um pouco mais alta */
            padding-bottom: 8px;
            border-bottom: 4px solid #fff; /* Truque visual */
            margin-bottom: -4px; /* Empurra para cobrir a borda azul */
            z-index: 10;
            box-shadow: 0 -4px 10px rgba(0,0,0,0.1);
        }

        .folder-tab i {
            font-size: 1.1em;
            margin-right: 8px;
        }

        /* Ajuste para celular */
        @media (max-width: 768px) {
            .folder-tabs-nav {
                padding-left: 10px;
                overflow-x: auto;
                white-space: nowrap;
            }
            .folder-tab {
                padding: 8px 16px;
                font-size: 0.85rem;
            }
        }


/* Hover */
        .folder-tab:hover {
            background-color: rgba(255, 255, 255, 0.4);
            color: #0000FF !important;
            transform: translateY(-2px);
        }
.folder-tab {
            display: inline-flex;
            align-items: center;
            padding: 8px 24px 6px 24px;

            /* Visual Inativo (Vidro sobre azul) */
            background-color: rgba(255, 255, 255, 0.2);
            color:black !important;
            text-decoration: none !important;
            font-weight: 600;
            font-size: 0.95rem;
            letter-spacing: 0.5px;

            /* Formato Arredondado (Só em cima) */
            border-radius: 10px 10px 0 0;
            border: 3px solid rgba(0, 0, 0, 0.1);
            border-bottom: none;

            transition: all 0.2s ease-in-out;
            position: relative;
            top: 0;
        }
.active{
        color:#fff !important;
        background-color:#0000ff!important;
        border-bottom: 4px solid #0000FF!important;
}
.active:hover{
        color:#fff !important;
}
    `);

    // 3. Inserir o HTML no Topo do Body
    $(function() {
        // Evita duplicidade se o script rodar 2x
        if ($('#custom-file-navbar').length === 0) {
            
            var html = `
            <div id="custom-file-navbar">
        <div class="navbar-logo-container">
            <img  src="/basedeconhecimento/resources/assets/logo.png" alt="" aria-hidden="true" height="50px" width="50px">
        </div>

        <nav class="folder-tabs-nav">
            <a href="https://palaciodamemoria.prefeitura.sp.gov.br/colecoes/index.php/" target="_blank" class="folder-tab">
                <i class="bi bi-box-seam-fill"></i>Atom
            </a>
            <a href="#" class="folder-tab active">
                <i class="bi bi-journal-text"></i>Wiki
            </a>
            <a href="#" class="folder-tab">
                <i class="bi bi-hash"></i>Número
            </a>
            <a href="#" class="folder-tab">
                <i class="bi bi-globe"></i>Sites
            </a>
        </nav>
    </div>
            `;

            // O SEGREDO: Prepend no body joga para o topo absoluto
            $('body').prepend(html);
        }
    });
});

$(function() {
    const container = document.getElementById("leitor-json");
    if (!container) return;

    let dados = [];
    let dadosFiltrados = [];
    let paginaAtual = 1;

    container.innerHTML = `
        <h1 class="mb-4">Consulta de Pareceres</h1>
        <div id="filtros" class="row g-3 mb-2">
            <div class="col-md-2"><input type="text" id="filtroProcesso" class="form-control" placeholder="Buscar por processo"></div>
            <div class="col-md-2"><input type="text" id="filtroDocumento" class="form-control" placeholder="Buscar por documento"></div>
            <div class="col-md-2"><select id="filtroVeiculo" class="form-select"><option value="">Todos os veículos</option></select></div>
            <div class="col-md-2"><select id="filtroSerie" class="form-select"><option value="">Todas as séries</option></select></div>
            <div class="col-md-2"><select id="filtroUnidade" class="form-select"><option value="">Todas as unidades</option></select></div>
            <div class="col-md-2"><select id="filtroOrgao" class="form-select"><option value="">Todos os órgãos</option></select></div>
            <div class="col-md-2 mt-2"><input type="text" id="filtroConteudo" class="form-control" placeholder="Buscar no conteúdo"></div>
        </div>
        <div class="mb-4 row g-2 align-items-center">
            <div class="col-auto"><button class="btn btn-primary btn-sm" id="btnPesquisar">Pesquisar</button></div>
            <div class="col-auto"><button class="btn btn-secondary btn-sm" id="btnLimpar">Limpar filtros</button></div>
            <div class="col-auto">
                <label for="resultadosPorPagina" class="form-label mb-0">Resultados por página:</label>
                <select id="resultadosPorPagina" class="form-select form-select-sm">
                    <option value="5">5</option>
                    <option value="10" selected>10</option>
                    <option value="20">20</option>
                    <option value="50">50</option>
                </select>
            </div>
        </div>
        <div id="dados"></div>
        <div class="pagination-buttons mt-3" id="paginacaoNumerica"></div>
    `;

    fetch("/images/dados.json")
        .then(res => res.json())
        .then(json => {
            dados = json;
            preencherSelects();
            aplicarFiltros();
        })
        .catch(err => console.error("Erro ao carregar dados.json:", err));

    function preencherSelects() {
        const veiculoSelect = document.getElementById("filtroVeiculo");
        const serieSelect = document.getElementById("filtroSerie");
        const unidadeSelect = document.getElementById("filtroUnidade");
        const orgaoSelect = document.getElementById("filtroOrgao");

        [...new Set(dados.map(item => item.veiculo))].forEach(v => {
            const opt = document.createElement("option"); opt.value = v; opt.textContent = v; veiculoSelect.appendChild(opt);
        });
        [...new Set(dados.map(item => item.serie))].forEach(s => {
            const opt = document.createElement("option"); opt.value = s; opt.textContent = s; serieSelect.appendChild(opt);
        });
        [...new Set(dados.map(item => item.unidade))].forEach(u => {
            const opt = document.createElement("option"); opt.value = u; opt.textContent = u; unidadeSelect.appendChild(opt);
        });
        [...new Set(dados.map(item => item.orgao))].forEach(o => {
            const opt = document.createElement("option"); opt.value = o; opt.textContent = o; orgaoSelect.appendChild(opt);
        });
    }

    function exibirDados() {
        const containerDados = document.getElementById("dados");
        containerDados.innerHTML = "";
        const resultadosPorPagina = parseInt(document.getElementById("resultadosPorPagina").value) || 10;
        const inicio = (paginaAtual-1)*resultadosPorPagina;
        const fim = inicio + resultadosPorPagina;
        const paginaDados = dadosFiltrados.slice(inicio,fim);

        if(!paginaDados.length){
            containerDados.innerHTML="<p class='text-muted'>Nenhum resultado encontrado.</p>";
            return;
        }

        paginaDados.forEach(item=>{
            const card=document.createElement("div");
            card.className="card mb-2";
            const body=document.createElement("div");
            body.className="card-body";
            body.innerHTML=`
                <h5 class="card-title">${item.veiculo}</h5>
                <h6 class="card-subtitle mb-2 text-muted">${item.orgao}</h6>
                <p><b>Unidade:</b> ${item.unidade}</p>
                <p><b>Série:</b> ${item.serie}</p>
                <p><b>Processo:</b> ${item.processo}</p>
                <p><b>Documento:</b> ${item.documento}</p>
                <div><b>Conteúdo:</b><br>${item.conteudo}</div>
            `;
            card.appendChild(body);
            containerDados.appendChild(card);
        });

        criarPaginacao();
    }

    function aplicarFiltros() {
        const processo=document.getElementById("filtroProcesso").value.toLowerCase();
        const documento=document.getElementById("filtroDocumento").value.toLowerCase();
        const veiculo=document.getElementById("filtroVeiculo").value;
        const serie=document.getElementById("filtroSerie").value;
        const unidade=document.getElementById("filtroUnidade").value;
        const orgao=document.getElementById("filtroOrgao").value;
        const conteudo=document.getElementById("filtroConteudo").value.toLowerCase();

        dadosFiltrados=dados.filter(item =>
            (!processo || item.processo.toLowerCase().includes(processo)) &&
            (!documento || item.documento.toLowerCase().includes(documento)) &&
            (!veiculo || item.veiculo===veiculo) &&
            (!serie || item.serie===serie) &&
            (!unidade || item.unidade===unidade) &&
            (!orgao || item.orgao===orgao) &&
            (!conteudo || item.conteudo.toLowerCase().includes(conteudo))
        );

        paginaAtual=1;
        exibirDados();
    }

    function limparFiltros() {
        ["filtroProcesso","filtroDocumento","filtroVeiculo","filtroSerie","filtroUnidade","filtroOrgao","filtroConteudo"].forEach(id=>document.getElementById(id).value="");
        aplicarFiltros();
    }

    function mudarPagina(n) {
        paginaAtual = n;
        exibirDados();
        document.getElementById("leitor-json").scrollIntoView({ behavior: "smooth" });
    }

    function criarPaginacao() {
    const resultadosPorPagina = parseInt(document.getElementById("resultadosPorPagina").value) || 10;
    const totalPaginas = Math.ceil(dadosFiltrados.length / resultadosPorPagina);
    const pagDiv = document.getElementById("paginacaoNumerica");
    pagDiv.innerHTML = "";

    if (totalPaginas <= 1) return;

    // Botão anterior
    const btnAnt = document.createElement("button");
    btnAnt.textContent = "«";
    btnAnt.className = "btn btn-outline-primary btn-sm me-1";
    btnAnt.disabled = paginaAtual === 1;
    btnAnt.onclick = () => mudarPagina(paginaAtual - 1);
    pagDiv.appendChild(btnAnt);

    // Primeira página
    const btn1 = document.createElement("button");
    btn1.textContent = "1";
    btn1.className = "btn btn-outline-primary btn-sm me-1" + (paginaAtual === 1 ? " active" : "");
    btn1.onclick = () => mudarPagina(1);
    pagDiv.appendChild(btn1);

    // Pontos antes, se necessário
    if (paginaAtual > 4) {
        const dots = document.createElement("span");
        dots.textContent = "...";
        dots.className = "mx-1";
        pagDiv.appendChild(dots);
    }

    // Páginas ao redor da atual (3 antes e 3 depois)
    const inicio = Math.max(2, paginaAtual - 3);
    const fim = Math.min(totalPaginas - 1, paginaAtual + 3);
    for (let i = inicio; i <= fim; i++) {
        const btn = document.createElement("button");
        btn.textContent = i;
        btn.className = "btn btn-outline-primary btn-sm me-1" + (i === paginaAtual ? " active" : "");
        btn.onclick = () => mudarPagina(i);
        pagDiv.appendChild(btn);
    }

    // Pontos depois, se necessário
    if (paginaAtual < totalPaginas - 3) {
        const dots = document.createElement("span");
        dots.textContent = "...";
        dots.className = "mx-1";
        pagDiv.appendChild(dots);
    }

    // Última página
    if (totalPaginas > 1) {
        const btnLast = document.createElement("button");
        btnLast.textContent = totalPaginas;
        btnLast.className = "btn btn-outline-primary btn-sm" + (paginaAtual === totalPaginas ? " active" : "");
        btnLast.onclick = () => mudarPagina(totalPaginas);
        pagDiv.appendChild(btnLast);
    }

    // Botão próximo
    const btnProx = document.createElement("button");
    btnProx.textContent = "»";
    btnProx.className = "btn btn-outline-primary btn-sm ms-1";
    btnProx.disabled = paginaAtual === totalPaginas;
    btnProx.onclick = () => mudarPagina(paginaAtual + 1);
    pagDiv.appendChild(btnProx);
}
 

    // Eventos filtros
    document.getElementById("btnPesquisar").onclick = aplicarFiltros;
    document.getElementById("btnLimpar").onclick = limparFiltros;
    document.getElementById("resultadosPorPagina").onchange = aplicarFiltros;
});

// Função para ativar o Hand Talk no MediaWiki
function ativarHandTalk(token) {
    if (!token) {
        console.warn("Hand Talk: token não informado.");
        return;
    }

    // Verifica se o HT já foi carregado
    if (typeof HT !== 'undefined') {
        console.log("Hand Talk já carregado.");
        return;
    }

    // Cria o script do Hand Talk
    var htScript = document.createElement('script');
    htScript.src = "https://plugin.handtalk.me/web/latest/handtalk.min.js";
    htScript.type = "text/javascript";

    // Inicializa o Hand Talk quando o script carregar
    htScript.onload = function() {
        var ht = new HT({
            token: "aa1f4871439ba18dabef482aae5fd934",
            align: "left", // canto inferior direito
            size: "medium",           // tamanho do avatar
            voice: "pt-BR"            // voz
        });
        console.log("Hand Talk ativado com sucesso!");
    };

    // Adiciona o script ao body
    document.body.appendChild(htScript);
}

// Exemplo de uso
ativarHandTalk("aa1f4871439ba18dabef482aae5fd934"); // substitua pelo token real
// Move o conteúdo despinned para não aparecer o pinned

document.addEventListener("DOMContentLoaded", function() {
    var menu = document.getElementById("vector-main-menu");
    if(menu){
        menu.innerHTML = ""; // limpa o menu que foi “pinned”
    }
});

mw.loader.using(['mediawiki.util', 'jquery'], function() {
    
    mw.util.addCSS(`
        /* 1. Garante que o container do botão esteja visível */
        #vector-main-menu-dropdown-label {
            opacity: 1 !important;
            visibility: visible !important;
            background: transparent !important; /* Remove fundo cinza/quadrado */
        }

        /* 2. Esconde o ícone antigo (que estava sumindo ou preto) */
        #vector-main-menu-dropdown .vector-icon {
            background-color: transparent !important;
            mask: none !important;
            -webkit-mask: none !important;
            filter: none !important; /* Remove o filtro que deu erro */
        }

       /* 3. Coloca o NOVO ícone BRANCO por cima usando imagem de fundo */
#vector-main-menu-dropdown .vector-icon {
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Cpath fill='%23ffffff' d='M1 3h18v3H1V3zm0 6h18v3H1V9zm0 6h18v3H1v-3z'/%3E%3C/svg%3E") !important;
    background-repeat: no-repeat !important;
    background-position: center !important;
    background-size: 20px 20px !important;
    opacity: 1 !important;
    width: 20px !important;
    height: 20px !important;
    display: inline-block !important;
}
        
        /* 4. (Opcional) Efeito Hover - Fica azul claro ao passar o mouse */
        #vector-main-menu-dropdown-label:hover .vector-icon {
             opacity: 0.7 !important;
        }
    `);
});