nbroad commited on
Commit
c81446c
·
verified ·
1 Parent(s): f11953b

Upload templates/dashboard.html with huggingface_hub

Browse files
Files changed (1) hide show
  1. templates/dashboard.html +226 -83
templates/dashboard.html CHANGED
@@ -351,31 +351,45 @@
351
  </div>
352
 
353
  <div class="content">
354
- <div id="loading" class="loading">
355
- <div class="spinner"></div>
356
- <p>Loading provider data...</p>
357
- </div>
358
-
359
  <div id="error" class="error" style="display: none;">
360
  <strong>Error:</strong> <span id="errorMessage"></span>
361
  </div>
362
 
363
- <div id="content" style="display: none;">
364
  <div class="stats-row" id="statsRow">
365
- <!-- Stats cards will be populated here -->
 
 
 
 
 
 
 
 
 
 
 
366
  </div>
367
 
368
  <div class="chart-container">
369
  <h2>Live Comparison of Monthly Requests by Provider</h2>
370
- <div class="chart-wrapper">
371
- <canvas id="requestsChart"></canvas>
 
 
 
 
372
  </div>
373
  </div>
374
 
375
  <div class="chart-container">
376
  <h2 id="historicalChartTitle">Historical Trends</h2>
377
- <div class="chart-wrapper">
378
- <canvas id="historicalChart"></canvas>
 
 
 
 
379
  </div>
380
  <div class="chart-instructions">
381
  Hover for detailed coordinates • Click legend items to show/hide providers
@@ -384,7 +398,11 @@
384
 
385
  <div class="table-container">
386
  <h2>Provider Details</h2>
387
- <table id="providersTable">
 
 
 
 
388
  <thead>
389
  <tr>
390
  <th>Provider</th>
@@ -400,11 +418,11 @@
400
 
401
  <div class="table-container">
402
  <h2>Model Support Matrix</h2>
403
- <div id="modelsLoading" class="loading" style="display: none;">
404
- <div class="spinner"></div>
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">
@@ -474,8 +492,6 @@
474
  }
475
 
476
  function showError(message) {
477
- document.getElementById('loading').style.display = 'none';
478
- document.getElementById('content').style.display = 'none';
479
  document.getElementById('error').style.display = 'block';
480
  document.getElementById('errorMessage').textContent = message;
481
  }
@@ -494,27 +510,35 @@
494
  const totalRequests = data.providers.reduce((sum, provider) => sum + provider.monthly_requests_int, 0);
495
  const topProvider = data.providers[0];
496
 
497
- // Use requestAnimationFrame for smooth DOM updates
498
- requestAnimationFrame(() => {
499
- statsRow.innerHTML = `
500
- <div class="stat-card">
501
- <h3>${data.total_providers}</h3>
502
- <p>Total Providers</p>
503
- </div>
504
- <div class="stat-card">
505
- <h3>${formatNumber(totalRequests)}</h3>
506
- <p>Total Monthly Requests</p>
507
- </div>
508
- <div class="stat-card">
509
- <h3>${topProvider.provider}</h3>
510
- <p>Top Provider</p>
511
- </div>
512
- `;
513
- });
514
  }
515
 
