Skip to content
Open
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
81 changes: 72 additions & 9 deletions lib/skunk/generators/html/templates/skunk_overview.html.erb

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When loading the report, the arrow icons do not show up

Image

They should be visible like so; however, I'm unsure if they show a neutral hint or the actual initial sort preference. The reports start with:
Image

For the neutral hint, I added this .table-header::after { content: " ⇅"; opacity: .35 }

@fbuys,
Would you be happy with a neutral hint or more like an initial arrow that matches the actual pre-sorted order?
And, since you are around, what do you think about the sorting implementation? As for the code, I'd say it looks good, but as for what columns you want to be sorted, What are the criteria to follow, etc.?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the helpful feedback. I’ve updated the report to indicate the initial sort direction. Since the report is initially sorted by Skunk Score in descending order, the Skunk Score column now displays the descending arrow by default, while the other columns remain neutral until selected. I’ve also kept the existing numeric and alphabetical sorting behavior unchanged.

Please let me know if you have any further suggestions or would prefer a different sorting behavior. Thank you again for your guidance!

Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,29 @@
font-weight: bold;
}

/* Sortable Table Headers */
.table-header {
cursor: pointer;
user-select: none;
}

.table-header:hover {
text-decoration: underline;
}

.sort-type {
display: inline-block;
margin-left: 0.4rem;
}

.table-header-asc::after {
content: " ▲";
}

.table-header-desc::after {
content: " ▼";
}

/* Mobile Card Layout */
@media screen and (max-width: 800px) {
.skunk-results thead {
Expand Down Expand Up @@ -257,15 +280,15 @@

<section class="table-section">
<h2>Skunk Analysis</h2>
<table class="skunk-results">
<table id="skunkTable" class="skunk-results">
<thead>
<tr>
<th>File</th>
<th>Skunk Score</th>
<th>Churn × Cost</th>
<th>Churn</th>
<th>Cost</th>
<th>Coverage</th>
<th class="table-header">File<span class="sort-type"></span></th>
<th class="table-header active table-header-desc">Skunk Score<span class="sort-type"></span></th>
<th class="table-header">Churn &times; Cost<span class="sort-type"></span></th>
<th class="table-header">Churn<span class="sort-type"></span></th>
<th class="table-header">Cost<span class="sort-type"></span></th>
<th class="table-header">Coverage<span class="sort-type"></span></th>
</tr>
</thead>
<tbody>
Expand All @@ -279,7 +302,7 @@
<span><%= item.skunk_score %></span>
</td>
<td>
<label>Churn × Cost</label>
<label>Churn &times; Cost</label>
<span><%= item.churn_times_cost %></span>
</td>
<td>
Expand All @@ -304,5 +327,45 @@
<p>Generated with Skunk v<%= @skunk_version %> on <%= @generated_at %></p>
</footer>
</div>

<script>
document.addEventListener("DOMContentLoaded", () => {
const table = document.getElementById("skunkTable");
const headers = table.querySelectorAll(".table-header");
const tbody = table.querySelector("tbody");
const numericColumns = [1, 2, 3, 4, 5];

const cellValue = (row, columnIndex) =>
row.cells[columnIndex].querySelector("span:last-child").textContent.trim();

const compareRows = (rowA, rowB, columnIndex, ascending) => {
const valueA = cellValue(rowA, columnIndex);
const valueB = cellValue(rowB, columnIndex);

if (numericColumns.includes(columnIndex)) {
return ascending ? Number(valueA) - Number(valueB) : Number(valueB) - Number(valueA);
}

return ascending ? valueA.localeCompare(valueB) : valueB.localeCompare(valueA);
};

headers.forEach((header, columnIndex) => {
header.addEventListener("click", () => {
const ascending = !header.classList.contains("table-header-asc");
const rows = Array.from(tbody.querySelectorAll(".table-row"));

headers.forEach((otherHeader) => {
otherHeader.classList.remove("active", "table-header-asc", "table-header-desc");
});

header.classList.add("active", ascending ? "table-header-asc" : "table-header-desc");

rows
.sort((rowA, rowB) => compareRows(rowA, rowB, columnIndex, ascending))
.forEach((row) => tbody.appendChild(row));
});
});
});
</script>
</body>
</html>
</html>