skyview/assets/static/js/modules/callsign-manager.js
Ole-Morten Duesund 8019049c63 feat: Enhance web interface with database integration and callsign management
- Add callsign management module for enhanced aircraft information
- Integrate database status display in web interface
- Update aircraft manager with database-backed callsign resolution
- Enhance user interface with database connectivity indicators
- Add embedded asset management for new database interface components

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-31 19:43:58 +02:00

163 lines
No EOL
5.6 KiB
JavaScript

// Callsign enrichment and display module
export class CallsignManager {
constructor() {
this.callsignCache = new Map();
this.pendingRequests = new Map();
// Rate limiting to avoid overwhelming the API
this.lastRequestTime = 0;
this.requestInterval = 100; // Minimum 100ms between requests
}
/**
* Get enriched callsign information, using cache when available
* @param {string} callsign - The raw callsign to lookup
* @returns {Promise<Object>} - Enriched callsign data
*/
async getCallsignInfo(callsign) {
if (!callsign || callsign.trim() === '') {
return null;
}
const cleanCallsign = callsign.trim().toUpperCase();
// Check cache first
if (this.callsignCache.has(cleanCallsign)) {
return this.callsignCache.get(cleanCallsign);
}
// Check if we already have a pending request for this callsign
if (this.pendingRequests.has(cleanCallsign)) {
return this.pendingRequests.get(cleanCallsign);
}
// Rate limiting
const now = Date.now();
if (now - this.lastRequestTime < this.requestInterval) {
await new Promise(resolve => setTimeout(resolve, this.requestInterval));
}
// Create the API request
const requestPromise = this.fetchCallsignInfo(cleanCallsign);
this.pendingRequests.set(cleanCallsign, requestPromise);
try {
const result = await requestPromise;
// Cache the result for future use
if (result && result.callsign) {
this.callsignCache.set(cleanCallsign, result.callsign);
}
return result ? result.callsign : null;
} catch (error) {
console.warn(`Failed to lookup callsign ${cleanCallsign}:`, error);
return null;
} finally {
// Clean up pending request
this.pendingRequests.delete(cleanCallsign);
this.lastRequestTime = Date.now();
}
}
/**
* Fetch callsign information from the API
* @param {string} callsign - The callsign to lookup
* @returns {Promise<Object>} - API response
*/
async fetchCallsignInfo(callsign) {
const response = await fetch(`/api/callsign/${encodeURIComponent(callsign)}`);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
}
/**
* Generate rich HTML display for a callsign
* @param {Object} callsignInfo - Enriched callsign data from API
* @param {string} originalCallsign - Original callsign if API data is null
* @returns {string} - HTML string for display
*/
generateCallsignDisplay(callsignInfo, originalCallsign = '') {
if (!callsignInfo || !callsignInfo.is_valid) {
// Fallback for invalid or missing callsign data
if (originalCallsign) {
return `<span class="callsign-display simple">${originalCallsign}</span>`;
}
return '<span class="callsign-display no-data">N/A</span>';
}
const parts = [];
// Airline code
if (callsignInfo.airline_code) {
parts.push(`<span class="airline-code">${callsignInfo.airline_code}</span>`);
}
// Flight number
if (callsignInfo.flight_number) {
parts.push(`<span class="flight-number">${callsignInfo.flight_number}</span>`);
}
// Airline name (if available)
let airlineInfo = '';
if (callsignInfo.airline_name) {
airlineInfo = `<span class="airline-name" title="${callsignInfo.airline_name}">
${callsignInfo.airline_name}
</span>`;
// Add country if available
if (callsignInfo.airline_country) {
airlineInfo += ` <span class="airline-country">(${callsignInfo.airline_country})</span>`;
}
}
return `
<span class="callsign-display enriched">
<span class="callsign-code">${parts.join(' ')}</span>
${airlineInfo ? `<span class="callsign-details">${airlineInfo}</span>` : ''}
</span>
`;
}
/**
* Generate compact callsign display for table view
* @param {Object} callsignInfo - Enriched callsign data
* @param {string} originalCallsign - Original callsign fallback
* @returns {string} - Compact HTML for table display
*/
generateCompactCallsignDisplay(callsignInfo, originalCallsign = '') {
if (!callsignInfo || !callsignInfo.is_valid) {
return originalCallsign || 'N/A';
}
// For tables, use the display_name or format airline + flight
if (callsignInfo.display_name) {
return `<span class="callsign-compact" title="${callsignInfo.airline_name || ''}">${callsignInfo.display_name}</span>`;
}
return `<span class="callsign-compact">${callsignInfo.airline_code} ${callsignInfo.flight_number}</span>`;
}
/**
* Clear the callsign cache (useful for memory management)
*/
clearCache() {
this.callsignCache.clear();
console.debug('Callsign cache cleared');
}
/**
* Get cache statistics for debugging
* @returns {Object} - Cache size and pending requests
*/
getCacheStats() {
return {
cacheSize: this.callsignCache.size,
pendingRequests: this.pendingRequests.size
};
}
}