516
  function updateChart(data) {
517
- const ctx = document.getElementById('requestsChart').getContext('2d');
 
 
 
 
 
 
 
 
 
 
518
 
519
  if (chart) {
520
  chart.destroy();
@@ -602,7 +626,17 @@
602
  }
603
 
604
  function updateHistoricalChart(historicalData) {
605
- const ctx = document.getElementById('historicalChart').getContext('2d');
 
 
 
 
 
 
 
 
 
 
606
 
607
  if (historicalChart) {
608
  historicalChart.destroy();
@@ -803,6 +837,15 @@
803
 
804
  function updateTable(data) {
805
  const tableBody = document.getElementById('tableBody');
 
 
 
 
 
 
 
 
 
806
  const rows = data.providers.map(provider => `
807
  <tr>
808
  <td><strong>${provider.provider}</strong></td>
@@ -811,10 +854,7 @@
811
  </tr>
812
  `).join('');
813
 
814
- // Use requestAnimationFrame for smooth DOM updates
815
- requestAnimationFrame(() => {
816
- tableBody.innerHTML = rows;
817
- });
818
  }
819
 
820
  function updateModelsTable(modelsData) {
@@ -822,6 +862,15 @@
822
  const modelsTableHeader = document.getElementById('modelsTableHeader');
823
  const modelsTableFoot = document.getElementById('modelsTableFoot');
824
  const modelsLoading = document.getElementById('modelsLoading');
 
 
 
 
 
 
 
 
 
825
 
826
  if (modelsData.error) {
827
  const errorRow = `
@@ -833,11 +882,8 @@
833
  </td>
834
  </tr>
835
  `;
836
- requestAnimationFrame(() => {
837
- modelsLoading.style.display = 'none';
838
- modelsTableBody.innerHTML = errorRow;
839
- modelsTableFoot.innerHTML = '';
840
- });
841
  return;
842
  }
843
 
@@ -918,50 +964,59 @@
918
  })
919
  .join('<br>');
920
 
921
- // Use requestAnimationFrame for smooth DOM updates
922
- requestAnimationFrame(() => {
923
- modelsLoading.style.display = 'none';
924
- modelsTableHeader.innerHTML = headerHtml;
925
- modelsTableBody.innerHTML = matrixRows;
926
- modelsTableFoot.innerHTML = footerHtml;
927
- if (providerLinksDiv) {
928
- providerLinksDiv.innerHTML = providerLinksHtml;
929
- }
930
- });
931
  }
932
 
933
  async function loadData() {
934
- try {
935
- const loadingEl = document.getElementById('loading');
936
- const contentEl = document.getElementById('content');
937
- const errorEl = document.getElementById('error');
938
- const modelsLoading = document.getElementById('modelsLoading');
 
 
 
 
 
 
 
 
 
939
 
940
- loadingEl.style.display = 'block';
941
- contentEl.style.display = 'none';
942
- errorEl.style.display = 'none';
943
- modelsLoading.style.display = 'block';
944
-
945
- // Fetch current data, historical data, and models data
946
- const [data, historicalData, modelsData] = await Promise.all([
947
- fetchProviderData(),
948
- fetchHistoricalData(),
949
- fetchModelsData()
950
- ]);
951
 
952
- // Batch DOM updates using requestAnimationFrame
953
- requestAnimationFrame(() => {
954
- loadingEl.style.display = 'none';
955
- contentEl.style.display = 'block';
956
- document.getElementById('lastUpdated').textContent = `Last updated: ${data.last_updated}`;
957
- });
958
-
959
- // Update components
960
  updateStats(data);
961
  updateChart(data);
962
  updateTable(data);
 
 
 
 
 
 
 
 
 
963
  updateHistoricalChart(historicalData);
964
- updateModelsTable(modelsData);
965
 
966
  // Update historical chart title with date range
967
  const titleElement = document.getElementById('historicalChartTitle');
@@ -970,9 +1025,23 @@
970
  } else {
971
  titleElement.textContent = 'Historical Trends';
972
  }
 
 
 
 
 
 
 
973
 
 
 
 
 
974
  } catch (error) {
975
- showError('Failed to load provider data. Please try again.');
 
 
 
976
  }
977
  }
978
 
@@ -982,13 +1051,87 @@
982
  refreshBtn.textContent = 'Refreshing...';
983
 
984
  try {
 
 
 
 
985
  await loadData();
986
  } finally {
987
  // Small delay to prevent rapid clicking
988
  setTimeout(() => {
989
  refreshBtn.disabled = false;
990
  refreshBtn.textContent = 'Refresh Data';
991
- }, 100);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
992
  }
993
  }
994
 
 
351
  </div>
352
 
353
  <div class="content">
 
 
 
 
 
354
  <div id="error" class="error" style="display: none;">
355
  <strong>Error:</strong> <span id="errorMessage"></span>
356
  </div>
357
 
358
+ <div id="content">
359
  <div class="stats-row" id="statsRow">
360
+ <div class="stat-card">
361
+ <div class="spinner" style="width: 20px; height: 20px; border-width: 2px; margin: 0 auto 5px;"></div>
362
+ <p>Loading...</p>
363
+ </div>
364
+ <div class="stat-card">
365
+ <div class="spinner" style="width: 20px; height: 20px; border-width: 2px; margin: 0 auto 5px;"></div>
366
+ <p>Loading...</p>
367
+ </div>
368
+ <div class="stat-card">
369
+ <div class="spinner" style="width: 20px; height: 20px; border-width: 2px; margin: 0 auto 5px;"></div>
370
+ <p>Loading...</p>
371
+ </div>
372
  </div>
