import apiClient from './apiClient.js';
class ProvidersView {
constructor(section) {
this.section = section;
this.tableBody = section?.querySelector('[data-providers-table]');
this.searchInput = section?.querySelector('[data-provider-search]');
this.categorySelect = section?.querySelector('[data-provider-category]');
this.summaryNode = section?.querySelector('[data-provider-summary]');
this.refreshButton = section?.querySelector('[data-provider-refresh]');
this.providers = [];
this.filtered = [];
}
init() {
if (!this.section) return;
this.bindEvents();
this.loadProviders();
}
bindEvents() {
this.searchInput?.addEventListener('input', () => this.applyFilters());
this.categorySelect?.addEventListener('change', () => this.applyFilters());
this.refreshButton?.addEventListener('click', () => this.loadProviders());
}
async loadProviders() {
if (this.tableBody) {
this.tableBody.innerHTML = '
| Loading providers... |
';
}
const result = await apiClient.getProviders();
if (!result.ok) {
this.tableBody.innerHTML = `${result.error} |
`;
return;
}
const data = result.data || {};
this.providers = data.providers || data || [];
this.applyFilters();
}
applyFilters() {
const term = (this.searchInput?.value || '').toLowerCase();
const category = this.categorySelect?.value || 'all';
this.filtered = this.providers.filter((provider) => {
const matchesTerm = `${provider.name} ${provider.provider_id}`.toLowerCase().includes(term);
const matchesCategory = category === 'all' || (provider.category || 'uncategorized') === category;
return matchesTerm && matchesCategory;
});
this.renderTable();
this.renderSummary();
}
renderTable() {
if (!this.tableBody) return;
if (!this.filtered.length) {
this.tableBody.innerHTML = '| No providers match the filters. |
';
return;
}
this.tableBody.innerHTML = this.filtered
.map(
(provider) => `
| ${provider.name || provider.provider_id} |
${provider.category || 'general'} |
${
provider.status || 'unknown'
} |
${provider.latency_ms ? `${provider.latency_ms}ms` : '—'} |
${provider.error || provider.status_code || 'OK'} |
`,
)
.join('');
}
renderSummary() {
if (!this.summaryNode) return;
const total = this.providers.length;
const healthy = this.providers.filter((provider) => provider.status === 'healthy').length;
const degraded = total - healthy;
this.summaryNode.innerHTML = `
`;
}
}
export default ProvidersView;