App-Test-Generator

 view release on metacpan or  search on metacpan

bin/test-generator-index  view on Meta::CPAN

				window.open(url, '_blank');
			}
		}
	}
});

document.getElementById('toggleTrend').addEventListener('change', function(e) {
	const show = e.target.checked;
	const trendDataset = chart.data.datasets.find(ds => ds.label === 'Regression Line');
	trendDataset.hidden = !show;
	chart.update();
});

// Reset Zoom button handler (calls plugin API if available)
const resetBtn = document.getElementById('resetZoomBtn');
if(resetBtn) {
	resetBtn.addEventListener('click', function() {
		try {
			if(chart && typeof chart.resetZoom === 'function') {
				chart.resetZoom();
			} else {
				console.warn('resetZoom not available; zoom plugin may not be registered.');
			}
		} catch (e) {
			console.warn('resetZoom call failed', e);
		}
	});
}

function sortTable(th) {
	// Always recompute colIndex from DOM so it stays correct after drag-reordering.
	// The historic onclick="sortTable(this, N)" calls still work; the N is ignored.
	const colIndex = Array.from(th.parentElement.cells).indexOf(th);
	const table = th.closest("table");
	if(!table || !table.tBodies.length) return;

	const tbody = table.tBodies[0];
	const rows = Array.from(tbody.rows);

	const prevCol = table.getAttribute("data-sort-col");
	const prevOrder = table.getAttribute("data-sort-order") || "desc";
	const asc = (prevCol != colIndex) ? true : (prevOrder === "desc");

	const isDate = th.dataset.sortType === 'date';

	const normalRows = rows.filter(r => !r.classList.contains("nosort"));
	const fixedRows = rows.filter(r => r.classList.contains("nosort"));

	normalRows.sort((a, b) => {
		const cellA = a.cells[colIndex];
		const cellB = b.cells[colIndex];
		let x = (cellA?.dataset.value ?? cellA?.innerText ?? "").trim();
		let y = (cellB?.dataset.value ?? cellB?.innerText ?? "").trim();

		if(isDate) {
			x = Date.parse(x) || 0;
			y = Date.parse(y) || 0;
		} else {
			const nx = parseFloat(x);
			const ny = parseFloat(y);
			if(!isNaN(nx) && !isNaN(ny)) {
				x = nx;
				y = ny;
			} else {
				x = x.toLowerCase();
				y = y.toLowerCase();
			}
		}

		if(x < y) return asc ? -1 : 1;
		if(x > y) return asc ? 1 : -1;
		return 0;
	});

	normalRows.forEach(r => tbody.appendChild(r));
	fixedRows.forEach(r => tbody.appendChild(r));

	// Update arrows
	const headers = table.tHead.rows[0].cells;
	for(let i = 0; i < headers.length; i++) {
		const arrow = headers[i].querySelector(".arrow");
		if(!arrow) continue;

		if(i === colIndex) {
			arrow.textContent = asc ? "â–²" : "â–¼";
			arrow.classList.add("active");
		} else {
			arrow.textContent = "â–²";
			arrow.classList.remove("active");
		}
	}

	table.setAttribute("data-sort-col", colIndex);
	table.setAttribute("data-sort-order", asc ? "asc" : "desc");
	saveSortState(table);
}

// ---------------------------------------------------------
// Column drag-to-reorder
// ---------------------------------------------------------
let _dragSrcTh = null;
let _initializingTables = false;

// ---------------------------------------------------------
// localStorage persistence for sort state and column order
// ---------------------------------------------------------
function _tableId(table) {
	return table ? table.dataset.tableId : null;
}

function saveColOrder(table) {
	const id = _tableId(table);
	if(!id) return;
	const headerRow = table.tHead && table.tHead.rows[0];
	if(!headerRow) return;
	const order = Array.from(headerRow.cells).map(th => parseInt(th.dataset.colId, 10));
	try { localStorage.setItem('atg_col_order_' + id, JSON.stringify(order)); } catch(e) {}
}

function saveSortState(table) {
	if(_initializingTables) return;



( run in 1.085 second using v1.01-cache-2.11-cpan-e7c6538aa59 )