373
 
374
  <div class="chart-container">
375
  <h2>Live Comparison of Monthly Requests by Provider</h2>
376
+ <div class="chart-wrapper" id="requestsChartWrapper">
377
+ <div class="loading" style="display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 350px;">
378
+ <div class="spinner" style="margin-bottom: 15px;"></div>
379
+ <p style="color: #6c757d;">Loading chart data...</p>
380
+ </div>
381
+ <canvas id="requestsChart" style="display: none;"></canvas>
382
  </div>
383
  </div>
384
 
385
  <div class="chart-container">
386
  <h2 id="historicalChartTitle">Historical Trends</h2>
387
+ <div class="chart-wrapper" id="historicalChartWrapper">
388
+ <div class="loading" style="display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 350px;">
389
+ <div class="spinner" style="margin-bottom: 15px;"></div>
390
+ <p style="color: #6c757d;">Loading historical data...</p>
391
+ </div>
392
+ <canvas id="historicalChart" style="display: none;"></canvas>
393
  </div>
394
  <div class="chart-instructions">
395
  Hover for detailed coordinates • Click legend items to show/hide providers
 
398
 
399
  <div class="table-container">
400
  <h2>Provider Details</h2>
401
+ <div id="providersTableLoading" class="loading" style="display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 200px;">
402
+ <div class="spinner" style="margin-bottom: 15px;"></div>
403
+ <p style="color: #6c757d;">Loading provider data...</p>
404
+ </div>
405
+ <table id="providersTable" style="display: none;">
406
  <thead>
407
  <tr>
408
  <th>Provider</th>
 
418
 
419
  <div class="table-container">
420
  <h2>Model Support Matrix</h2>
421
+ <div id="modelsLoading" class="loading" style="display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 200px;">
422
+ <div class="spinner" style="margin-bottom: 15px;"></div>
423
+ <p style="color: #6c757d;">Loading models data...</p>
424
  </div>
425
+ <div id="modelsTableContainer" style="overflow-x: auto; display: none;">
426
  <table id="modelsTable" style="width: 100%; table-layout: fixed;">
427
  <thead>
428
  <tr id="modelsTableHeader">
 
492
  }
493
 
494
  function showError(message) {
 
 
495
  document.getElementById('error').style.display = 'block';
496
  document.getElementById('errorMessage').textContent = message;
497
  }
 
510
  const totalRequests = data.providers.reduce((sum, provider) => sum + provider.monthly_requests_int, 0);
511
  const topProvider = data.providers[0];
512
 
513
+ // Update immediately without blocking
514
+ statsRow.innerHTML = `
515
+ <div class="stat-card">
516
+ <h3>${data.total_providers}</h3>
517
+ <p>Total Providers</p>
518
+ </div>
519
+ <div class="stat-card">
520
+ <h3>${formatNumber(totalRequests)}</h3>
521
+ <p>Total Monthly Requests</p>
522
+ </div>
523
+ <div class="stat-card">
524
+ <h3>${topProvider.provider}</h3>
525
+ <p>Top Provider</p>
526
+ </div>
527
+ `;
 
 
528
  }
529
 
