Files
nova-dev-extension/popup.js
T
Josias Castro 790e67d5d7 Initial commit
2026-06-18 17:12:16 -03:00

313 lines
8.8 KiB
JavaScript

const DEPLOY_STEPS = [
{
id: "export-project",
label: "Exportar proyecto",
file: "export-project.js",
enabled: true
},
{
id: "increment-version",
label: "Incrementar y bloquear version",
files: ["increment-version.js", "lock-version-history.js"],
enabled: true,
linkedToggle: "toggle-increment-version"
},
{
id: "generate-source-code",
label: "Generar codigo",
file: "generate-source-code.js",
enabled: true
}
];
const REPORTS_DOWNLOAD_URL = "http://172.27.197.229:8092/scriptcase/app/GT_ARIES/blank_PROCESAR_DESCARGAR_REPORTES/";
const SCRIPT_DELAY_MS = 2500;
const CHECK_ICON = `
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M9.2 16.6 4.8 12.2l-1.6 1.6 6 6L21 7.8l-1.6-1.6L9.2 16.6Z"/>
</svg>`;
const PLAY_ICON = `
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M8 5v14l11-7L8 5Z"/>
</svg>`;
const SKIP_ICON = `
<svg viewBox="0 0 24 24" aria-hidden="true">
<path d="M5 7.4 6.4 6 12 11.6 17.6 6 19 7.4 13.4 13 19 18.6 17.6 20 12 14.4 6.4 20 5 18.6 10.6 13 5 7.4Z"/>
</svg>`;
const state = {
running: false,
stepStatus: Object.fromEntries(DEPLOY_STEPS.map(step => [step.id, "pending"])),
logs: []
};
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const stepsEl = document.getElementById("steps");
const optionsEl = document.getElementById("step-options");
const logsEl = document.getElementById("logs");
const runButton = document.getElementById("run-deploy");
const generateIdButton = document.getElementById("generate-test-id");
const downloadReportsButton = document.getElementById("download-reports-folder");
const clearLogsButton = document.getElementById("clear-logs");
const incrementToggle = document.getElementById("toggle-increment-version");
document.addEventListener("DOMContentLoaded", init);
async function init() {
renderOptions();
renderSteps();
bindEvents();
await restoreOptions();
syncIncrementOption();
renderSteps();
log("INFO", "Deploy Master listo.");
}
function bindEvents() {
runButton.addEventListener("click", runDeploy);
generateIdButton.addEventListener("click", generateTestId);
downloadReportsButton.addEventListener("click", openReportsFolder);
clearLogsButton.addEventListener("click", () => {
state.logs = [];
renderLogs();
});
incrementToggle.addEventListener("change", () => {
syncIncrementOption();
persistOptions();
renderSteps();
});
}
function renderOptions() {
optionsEl.innerHTML = DEPLOY_STEPS.map(step => `
<label class="option" title="${getStepFiles(step).join(", ")}">
<input type="checkbox" data-step-option="${step.id}" ${step.enabled ? "checked" : ""}>
<span class="mini-check"></span>
<span>${step.label}</span>
</label>
`).join("");
optionsEl.querySelectorAll("[data-step-option]").forEach(input => {
input.addEventListener("change", () => {
const step = DEPLOY_STEPS.find(item => item.id === input.dataset.stepOption);
step.enabled = input.checked;
if (step.linkedToggle === "toggle-increment-version") {
incrementToggle.checked = input.checked;
}
persistOptions();
renderSteps();
});
});
}
function renderSteps() {
stepsEl.innerHTML = DEPLOY_STEPS.map(step => {
const status = step.enabled ? state.stepStatus[step.id] : "skipped";
return `
<div class="step ${status}">
<div class="step-dot">${getStepIcon(status)}</div>
<div>${step.label}</div>
</div>
`;
}).join("");
}
function getStepIcon(status) {
if (status === "running") return PLAY_ICON;
if (status === "skipped") return SKIP_ICON;
return CHECK_ICON;
}
async function runDeploy() {
if (state.running) return;
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
if (!tab?.id) {
log("ERROR", "No se pudo detectar la pestaña activa.");
return;
}
const selectedSteps = DEPLOY_STEPS.filter(step => step.enabled);
if (!selectedSteps.length) {
log("WARN", "No hay pasos seleccionados para ejecutar.");
return;
}
setRunning(true);
resetStepStatus();
log("INFO", "Deploy iniciado...");
try {
for (const step of DEPLOY_STEPS) {
if (!step.enabled) {
setStepStatus(step.id, "skipped");
log("INFO", `Saltando ${getStepFiles(step).join(", ")}.`);
continue;
}
setStepStatus(step.id, "running");
log("INFO", `Ejecutando ${getStepFiles(step).join(", ")}...`);
const stepFiles = getStepFiles(step);
for (const [index, file] of stepFiles.entries()) {
await chrome.scripting.executeScript({
target: { tabId: tab.id, allFrames: false },
files: [file]
});
if (index < stepFiles.length - 1) {
log("INFO", `Esperando ${SCRIPT_DELAY_MS / 1000}s antes del siguiente script...`);
await sleep(SCRIPT_DELAY_MS);
}
}
setStepStatus(step.id, "done");
log("INFO", `${step.label} finalizado.`);
}
log("SUCCESS", "Deploy completado exitosamente!");
} catch (error) {
const runningStep = DEPLOY_STEPS.find(step => state.stepStatus[step.id] === "running");
if (runningStep) {
setStepStatus(runningStep.id, "error");
}
log("ERROR", error?.message || "Ocurrio un error al ejecutar el deploy.");
} finally {
setRunning(false);
}
}
async function openReportsFolder() {
await chrome.tabs.create({ url: REPORTS_DOWNLOAD_URL });
log("INFO", "Abriendo descarga de carpeta de reportes.");
}
async function generateTestId() {
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
if (!tab?.id) {
log("ERROR", "No se pudo detectar la pestaña activa.");
return;
}
try {
const [{ result }] = await chrome.scripting.executeScript({
target: { tabId: tab.id },
func: generateAndCopyTestId
});
log("INFO", `ID generado: ${result}`);
} catch (error) {
log("ERROR", error?.message || "No se pudo generar el ID de prueba.");
}
}
function generateAndCopyTestId() {
const now = new Date();
const pad = value => String(value).padStart(2, "0");
const id = `TEST-${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
const textarea = document.createElement("textarea");
textarea.value = id;
textarea.style.position = "fixed";
textarea.style.top = "0";
textarea.style.left = "0";
textarea.style.opacity = "0";
document.body.appendChild(textarea);
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
return id;
}
function resetStepStatus() {
DEPLOY_STEPS.forEach(step => {
state.stepStatus[step.id] = step.enabled ? "pending" : "skipped";
});
renderSteps();
}
function setStepStatus(stepId, status) {
state.stepStatus[stepId] = status;
renderSteps();
}
function setRunning(isRunning) {
state.running = isRunning;
runButton.disabled = isRunning;
generateIdButton.disabled = isRunning;
downloadReportsButton.disabled = isRunning;
runButton.textContent = isRunning ? "Ejecutando..." : "Ejecutar Deploy";
}
function syncIncrementOption() {
const incrementStep = DEPLOY_STEPS.find(step => step.id === "increment-version");
incrementStep.enabled = incrementToggle.checked;
const option = optionsEl.querySelector('[data-step-option="increment-version"]');
if (option) {
option.checked = incrementToggle.checked;
}
}
async function restoreOptions() {
const { deployStepOptions } = await chrome.storage.local.get("deployStepOptions");
if (!deployStepOptions) return;
DEPLOY_STEPS.forEach(step => {
if (typeof deployStepOptions[step.id] === "boolean") {
step.enabled = deployStepOptions[step.id];
}
});
incrementToggle.checked = DEPLOY_STEPS.find(step => step.id === "increment-version").enabled;
optionsEl.querySelectorAll("[data-step-option]").forEach(input => {
const step = DEPLOY_STEPS.find(item => item.id === input.dataset.stepOption);
input.checked = step.enabled;
});
}
async function persistOptions() {
const deployStepOptions = Object.fromEntries(DEPLOY_STEPS.map(step => [step.id, step.enabled]));
await chrome.storage.local.set({ deployStepOptions });
}
function getStepFiles(step) {
return step.files || [step.file];
}
function log(level, message) {
const line = `[${level}] ${message}`;
state.logs.push({ level, line });
renderLogs();
}
function renderLogs() {
logsEl.innerHTML = state.logs
.map(entry => {
const className = entry.level === "SUCCESS" ? "log-success" : "";
return `<span class="${className}">${escapeHtml(entry.line)}</span>`;
})
.join("\n");
logsEl.scrollTop = logsEl.scrollHeight;
}
function escapeHtml(value) {
return value
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;")
.replaceAll("'", "&#039;");
}