Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -119,47 +119,64 @@ export class ReportGenerationService {
const resultService = this.workflowResultService.getResultService(operatorId);
const paginatedResultService = this.workflowResultService.getPaginatedResultService(operatorId);

// Generate the HTML content for operator details, which will be included in the report
const operatorDetailsHtml = `<div style="text-align: center;">
<h4>Operator Details</h4>
<div id="json-editor-${operatorId}" style="height: 400px;"></div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const container = document.querySelector("#json-editor-${operatorId}");
const options = { mode: 'view', language: 'en' };
const editor = new JSONEditor(container, options);
});
</script>
</div>`;
const workflowContent = this.workflowActionService.getWorkflowContent();
const operatorDetails = workflowContent.operators.find(op => op.operatorID === operatorId);

const operatorDetailsHtml = `
<div style="text-align: center;">
<h4>Operator Details</h4>
<div id="json-editor-${operatorId}" style="height: 400px;"></div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const container = document.querySelector("#json-editor-${operatorId}");
const options = { mode: 'view', language: 'en' };
const editor = new JSONEditor(container, options);
editor.set(${JSON.stringify(operatorDetails)});
});
</script>
</div>
`;

// Check if the paginated result service is available
if (paginatedResultService) {
paginatedResultService.selectPage(1, 10).subscribe({
next: pageData => {
try {
// Handle the paginated results
const table = pageData.table;
let htmlContent = `<h3>Operator ID: ${operatorId}</h3>`;

if (!table.length) {
// If no results are found, display a message
htmlContent += "<p>No results found for operator</p>";
} else {
// Generate an HTML table to display the results
const columns: string[] = Object.keys(table[0]);
const rows: any[][] = table.map(row => columns.map(col => row[col]));

htmlContent += `<div style="width: 50%; margin: 0 auto; text-align: center;">
<table style="width: 100%; border-collapse: collapse; margin: 0 auto;">
<thead>
<tr>${columns.map(col => `<th style="border: 1px solid black; padding: 8px; text-align: center;">${col}</th>`).join("")}</tr>
</thead>
<tbody>
${rows.map(row => `<tr>${row.map(cell => `<td style="border: 1px solid black; padding: 8px; text-align: center;">${String(cell)}</td>`).join("")}</tr>`).join("")}
</tbody>
</table>
</div>`;
allResults.push({
operatorId,
html: `
<h3>Operator ID: ${operatorId}</h3>
<p>No results found for operator</p>
<button onclick="toggleDetails('details-${operatorId}')">Toggle Details</button>
<div id="details-${operatorId}" style="display: none;">${operatorDetailsHtml}</div>
<div contenteditable="true" id="comment-${operatorId}" style="width: 100%; margin-top: 10px; border: 1px solid black; padding: 10px;">Add your comments here...</div>
`,
});
resolve();
return;
}
// Generate an HTML table to display the results
const columns: string[] = Object.keys(table[0]);
const rows: any[][] = table.map(row => columns.map(col => row[col]));

const htmlContent: string = `
<div style="width: 50%; margin: 0 auto; text-align: center;">
<h3>Operator ID: ${operatorId}</h3>
<table style="width: 100%; border-collapse: collapse; margin: 0 auto;">
<thead>
<tr>${columns.map(col => `<th style="border: 1px solid black; padding: 8px; text-align: center;">${col}</th>`).join("")}</tr>
</thead>
<tbody>
${rows.map(row => `<tr>${row.map(cell => `<td style="border: 1px solid black; padding: 8px; text-align: center;">${String(cell)}</td>`).join("")}</tr>`).join("")}
</tbody>
</table>
<button onclick="toggleDetails('details-${operatorId}')">Toggle Details</button>
<div id="details-${operatorId}" style="display: none;">${operatorDetailsHtml}</div>
<div contenteditable="true" id="comment-${operatorId}" style="width: 100%; margin-top: 10px; border: 1px solid black; padding: 10px;">Add your comments here...</div>
</div>
`;

// Add the generated HTML content to the allResults array
allResults.push({ operatorId, html: htmlContent });
Expand All @@ -181,59 +198,63 @@ export class ReportGenerationService {
},
});
} else if (resultService) {
try {
// Retrieve the current snapshot of results
const data = resultService.getCurrentResultSnapshot();
let htmlContent = `<h3>Operator ID: ${operatorId}</h3>`;
// Retrieve the current snapshot of results
const data = resultService.getCurrentResultSnapshot();

if (data) {
// Parse the HTML content from the snapshot data
const parser = new DOMParser();
const lastData = data[data.length - 1];
const doc = parser.parseFromString(Object(lastData)["html-content"], "text/html");
// Check if data exists; if it does, parse and display the HTML content.
// If no data is available, return a message indicating "No data found for operator."
if (data) {
// Parse the HTML content from the snapshot data
const parser = new DOMParser();
const lastData = data[data.length - 1];
const doc = parser.parseFromString(Object(lastData)["html-content"], "text/html");

// Ensure the document's height is set correctly
doc.documentElement.style.height = "50%";
doc.body.style.height = "50%";
// Ensure the document's height is set correctly
doc.documentElement.style.height = "50%";
doc.body.style.height = "50%";

const firstDiv = doc.body.querySelector("div");
if (firstDiv) firstDiv.style.height = "100%";
const firstDiv = doc.body.querySelector("div");
if (firstDiv) firstDiv.style.height = "100%";

const serializer = new XMLSerializer();
const newHtmlString = serializer.serializeToString(doc);
const serializer = new XMLSerializer();
const newHtmlString = serializer.serializeToString(doc);

htmlContent += newHtmlString;
} else {
// If no data is found, display a message
htmlContent += "<p>No data found for operator</p>";
}
const visualizationHtml = `
<h3 style="text-align: center;">Operator ID: ${operatorId}</h3>
${newHtmlString}
<button onclick="toggleDetails('details-${operatorId}')">Toggle Details</button>
<div id="details-${operatorId}" style="display: none;">${operatorDetailsHtml}</div>
<div contenteditable="true" id="comment-${operatorId}" style="width: 100%; margin-top: 10px; border: 1px solid black; padding: 10px;">Add your comments here...</div>
`;

// Add the generated HTML content to the allResults array
allResults.push({ operatorId, html: htmlContent });
allResults.push({ operatorId, html: visualizationHtml });
resolve();
} catch (error: unknown) {
// Handle any errors during snapshot result processing
const errorMessage = (error as Error).message || "Unknown error";
this.notificationService.error(
`Error processing snapshot results for operator ${operatorId}: ${errorMessage}`
);
reject(error);
}
} else {
try {
// If no result services are available, provide a default message
} else {
// If no data is found, display a message
allResults.push({
operatorId,
html: `<h3>Operator ID: ${operatorId}</h3>
<p>No results found for operator</p>`,
html: `
<h3>Operator ID: ${operatorId}</h3>
<p>No data found for operator</p>
<button onclick="toggleDetails('details-${operatorId}')">Toggle Details</button>
<div id="details-${operatorId}" style="display: none;">${operatorDetailsHtml}</div>
<div contenteditable="true" id="comment-${operatorId}" style="width: 100%; margin-top: 10px; border: 1px solid black; padding: 10px;">Add your comments here...</div>
`,
});
resolve();
} catch (error: unknown) {
// Handle any errors when pushing the default result
const errorMessage = (error as Error).message || "Unknown error";
this.notificationService.error(`Error pushing default result for operator ${operatorId}: ${errorMessage}`);
reject(error);
}
} else {
allResults.push({
operatorId,
html: `
<h3>Operator ID: ${operatorId}</h3>
<p>No results found for operator</p>
<button onclick="toggleDetails('details-${operatorId}')">Toggle Details</button>
<div id="details-${operatorId}" style="display: none;">${operatorDetailsHtml}</div>
<div contenteditable="true" id="comment-${operatorId}" style="width: 100%; margin-top: 10px; border: 1px solid black; padding: 10px;">Add your comments here...</div>
`,
});
resolve();
}
} catch (error: unknown) {
// Handle any unexpected errors that occur in the main logic
Expand All @@ -260,6 +281,9 @@ export class ReportGenerationService {
<html>
<head>
<title>Operator Results</title>
<!-- Link to JSONEditor CSS file-->
<link href="https://cdn.jsdelivr.net/npm/jsoneditor@10.1.0/dist/jsoneditor.min.css" rel="stylesheet" type="text/css" />
<script src="https://cdn.jsdelivr.net/npm/jsoneditor@10.1.0/dist/jsoneditor.min.js"></script>
<style>
.button {
margin-top: 20px;
Expand Down Expand Up @@ -288,7 +312,25 @@ export class ReportGenerationService {
}
</style>
<script>
// JavaScript functions for comment handling and JSON downloading...
function toggleDetails(id) {
const detailsElement = document.getElementById(id);
if (detailsElement.style.display === "none") {
detailsElement.style.display = "block";
} else {
detailsElement.style.display = "none";
}
}

function downloadJson() {
const workflowContent = ${JSON.stringify(this.workflowActionService.getWorkflowContent())};
const jsonBlob = new Blob([JSON.stringify(workflowContent, null, 2)], {type: "application/json"});
const url = URL.createObjectURL(jsonBlob);
const a = document.createElement("a");
a.href = url;
a.download = "${workflowName}-workflow.json";
a.click();
URL.revokeObjectURL(url);
}
</script>
</head>
<body>
Expand All @@ -297,13 +339,16 @@ export class ReportGenerationService {
<img src="${workflowSnapshot}" alt="Workflow Snapshot" style="width: 100%; max-width: 800px;">
</div>
${allResults.join("")}
<div style="text-align: center; margin-top: 20px;">
<button class="button" onclick="downloadJson()">Download Workflow JSON</button>
</div>
</body>
</html>
`;

const blob = new Blob([htmlContent], { type: "text/html" });
const url = URL.createObjectURL(blob);
const fileName = `${workflowName}-report.html`; // Use workflowName to generate the file name
const fileName = `${workflowName}-report.html`;
const a = document.createElement("a");
a.href = url;
a.download = fileName;
Expand Down
7 changes: 7 additions & 0 deletions core/gui/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
<link
href="https://fonts.googleapis.com/icon?family=Material+Icons&display=block"
rel="stylesheet" />

<!-- Add JSON Editor CSS and JS -->
<link
href="https://cdn.jsdelivr.net/npm/jsoneditor@10.1.0/dist/jsoneditor.min.css"
rel="stylesheet"
type="text/css" />
<script src="https://cdn.jsdelivr.net/npm/jsoneditor@10.1.0/dist/jsoneditor.min.js"></script>
</head>
<body>
<texera-root></texera-root>
Expand Down