530
  function updateChart(data) {
531
+ const wrapper = document.getElementById('requestsChartWrapper');
532
+ const canvas = document.getElementById('requestsChart');
533
+ const loadingEl = wrapper.querySelector('.loading');
534
+
535
+ // Hide loading, show canvas
536
+ if (loadingEl) {
537
+ loadingEl.style.display = 'none';
538
+ }
539
+ canvas.style.display = 'block';
540
+
541
+ const ctx = canvas.getContext('2d');
542
 
543
  if (chart) {
544
  chart.destroy();
 
626
  }
627
 
628
  function updateHistoricalChart(historicalData) {
629
+ const wrapper = document.getElementById('historicalChartWrapper');
630
+ const canvas = document.getElementById('historicalChart');
631
+ const loadingEl = wrapper.querySelector('.loading');
632
+
633
+ // Hide loading, show canvas
634
+ if (loadingEl) {
635
+ loadingEl.style.display = 'none';
636
+ }
637
+ canvas.style.display = 'block';
638
+
639
+ const ctx = canvas.getContext('2d');
640
 
641
  if (historicalChart) {
642
  historicalChart.destroy();
 
837
 
838
  function updateTable(data) {
839
  const tableBody = document.getElementById('tableBody');
840
+ const table = document.getElementById('providersTable');
841
+ const loadingEl = document.getElementById('providersTableLoading');
842
+
843
+ // Hide loading, show table
844
+ if (loadingEl) {
845
+ loadingEl.style.display = 'none';
846
+ }
847
+ table.style.display = 'table';
848
+
849
  const rows = data.providers.map(provider => `
850
  <tr>
851
  <td><strong>${provider.provider}</strong></td>
 
854
  </tr>
855
  `).join('');
856
 
857
+ tableBody.innerHTML = rows;
 
 
 
858
  }
859
 
860
  function updateModelsTable(modelsData) {
 
862
  const modelsTableHeader = document.getElementById('modelsTableHeader');
863
  const modelsTableFoot = document.getElementById('modelsTableFoot');
864
  const modelsLoading = document.getElementById('modelsLoading');
865
+ const modelsTableContainer = document.getElementById('modelsTableContainer');
866
+
867
+ // Hide loading, show table
868
+ if (modelsLoading) {
869
+ modelsLoading.style.display = 'none';
870
+ }
871
+ if (modelsTableContainer) {
872
+ modelsTableContainer.style.display = 'block';
873
+ }
874
 
875
  if (modelsData.error) {
876
  const errorRow = `
 
882
  </td>
883
  </tr>
884
  `;
885
+ modelsTableBody.innerHTML = errorRow;
886
+ modelsTableFoot.innerHTML = '';
 
 
 
887
  return;
888
  }
889
 
 
964
  })
965
  .join('<br>');
966
 
967
+ // Update immediately
968
+ modelsTableHeader.innerHTML = headerHtml;
969
+ modelsTableBody.innerHTML = matrixRows;
970
+ modelsTableFoot.innerHTML = footerHtml;
971
+ if (providerLinksDiv) {
972
+ providerLinksDiv.innerHTML = providerLinksHtml;
973
+ }
 
 
 
974
  }
975
 
976
  async function loadData() {
977
+ const errorEl = document.getElementById('error');
978
+ errorEl.style.display = 'none';
979
+
980
+ // Load provider data first (most important, fastest)
981
+ loadProviderData().catch(error => {
982
+ console.error('Error loading provider data:', error);
983
+ showError('Failed to load provider data. Please try again.');
984
+ });
985
+
986
+ // Load historical data second (can be slower)
987
+ loadHistoricalData().catch(error => {
988
+ console.error('Error loading historical data:', error);
989
+ // Don't show error for historical data, just log it
990
+ });
991
 
992
+ // Load models data last (heaviest)
993
+ loadModelsData().catch(error => {
994
+ console.error('Error loading models data:', error);
995
+ // Don't show error for models data, just log it
996
+ });
997
+ }
998
+
999
+ async function loadProviderData() {
1000
+ try {
1001
+ const data = await fetchProviderData();
 
1002
 
1003
+ // Update last updated timestamp
1004
+ document.getElementById('lastUpdated').textContent = `Last updated: ${data.last_updated}`;
1005
+
1006
+ // Update components immediately as data arrives
 
 
 
 
1007
  updateStats(data);
1008
  updateChart(data);
1009
  updateTable(data);
1010
+ } catch (error) {
1011
+ console.error('Error in loadProviderData:', error);
1012
+ throw error;
1013
+ }
1014
+ }
1015
+
1016
+ async function loadHistoricalData() {
1017
+ try {
1018
+ const historicalData = await fetchHistoricalData();
1019
  updateHistoricalChart(historicalData);
 
1020
 
1021
  // Update historical chart title with date range
1022
  const titleElement = document.getElementById('historicalChartTitle');
 
1025
  } else {
1026
  titleElement.textContent = 'Historical Trends';
1027
  }
1028
+ } catch (error) {
1029
+ console.error('Error in loadHistoricalData:', error);
1030
+ // Show a message in the chart area if it fails
1031
+ const wrapper = document.getElementById('historicalChartWrapper');
1032
+ wrapper.innerHTML = '<div class="loading" style="padding: 20px; color: #6c757d; text-align: center;">Historical data temporarily unavailable</div>';
1033
+ }
1034
+ }
1035
 
