Upload templates/dashboard.html with huggingface_hub
Browse files- templates/dashboard.html +91 -13
templates/dashboard.html
CHANGED
@@ -204,8 +204,10 @@
|
|
204 |
|
205 |
.matrix-cell {
|
206 |
text-align: center;
|
207 |
-
padding:
|
208 |
-
min-width:
|
|
|
|
|
209 |
}
|
210 |
|
211 |
.matrix-cell.supported {
|
@@ -225,7 +227,11 @@
|
|
225 |
z-index: 5;
|
226 |
border-right: 2px solid #dee2e6;
|
227 |
font-family: monospace;
|
228 |
-
font-size: 0.
|
|
|
|
|
|
|
|
|
229 |
}
|
230 |
|
231 |
.total-cell {
|
@@ -399,12 +405,12 @@
|
|
399 |
<p>Loading models data...</p>
|
400 |
</div>
|
401 |
<div style="overflow-x: auto;">
|
402 |
-
<table id="modelsTable" style="
|
403 |
<thead>
|
404 |
<tr id="modelsTableHeader">
|
405 |
-
<th style="
|
406 |
<!-- Provider columns will be populated here -->
|
407 |
-
<th style="
|
408 |
</tr>
|
409 |
</thead>
|
410 |
<tbody id="modelsTableBody">
|
@@ -840,16 +846,34 @@
|
|
840 |
const providerTotals = modelsData.provider_totals || {};
|
841 |
const providerMapping = modelsData.provider_mapping || {};
|
842 |
|
843 |
-
//
|
844 |
-
const
|
845 |
-
|
846 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
847 |
|
848 |
// Update header
|
849 |
const headerHtml = `
|
850 |
-
<th style="
|
851 |
${providerHeaders}
|
852 |
-
<th style="
|
853 |
`;
|
854 |
|
855 |
// Build matrix rows
|
@@ -968,8 +992,62 @@
|
|
968 |
}
|
969 |
}
|
970 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
971 |
// Load data when page loads
|
972 |
-
document.addEventListener('DOMContentLoaded',
|
|
|
|
|
|
|
973 |
|
974 |
// Auto-refresh every 10 minutes (reduced from 5 to improve performance)
|
975 |
setInterval(loadData, 10 * 60 * 1000);
|
|
|
204 |
|
205 |
.matrix-cell {
|
206 |
text-align: center;
|
207 |
+
padding: 4px 2px;
|
208 |
+
min-width: 60px;
|
209 |
+
max-width: 60px;
|
210 |
+
font-size: 0.8rem;
|
211 |
}
|
212 |
|
213 |
.matrix-cell.supported {
|
|
|
227 |
z-index: 5;
|
228 |
border-right: 2px solid #dee2e6;
|
229 |
font-family: monospace;
|
230 |
+
font-size: 0.75rem;
|
231 |
+
max-width: 250px;
|
232 |
+
overflow: hidden;
|
233 |
+
text-overflow: ellipsis;
|
234 |
+
white-space: nowrap;
|
235 |
}
|
236 |
|
237 |
.total-cell {
|
|
|
405 |
<p>Loading models data...</p>
|
406 |
</div>
|
407 |
<div style="overflow-x: auto;">
|
408 |
+
<table id="modelsTable" style="width: 100%; table-layout: fixed;">
|
409 |
<thead>
|
410 |
<tr id="modelsTableHeader">
|
411 |
+
<th style="width: 250px; position: sticky; left: 0; background: #f8f9fa; z-index: 10;">Model ID</th>
|
412 |
<!-- Provider columns will be populated here -->
|
413 |
+
<th style="width: 60px;">Total</th>
|
414 |
</tr>
|
415 |
</thead>
|
416 |
<tbody id="modelsTableBody">
|
|
|
846 |
const providerTotals = modelsData.provider_totals || {};
|
847 |
const providerMapping = modelsData.provider_mapping || {};
|
848 |
|
849 |
+
// Create shorter provider names for column headers
|
850 |
+
const providerShortNames = {
|
851 |
+
'togethercomputer': 'Together',
|
852 |
+
'fireworks-ai': 'Fireworks',
|
853 |
+
'nebius': 'Nebius',
|
854 |
+
'fal': 'FAL',
|
855 |
+
'groq': 'Groq',
|
856 |
+
'cerebras': 'Cerebras',
|
857 |
+
'sambanovasystems': 'SambaNova',
|
858 |
+
'replicate': 'Replicate',
|
859 |
+
'novita': 'Novita',
|
860 |
+
'Hyperbolic': 'Hyperbolic',
|
861 |
+
'featherless-ai': 'Featherless',
|
862 |
+
'CohereLabs': 'Cohere',
|
863 |
+
'nscale': 'NScale'
|
864 |
+
};
|
865 |
+
|
866 |
+
// Build header with provider columns using shorter names
|
867 |
+
const providerHeaders = providers.map(provider => {
|
868 |
+
const shortName = providerShortNames[provider] || provider;
|
869 |
+
return `<th class="matrix-cell" style="width: 60px; font-size: 0.7rem; padding: 2px;" title="${provider}">${shortName}</th>`;
|
870 |
+
}).join('');
|
871 |
|
872 |
// Update header
|
873 |
const headerHtml = `
|
874 |
+
<th style="width: 250px; position: sticky; left: 0; background: #f8f9fa; z-index: 10;">Model ID</th>
|
875 |
${providerHeaders}
|
876 |
+
<th style="width: 60px;" class="total-cell">Total</th>
|
877 |
`;
|
878 |
|
879 |
// Build matrix rows
|
|
|
992 |
}
|
993 |
}
|
994 |
|
995 |
+
// Disable browser back/forward navigation gestures to prevent accidental navigation during scrolling
|
996 |
+
function disableNavigationGestures() {
|
997 |
+
// Prevent horizontal swipe gestures from triggering browser navigation
|
998 |
+
let startX = 0;
|
999 |
+
let startY = 0;
|
1000 |
+
|
1001 |
+
document.addEventListener('touchstart', function(e) {
|
1002 |
+
startX = e.touches[0].clientX;
|
1003 |
+
startY = e.touches[0].clientY;
|
1004 |
+
}, { passive: false });
|
1005 |
+
|
1006 |
+
document.addEventListener('touchmove', function(e) {
|
1007 |
+
if (e.touches.length > 1) return; // Multi-touch, allow default
|
1008 |
+
|
1009 |
+
const deltaX = Math.abs(e.touches[0].clientX - startX);
|
1010 |
+
const deltaY = Math.abs(e.touches[0].clientY - startY);
|
1011 |
+
|
1012 |
+
// If horizontal movement is significant and greater than vertical, prevent default
|
1013 |
+
if (deltaX > 10 && deltaX > deltaY) {
|
1014 |
+
e.preventDefault();
|
1015 |
+
}
|
1016 |
+
}, { passive: false });
|
1017 |
+
|
1018 |
+
// Also prevent mouse wheel horizontal scrolling from triggering navigation
|
1019 |
+
document.addEventListener('wheel', function(e) {
|
1020 |
+
// Only prevent if we're scrolling horizontally and near the edge of a scrollable container
|
1021 |
+
if (Math.abs(e.deltaX) > Math.abs(e.deltaY)) {
|
1022 |
+
const target = e.target.closest('.table-container, [style*="overflow"]');
|
1023 |
+
if (target) {
|
1024 |
+
e.stopPropagation();
|
1025 |
+
}
|
1026 |
+
}
|
1027 |
+
}, { passive: false });
|
1028 |
+
|
1029 |
+
// Prevent browser back/forward keyboard shortcuts when focused on the app
|
1030 |
+
document.addEventListener('keydown', function(e) {
|
1031 |
+
// Prevent Alt+Left/Right (Windows) and Cmd+Left/Right (Mac) browser navigation
|
1032 |
+
if ((e.altKey && (e.key === 'ArrowLeft' || e.key === 'ArrowRight')) ||
|
1033 |
+
(e.metaKey && (e.key === 'ArrowLeft' || e.key === 'ArrowRight'))) {
|
1034 |
+
e.preventDefault();
|
1035 |
+
}
|
1036 |
+
|
1037 |
+
// Prevent Backspace navigation when not in input fields
|
1038 |
+
if (e.key === 'Backspace' &&
|
1039 |
+
!['INPUT', 'TEXTAREA'].includes(e.target.tagName) &&
|
1040 |
+
!e.target.isContentEditable) {
|
1041 |
+
e.preventDefault();
|
1042 |
+
}
|
1043 |
+
});
|
1044 |
+
}
|
1045 |
+
|
1046 |
// Load data when page loads
|
1047 |
+
document.addEventListener('DOMContentLoaded', function() {
|
1048 |
+
disableNavigationGestures();
|
1049 |
+
loadData();
|
1050 |
+
});
|
1051 |
|
1052 |
// Auto-refresh every 10 minutes (reduced from 5 to improve performance)
|
1053 |
setInterval(loadData, 10 * 60 * 1000);
|