Add expandable usage table with show more button

This commit is contained in:
jelveh
2025-12-09 16:42:52 -08:00
parent 9da8aa0849
commit ab5f168cd7
3 changed files with 90 additions and 53 deletions
+33 -21
View File
@@ -23,6 +23,8 @@ let usageTableSortState = {
direction: 'desc' // default descending (highest cost first)
};
let usageTableData = []; // Store raw data for sorting
let usageTableExpanded = false; // Track if table is showing all rows
const USAGE_TABLE_INITIAL_ROWS = 10;
const TabUsage = {
id: 'usage',
@@ -60,11 +62,8 @@ const TabUsage = {
<span class="usage-progbar-percent"></span>
</div>
</div>
<div class="driver-usage-details" style="margin-top: 5px; font-size: 13px; cursor: pointer;">
<div class="caret"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-caret-right-fill" viewBox="0 0 16 16"><path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/></svg></div>
<span class="driver-usage-details-text disable-user-select">View usage details</span>
</div>
<div class="driver-usage-details-content hide-scrollbar" style="display: none;">
<h3 style="margin:15px 0 10px 0; font-size: 14px; font-weight: 500;">Usage Details</h3>
<div class="driver-usage-details-content visible">
</div>
</div>
</div>`;
@@ -75,20 +74,6 @@ const TabUsage = {
update_usage_details($el_window);
});
// Scoped click handler for usage details toggle
$($el_window).on('click', '.driver-usage-details', function () {
const $container = $(this).closest('.driver-usage');
$container.find('.driver-usage-details-content').toggleClass('active');
$(this).toggleClass('active');
// change the text of the driver-usage-details-text depending on the class
if ( $(this).hasClass('active') ) {
$(this).find('.driver-usage-details-text').text('Hide usage details');
} else {
$(this).find('.driver-usage-details-text').text('View usage details');
}
});
// Click handler for sortable table headers
$($el_window).on('click', '.driver-usage-details-content-table th[data-sort]', function () {
const column = $(this).data('sort');
@@ -103,6 +88,12 @@ const TabUsage = {
renderUsageTable();
});
// Click handler for "Show more" to expand the table
$($el_window).on('click', '.usage-table-show-more', function () {
usageTableExpanded = true;
renderUsageTable();
});
},
};
@@ -156,8 +147,17 @@ function renderUsageTable() {
return 0;
});
// Determine how many rows to show
const hasMoreRows = sortedData.length > USAGE_TABLE_INITIAL_ROWS;
const rowsToShow = usageTableExpanded ? sortedData : sortedData.slice(0, USAGE_TABLE_INITIAL_ROWS);
const hiddenRowCount = sortedData.length - USAGE_TABLE_INITIAL_ROWS;
// Build the wrapper with potential collapsed state
const isCollapsed = hasMoreRows && !usageTableExpanded;
let h = `<div class="usage-table-wrapper${isCollapsed ? ' collapsed' : ''}">`;
// Build the table
let h = '<table class="driver-usage-details-content-table">';
h += '<table class="driver-usage-details-content-table">';
h += `<thead>
<tr>
@@ -168,7 +168,7 @@ function renderUsageTable() {
</thead>`;
h += '<tbody>';
for ( const row of sortedData ) {
for ( const row of rowsToShow ) {
h += `
<tr>
<td>${row.resource}</td>
@@ -179,10 +179,22 @@ function renderUsageTable() {
h += '</tbody>';
h += '</table>';
// Add "Show more" overlay if there are hidden rows
if ( isCollapsed ) {
h += `<div class="usage-table-fade-overlay">
<button class="usage-table-show-more">Show ${hiddenRowCount} more</button>
</div>`;
}
h += '</div>';
$('.driver-usage-details-content').html(h);
}
async function update_usage_details ($el_window) {
// Reset expanded state on refresh
usageTableExpanded = false;
// Add spinning animation and record start time
const startTime = Date.now();
$($el_window).find('.update-usage-details-icon').css('animation', 'spin 1s linear infinite');
+2 -2
View File
@@ -34,8 +34,8 @@ import TabUsage from './TabUsage.js';
// Registry of all available tabs
const tabs = [
TabHome,
TabApps,
TabFiles,
// TabApps,
// TabFiles,
TabUsage,
];
+55 -30
View File
@@ -4585,56 +4585,81 @@ fieldset[name=number-code] {
flex-direction: column;
margin-top: 20px;
}
.driver-usage-details-text{
cursor: pointer !important;
font-weight: 500;
}
.driver-usage-details-content {
display: none;
margin-top: 10px;
border-radius: 4px;
}
.driver-usage-details-content.active {
display: block !important;
flex-grow: 1;
overflow-y: scroll;
.driver-usage-details-content.visible {
display: block;
}
.driver-usage-details{
display: inline-block;
cursor: pointer;
display: flex;
align-items: center;
height: 25px;
/* Usage table wrapper for collapsed/expanded states */
.usage-table-wrapper {
position: relative;
}
.driver-usage-details .caret {
transition: transform 0.1s ease-in-out;
margin-right: 3px;
display: inline-block;
width: 20px;
height: 20px;
.usage-table-wrapper.collapsed {
position: relative;
}
/* Fade overlay with gradient */
.usage-table-fade-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 100px;
background: linear-gradient(to bottom,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.85) 40%,
rgba(255, 255, 255, 1) 100%);
display: flex;
align-items: center;
align-items: flex-end;
justify-content: center;
opacity: 0.6;
margin-left: -3px;
padding-bottom: 12px;
pointer-events: none;
}
.driver-usage-details .caret svg{
width: 14px;
height: 14px;
/* Dark theme support for fade overlay */
html.dark-mode .usage-table-fade-overlay {
background: linear-gradient(to bottom,
rgba(31, 31, 31, 0) 0%,
rgba(31, 31, 31, 0.85) 40%,
rgba(31, 31, 31, 1) 100%);
}
.driver-usage-details.active .caret {
transform: rotate(90deg);
margin-top: -2px;
/* Show more button */
.usage-table-show-more {
pointer-events: auto;
background: #3b82f6;
color: white;
border: none;
padding: 8px 20px;
border-radius: 6px;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: background-color 0.15s ease, transform 0.1s ease;
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3);
}
.usage-table-show-more:hover {
background: #2563eb;
transform: translateY(-1px);
}
.usage-table-show-more:active {
transform: translateY(0);
}
.driver-usage-details-content-table {
width: 100%;
border-collapse: collapse;
}
.usage-table-wrapper:not(.collapsed) .driver-usage-details-content-table {
margin-bottom: 30px;
}