1036
+ async function loadModelsData() {
1037
+ try {
1038
+ const modelsData = await fetchModelsData();
1039
+ updateModelsTable(modelsData);
1040
  } catch (error) {
1041
+ console.error('Error in loadModelsData:', error);
1042
+ // Show a message in the models area if it fails
1043
+ const modelsLoading = document.getElementById('modelsLoading');
1044
+ modelsLoading.innerHTML = '<div style="padding: 20px; color: #6c757d; text-align: center;">Models data temporarily unavailable</div>';
1045
  }
1046
  }
1047
 
 
1051
  refreshBtn.textContent = 'Refreshing...';
1052
 
1053
  try {
1054
+ // Reset loading states
1055
+ resetLoadingStates();
1056
+
1057
+ // Load all data progressively
1058
  await loadData();
1059
  } finally {
1060
  // Small delay to prevent rapid clicking
1061
  setTimeout(() => {
1062
  refreshBtn.disabled = false;
1063
  refreshBtn.textContent = 'Refresh Data';
1064
+ }, 500);
1065
+ }
1066
+ }
1067
+
1068
+ function resetLoadingStates() {
1069
+ // Reset stats
1070
+ const statsRow = document.getElementById('statsRow');
1071
+ statsRow.innerHTML = `
1072
+ <div class="stat-card">
1073
+ <div class="spinner" style="width: 20px; height: 20px; border-width: 2px; margin: 0 auto 5px;"></div>
1074
+ <p>Loading...</p>
1075
+ </div>
1076
+ <div class="stat-card">
1077
+ <div class="spinner" style="width: 20px; height: 20px; border-width: 2px; margin: 0 auto 5px;"></div>
1078
+ <p>Loading...</p>
1079
+ </div>
1080
+ <div class="stat-card">
1081
+ <div class="spinner" style="width: 20px; height: 20px; border-width: 2px; margin: 0 auto 5px;"></div>
1082
+ <p>Loading...</p>
1083
+ </div>
1084
+ `;
1085
+
1086
+ // Reset charts
1087
+ const requestsChartWrapper = document.getElementById('requestsChartWrapper');
1088
+ const requestsChart = document.getElementById('requestsChart');
1089
+ requestsChartWrapper.innerHTML = `
1090
+ <div class="loading" style="display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 350px;">
1091
+ <div class="spinner" style="margin-bottom: 15px;"></div>
1092
+ <p style="color: #6c757d;">Loading chart data...</p>
1093
+ </div>
1094
+ `;
1095
+ requestsChart.style.display = 'none';
1096
+ if (chart) {
1097
+ chart.destroy();
1098
+ chart = null;
1099
+ }
1100
+
1101
+ const historicalChartWrapper = document.getElementById('historicalChartWrapper');
1102
+ const historicalChart = document.getElementById('historicalChart');
1103
+ historicalChartWrapper.innerHTML = `
1104
+ <div class="loading" style="display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 350px;">
1105
+ <div class="spinner" style="margin-bottom: 15px;"></div>
1106
+ <p style="color: #6c757d;">Loading historical data...</p>
1107
+ </div>
1108
+ `;
1109
+ historicalChart.style.display = 'none';
1110
+ if (historicalChart) {
1111
+ historicalChart.destroy();
1112
+ historicalChart = null;
1113
+ }
1114
+
1115
+ // Reset table
1116
+ const providersTable = document.getElementById('providersTable');
1117
+ const providersTableLoading = document.getElementById('providersTableLoading');
1118
+ providersTable.style.display = 'none';
1119
+ providersTableLoading.style.display = 'flex';
1120
+ providersTableLoading.innerHTML = `
1121
+ <div class="spinner" style="margin-bottom: 15px;"></div>
1122
+ <p style="color: #6c757d;">Loading provider data...</p>
1123
+ `;
1124
+
1125
+ // Reset models table
1126
+ const modelsLoading = document.getElementById('modelsLoading');
1127
+ const modelsTableContainer = document.getElementById('modelsTableContainer');
1128
+ modelsLoading.style.display = 'flex';
1129
+ modelsLoading.innerHTML = `
1130
+ <div class="spinner" style="margin-bottom: 15px;"></div>
1131
+ <p style="color: #6c757d;">Loading models data...</p>
1132
+ `;
1133
+ if (modelsTableContainer) {
1134
+ modelsTableContainer.style.display = 'none';
1135
  }
1136
  }
1137