Automatización de tareas repetitivas en Jira y paneles Vue con scripts del navegador

Reducir la fricción en los flujos de trabajo con Jira se logra con pequeños fragmentos de JavaScript que se ejecutan directamente en el navegador. Con herramientas como Arc Boost o las extensiones de Chrome es posible modificar el DOM, ajustar el comportamiento de filtros e inyectar valores automáticamente, ahorrando tiempo y evitando errores manualse.

Herramientas para inyectar scripts en cualquier sitio

Uso el boost de Arc, que permite asociar código JavaScript a un host específico. Al crear un boost se accede a una pestaña code donde se pega el script y se ejecuta en el contexto de la página. Para quienes no usan Arc, una extensión de Chrome que emplee content_scripts y haga coincidir patrones de URL ofrece el mismo resultado, e incluso más flexibilidad.

Modificaciones sobre la interfaz de Jira

Jira concentra muchas operaciones repetitivas. A continuación se muestran algunos ajustes que apliqué para agilizar el trabajo diario.

Reordenar el panel de filtros del daily

El orden de los compañeros en el tablero no coincidía con el que se seguía en la reunión. Bastó con manipular los elementos hijo del contenedor de la extensión rápida de filtros.

const contenedor = document.querySelector('.aui-expander-content.ghx-quick-content');
if (contenedor) {
    const hijos = contenedor.children;
    hijos[6].remove();
    hijos[10].remove();
    hijos[6].after(hijos[2]);
    hijos[9].after(hijos[1]);
}

Convertir selección múltiple en selección única

Los filtros del tablero aceptan múltiples selecciones; al pasar de una persona a otra era necesario desmarcar la anterior manualmente. Mediante un event listener se fuerza el comportamiento de botones de radio: al hacer clic en uno se desactivan los demás.

let actual = null;
contenedor.addEventListener('click', (e) => {
    if (actual) return;
    actual = e.target;
    Array.from(contenedor.children).forEach(item => {
        const boton = item.children[0];
        if (boton && boton.classList.contains('ghx-active') && boton.innerHTML !== actual.innerHTML) {
            boton.click();
        }
    });
    actual = null;
});

Autocompletar los campos obligatorios al cerrar un bug

Al cerrar una incidencia siempre se requerían los mismos valores: causa, tipo de resolución, descripción, etc. Un intervalo que localiza los campos y les asigna un valor elimina por completo la tarea repetitiva.

const rellenarCampo = (id, valor) => {
    const elemento = document.getElementById(id);
    if (elemento) elemento.value = valor;
};

setInterval(() => {
    rellenarCampo('resolution', 10000);
    rellenarCampo('customfield_10903', 12502);
    rellenarCampo('customfield_12301', 'Causa: error de código\nSolución: corrección\nÁmbito: interfaz\nResponsable: equipo');
}, 1000);

Accediendo a la instancia de Vue para mejorar un panel

En otro contexto, un panel de control de una aplicación Vue mostraba información muy resumida, aunque los datos completos ya estaban disponibles en el cliente. Con ayuda de la instancia Vue expuesta en el DOM se puede enriquecer la vista sin modificar el código original.

Localizar la instancia de Vue recorriendo el DOM

Vue almacena una referencia interna en el DOM (__vue__), que también utiliza la extensión Vue Devtools. Un recorrido recursivo revela dónde residen los datos.

const buscarVue = (nodo) => {
    if (nodo.__vue__) {
        console.log(nodo.__vue__._data);
    }
    [...nodo.children].forEach(hijo => buscarVue(hijo));
};
buscarVue(document.body);

Script final para inyectar estadísticas

Luego de identificar el nodo raíz se extrae la lista de datos desde _data y se agregan valores a cada fila de la tabla.

(function() {
    const appRoot = document.querySelector('.page_mod_page_simple.page_home');
    if (!appRoot || !appRoot.__vue__) return;
    const lista = appRoot.__vue__.$parent.currentList;
    const tabla = document.querySelector('.table_wrp_emotion_list .table_body');
    if (tabla && lista) {
        const filas = tabla.children;
        for (let i = 0; i < filas.length; i++) {
            if (lista[i]) {
                filas[i].children[2].innerHTML += ' (' + lista[i].SendNum + ' - ' + lista[i].DataTime + ')';
            }
        }
    }
})();

Resolver el aislamiento del entorno de ejecución

Los boosts y los content scripts de extensiones se ejecutan en un contexto separado del de la página, por lo que la propiedad __vue__ no siempre está accesible. Para sortearlo se crea un elemento <script> dinámico cuyo código corre en el contexto real de la aplicación.

const scriptPagina = document.createElement('script');
scriptPagina.textContent = `
  (function() {
    const raiz = document.querySelector('.page_mod_page_simple.page_home');
    if (!raiz || !raiz.__vue__) return;
    const datos = raiz.__vue__.$parent.currentList;
    const cuerpo = document.querySelector('.table_wrp_emotion_list .table_body');
    if (cuerpo && datos) {
      const filas = cuerpo.children;
      for (let i = 0; i < filas.length; i++) {
        if (datos[i]) {
          filas[i].children[2].innerHTML += ' (' + datos[i].SendNum + ' - ' + datos[i].DataTime + ')';
        }
      }
    }
  })();
`;
setTimeout(() => document.head.appendChild(scriptPagina), 1000);

Etiquetas: Jira automatización scripts de usuario Arc Boost Chrome Extension

Publicado el 9-15 19:24