fix(stats): resolve dashboard initialization race condition and test failure

- Refactor StatisticsManager to return promises from initializeVisualizations and initializeLists
- Update fetchAndRenderList to use the fetchData wrapper for consistent mocking
- Update statistics dashboard test to include mock data for paginated model-usage-list endpoint
This commit is contained in:
Will Miao
2026-03-03 15:08:33 +08:00
parent 8c5d5a8ca0
commit 7ba9b998d3
2 changed files with 37 additions and 9 deletions

View File

@@ -29,7 +29,7 @@ export class StatisticsManager {
await this.loadAllData();
// Initialize charts and visualizations
this.initializeVisualizations();
await this.initializeVisualizations();
this.initialized = true;
}
@@ -102,7 +102,7 @@ export class StatisticsManager {
return response.json();
}
initializeVisualizations() {
async initializeVisualizations() {
// Initialize metrics cards
this.renderMetricsCards();
@@ -110,7 +110,7 @@ export class StatisticsManager {
this.initializeCharts();
// Initialize lists and other components
this.initializeLists();
await this.initializeLists();
this.renderLargestModelsList();
this.renderTagCloud();
this.renderInsights();
@@ -554,14 +554,14 @@ export class StatisticsManager {
});
}
initializeLists() {
async initializeLists() {
const listTypes = [
{ type: 'lora', containerId: 'topLorasList' },
{ type: 'checkpoint', containerId: 'topCheckpointsList' },
{ type: 'embedding', containerId: 'topEmbeddingsList' }
];
listTypes.forEach(({ type, containerId }) => {
const promises = listTypes.map(({ type, containerId }) => {
const container = document.getElementById(containerId);
if (container) {
@@ -573,9 +573,12 @@ export class StatisticsManager {
});
// Initial fetch
this.fetchAndRenderList(type, container);
return this.fetchAndRenderList(type, container);
}
return Promise.resolve();
});
await Promise.all(promises);
}
async fetchAndRenderList(type, container) {
@@ -591,10 +594,8 @@ export class StatisticsManager {
try {
const url = `/api/lm/stats/model-usage-list?type=${type}&sort=${state.sort}&offset=${state.offset}&limit=${state.limit}`;
const response = await fetch(url);
if (!response.ok) throw new Error('Network response was not ok');
const result = await this.fetchData(url);
const result = await response.json();
if (result.success) {
const items = result.data.items;

View File

@@ -107,6 +107,33 @@ describe('Statistics dashboard rendering', () => {
],
},
},
'/api/lm/stats/model-usage-list?type=lora&sort=desc&offset=0&limit=50': {
success: true,
data: {
items: [
{ name: 'Lora A', base_model: 'SDXL', folder: 'loras', usage_count: 10, preview_url: '' },
],
total: 1,
},
},
'/api/lm/stats/model-usage-list?type=checkpoint&sort=desc&offset=0&limit=50': {
success: true,
data: {
items: [
{ name: 'Checkpoint A', base_model: 'SDXL', folder: 'checkpoints', usage_count: 5, preview_url: '' },
],
total: 1,
},
},
'/api/lm/stats/model-usage-list?type=embedding&sort=desc&offset=0&limit=50': {
success: true,
data: {
items: [
{ name: 'Embedding A', base_model: 'SDXL', folder: 'embeddings', usage_count: 7, preview_url: '' },
],
total: 1,
},
},
};
const { StatisticsManager } = await import(STATISTICS_MODULE);