diff --git a/assets/src/scripts/_file-elements.js b/assets/src/scripts/_file-elements.js index 2472919..12a30dd 100644 --- a/assets/src/scripts/_file-elements.js +++ b/assets/src/scripts/_file-elements.js @@ -6,20 +6,27 @@ import "highlight.js/styles/github.css"; import { highlightJsName } from "./_utils"; /** - * @param {Node} el - * @param {string} ext - * @param {string} url - * @param {object} outcome + * @param {Object} params + * @param {HTMLElement} params.element + * @param {string} params.fileExtension + * @param {string} params.fileUrl + * @param {object} params.outcome + * @param {string} params.fileIndex */ -export async function createTableElement(el, ext, url, outcome) { - const data = await fileLoader(ext, url); - - el.classList.add("overflow-x-auto"); +export async function createTableElement({ + element, + fileExtension, + fileUrl, + outcome, + fileIndex, +}) { + const data = await fileLoader(fileExtension, fileUrl); tableBuilder({ csvString: data, - el, + el: element, outcome, + fileIndex, }); } diff --git a/assets/src/scripts/_output-click.js b/assets/src/scripts/_output-click.js index 5fcdc00..764f60a 100644 --- a/assets/src/scripts/_output-click.js +++ b/assets/src/scripts/_output-click.js @@ -47,11 +47,6 @@ export default async function outputClick({ outputName, metadata }) { `[data-sacro-el="file-preview-template"]` ); - const filesCount = Object.keys(openOutput.value.metadata.files).length; - - // only attempt to render outcome cells if there is a single output file - const outcome = filesCount === 1 ? openOutput.value.metadata.outcome : {}; - Object.entries(openOutput.value.metadata.files).map(([i, filedata]) => { const path = filedata.name; const { url } = filedata; @@ -80,7 +75,13 @@ export default async function outputClick({ outputName, metadata }) { filePreviewLink.setAttribute("href", url); if (isCsv(ext)) { - createTableElement(filePreviewContent, ext, url, outcome); + createTableElement({ + element: filePreviewContent, + fileExtension: ext, + fileUrl: url, + outcome: filedata.cell_index, + fileIndex: i, + }); } else if (isImg(ext)) { createImageElement(filePreviewContent, url); } else if (isTxt(ext)) { diff --git a/assets/src/scripts/_table-builder.js b/assets/src/scripts/_table-builder.js index f48aa39..6b69f47 100644 --- a/assets/src/scripts/_table-builder.js +++ b/assets/src/scripts/_table-builder.js @@ -1,24 +1,25 @@ import Papa from "papaparse"; import { html } from "./_utils"; -const indexOfAll = (arr, val) => - arr.reduce((acc, el, i) => (el !== val ? [...acc, i] : acc), []); - /** - * - * @param {string} columnName - * @param {object} columnOutcome - * @param {string[]} headings - * @returns + * @param {Object} params + * @param {Object.} params.outcome + * @param {string} params.tableId */ -function highlightFailingCells(columnName, columnOutcome, headings) { - const rows = indexOfAll(Object.values(columnOutcome), "ok"); - const column = headings.findIndex((val) => val === columnName); +function highlightFailingCells({ outcome, tableId }) { + /** @type {HTMLElement|null} */ + const tableBody = document.getElementById(tableId); + if (!tableBody) return; - const colData = rows.map((row) => { - const tableBody = document.getElementById("csvBody"); - const tableRow = tableBody.children[row]; - const tableCell = tableRow.children[column]; + Object.keys(outcome).forEach((index) => { + const x = parseFloat(index.split(",")[0]) + 1; + const y = parseFloat(index.split(",")[1]) + 2; + + /** @type {HTMLTableCellElement|null} */ + const tableCell = tableBody.querySelector( + `tr:nth-child(${x}) > td:nth-child(${y})` + ); + if (!tableCell) return; tableCell.classList.add( "bg-red-50", @@ -30,28 +31,44 @@ function highlightFailingCells(columnName, columnOutcome, headings) { "cursor-pointer" ); - const tooltipContent = Object.values(columnOutcome) - [row].split("; ") - .filter((i) => i !== "") - .map((i) => html`${i}`) + /** @type {string} */ + const tooltipContent = outcome[index] + .map( + (/** @type {string} */ str) => html`${str}` + ) .join(""); const tooltipTemplateEl = document.getElementById(`tooltip`); + if (!(tooltipTemplateEl instanceof HTMLTemplateElement)) return; + const tooltipEl = tooltipTemplateEl?.content?.firstElementChild; + if (!tooltipEl) return; - const cellTooltip = - tooltipTemplateEl?.content?.firstElementChild.cloneNode(true); - - cellTooltip.classList.add("flex", "-bottom-2"); - cellTooltip.querySelector(`[data-sacro-el="tooltip-content"]`).innerHTML = - tooltipContent; + const cellTooltip = tooltipEl.cloneNode(true); tableCell.appendChild(cellTooltip); - return tableCell; + const tooltip = tableCell.querySelector("span:first-child"); + if (tooltip) { + tooltip.classList.add("flex", "-bottom-2"); + + const tooltipContentSpan = tooltip?.querySelector( + `[data-sacro-el="tooltip-content"]` + ); + if (tooltipContentSpan) { + tooltipContentSpan.innerHTML = tooltipContent; + } + } }); - return colData; } -function tableBuilder({ csvString, el, outcome }) { +/** + * + * @param {object} params + * @param {Object.} params.outcome + * @param {HTMLElement} params.el + * @param {string} params.csvString + * @param {string} params.fileIndex + */ +function tableBuilder({ csvString, el, outcome, fileIndex }) { const csvToJson = Papa.parse(csvString).data; const bodyCell = (row) => @@ -64,9 +81,9 @@ function tableBuilder({ csvString, el, outcome }) { : `` ); - const table = html` + const tableHtmlStr = html` @@ -80,11 +97,14 @@ function tableBuilder({ csvString, el, outcome }) {
`; - el.innerHTML = table; // eslint-disable-line no-param-reassign + if (typeof tableHtmlStr === "string") { + el.innerHTML = tableHtmlStr; // eslint-disable-line no-param-reassign - Object.keys(outcome).map((columnName) => - highlightFailingCells(columnName, outcome[columnName], csvToJson[0]) - ); + highlightFailingCells({ + outcome, + tableId: `csvTable${fileIndex}`, + }); + } } export default tableBuilder;