Unknown type supprt
This commit is contained in:
@@ -0,0 +1,50 @@
|
|||||||
|
"""Add user_aircraft table for user-defined aircraft types
|
||||||
|
|
||||||
|
Revision ID: 004_user_aircraft
|
||||||
|
Revises: 003_public_booking
|
||||||
|
Create Date: 2026-03-23 12:00:00.000000
|
||||||
|
|
||||||
|
This migration adds a user_aircraft table to store aircraft types
|
||||||
|
that are manually entered by users when not found in the main aircraft database.
|
||||||
|
|
||||||
|
"""
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '004_user_aircraft'
|
||||||
|
down_revision = '003_public_booking'
|
||||||
|
branch_labels = None
|
||||||
|
depends_on = None
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
"""
|
||||||
|
Create user_aircraft table for storing user-defined aircraft types.
|
||||||
|
"""
|
||||||
|
op.create_table('user_aircraft',
|
||||||
|
sa.Column('id', sa.Integer(), nullable=False),
|
||||||
|
sa.Column('registration', sa.String(length=25), nullable=False),
|
||||||
|
sa.Column('type_code', sa.String(length=30), nullable=False),
|
||||||
|
sa.Column('clean_reg', sa.String(length=25), nullable=False),
|
||||||
|
sa.Column('created_by', sa.String(length=16), nullable=False),
|
||||||
|
sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
|
||||||
|
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
|
||||||
|
sa.PrimaryKeyConstraint('id'),
|
||||||
|
sa.UniqueConstraint('registration')
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create indexes
|
||||||
|
op.create_index('idx_user_aircraft_registration', 'user_aircraft', ['registration'])
|
||||||
|
op.create_index('idx_user_aircraft_clean_reg', 'user_aircraft', ['clean_reg'])
|
||||||
|
op.create_index('idx_user_aircraft_created_by', 'user_aircraft', ['created_by'])
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
"""
|
||||||
|
Drop user_aircraft table.
|
||||||
|
"""
|
||||||
|
op.drop_index('idx_user_aircraft_created_by', table_name='user_aircraft')
|
||||||
|
op.drop_index('idx_user_aircraft_clean_reg', table_name='user_aircraft')
|
||||||
|
op.drop_index('idx_user_aircraft_registration', table_name='user_aircraft')
|
||||||
|
op.drop_table('user_aircraft')
|
||||||
@@ -2,8 +2,8 @@ from typing import List, Optional
|
|||||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from app.api.deps import get_db, get_current_active_user
|
from app.api.deps import get_db, get_current_active_user
|
||||||
from app.models.ppr import Aircraft
|
from app.models.ppr import Aircraft, UserAircraft
|
||||||
from app.schemas.ppr import Aircraft as AircraftSchema
|
from app.schemas.ppr import Aircraft as AircraftSchema, UserAircraftCreate
|
||||||
from app.models.ppr import User
|
from app.models.ppr import User
|
||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
@@ -18,6 +18,7 @@ async def lookup_aircraft_by_registration(
|
|||||||
"""
|
"""
|
||||||
Lookup aircraft by registration (clean match).
|
Lookup aircraft by registration (clean match).
|
||||||
Removes non-alphanumeric characters from input for matching.
|
Removes non-alphanumeric characters from input for matching.
|
||||||
|
Checks user_aircraft table first, then aircraft table.
|
||||||
"""
|
"""
|
||||||
# Clean the input registration (remove non-alphanumeric characters)
|
# Clean the input registration (remove non-alphanumeric characters)
|
||||||
clean_input = ''.join(c for c in registration if c.isalnum()).upper()
|
clean_input = ''.join(c for c in registration if c.isalnum()).upper()
|
||||||
@@ -25,7 +26,29 @@ async def lookup_aircraft_by_registration(
|
|||||||
if len(clean_input) < 4:
|
if len(clean_input) < 4:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# Query aircraft table using clean_reg column
|
# First check user_aircraft table
|
||||||
|
user_aircraft = db.query(UserAircraft).filter(
|
||||||
|
UserAircraft.clean_reg.like(f"{clean_input}%")
|
||||||
|
).limit(10).all()
|
||||||
|
|
||||||
|
if user_aircraft:
|
||||||
|
# Convert UserAircraft to Aircraft-like objects
|
||||||
|
result = []
|
||||||
|
for ua in user_aircraft:
|
||||||
|
# Create a mock Aircraft object with the user data
|
||||||
|
result.append({
|
||||||
|
'id': ua.id,
|
||||||
|
'registration': ua.registration,
|
||||||
|
'type_code': ua.type_code,
|
||||||
|
'clean_reg': ua.clean_reg,
|
||||||
|
'icao24': None,
|
||||||
|
'manufacturer_icao': None,
|
||||||
|
'manufacturer_name': None,
|
||||||
|
'model': None
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
|
||||||
|
# If no user aircraft found, check main aircraft table
|
||||||
aircraft_list = db.query(Aircraft).filter(
|
aircraft_list = db.query(Aircraft).filter(
|
||||||
Aircraft.clean_reg.like(f"{clean_input}%")
|
Aircraft.clean_reg.like(f"{clean_input}%")
|
||||||
).limit(10).all()
|
).limit(10).all()
|
||||||
@@ -42,6 +65,7 @@ async def public_lookup_aircraft_by_registration(
|
|||||||
Public lookup aircraft by registration (clean match).
|
Public lookup aircraft by registration (clean match).
|
||||||
Removes non-alphanumeric characters from input for matching.
|
Removes non-alphanumeric characters from input for matching.
|
||||||
No authentication required.
|
No authentication required.
|
||||||
|
Checks user_aircraft table first, then aircraft table.
|
||||||
"""
|
"""
|
||||||
# Clean the input registration (remove non-alphanumeric characters)
|
# Clean the input registration (remove non-alphanumeric characters)
|
||||||
clean_input = ''.join(c for c in registration if c.isalnum()).upper()
|
clean_input = ''.join(c for c in registration if c.isalnum()).upper()
|
||||||
@@ -49,7 +73,28 @@ async def public_lookup_aircraft_by_registration(
|
|||||||
if len(clean_input) < 4:
|
if len(clean_input) < 4:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# Query aircraft table using clean_reg column
|
# First check user_aircraft table
|
||||||
|
user_aircraft = db.query(UserAircraft).filter(
|
||||||
|
UserAircraft.clean_reg.like(f"{clean_input}%")
|
||||||
|
).limit(10).all()
|
||||||
|
|
||||||
|
if user_aircraft:
|
||||||
|
# Convert UserAircraft to Aircraft-like objects
|
||||||
|
result = []
|
||||||
|
for ua in user_aircraft:
|
||||||
|
result.append({
|
||||||
|
'id': ua.id,
|
||||||
|
'registration': ua.registration,
|
||||||
|
'type_code': ua.type_code,
|
||||||
|
'clean_reg': ua.clean_reg,
|
||||||
|
'icao24': None,
|
||||||
|
'manufacturer_icao': None,
|
||||||
|
'manufacturer_name': None,
|
||||||
|
'model': None
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
|
||||||
|
# If no user aircraft found, check main aircraft table
|
||||||
aircraft_list = db.query(Aircraft).filter(
|
aircraft_list = db.query(Aircraft).filter(
|
||||||
Aircraft.clean_reg.like(f"{clean_input}%")
|
Aircraft.clean_reg.like(f"{clean_input}%")
|
||||||
).limit(10).all()
|
).limit(10).all()
|
||||||
@@ -82,3 +127,38 @@ async def search_aircraft(
|
|||||||
).limit(limit).all()
|
).limit(limit).all()
|
||||||
|
|
||||||
return aircraft_list
|
return aircraft_list
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/user-aircraft", response_model=dict)
|
||||||
|
async def save_user_aircraft(
|
||||||
|
aircraft: UserAircraftCreate,
|
||||||
|
db: Session = Depends(get_db),
|
||||||
|
current_user: User = Depends(get_current_active_user)
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Save a user-defined aircraft type for a registration.
|
||||||
|
"""
|
||||||
|
# Clean the registration
|
||||||
|
clean_reg = ''.join(c for c in aircraft.registration if c.isalnum()).upper()
|
||||||
|
|
||||||
|
# Check if already exists
|
||||||
|
existing = db.query(UserAircraft).filter(
|
||||||
|
UserAircraft.registration == aircraft.registration.upper()
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if existing:
|
||||||
|
raise HTTPException(status_code=400, detail="Aircraft registration already exists in user database")
|
||||||
|
|
||||||
|
# Create new user aircraft
|
||||||
|
user_aircraft = UserAircraft(
|
||||||
|
registration=aircraft.registration.upper(),
|
||||||
|
type_code=aircraft.type_code.upper(),
|
||||||
|
clean_reg=clean_reg,
|
||||||
|
created_by=current_user.username
|
||||||
|
)
|
||||||
|
|
||||||
|
db.add(user_aircraft)
|
||||||
|
db.commit()
|
||||||
|
db.refresh(user_aircraft)
|
||||||
|
|
||||||
|
return {"message": "Aircraft saved successfully", "id": user_aircraft.id}
|
||||||
@@ -89,3 +89,15 @@ class Aircraft(Base):
|
|||||||
clean_reg = Column(String(25), nullable=True, index=True)
|
clean_reg = Column(String(25), nullable=True, index=True)
|
||||||
created_at = Column(DateTime, nullable=False, server_default=func.current_timestamp())
|
created_at = Column(DateTime, nullable=False, server_default=func.current_timestamp())
|
||||||
updated_at = Column(DateTime, nullable=False, server_default=func.current_timestamp(), onupdate=func.current_timestamp())
|
updated_at = Column(DateTime, nullable=False, server_default=func.current_timestamp(), onupdate=func.current_timestamp())
|
||||||
|
|
||||||
|
|
||||||
|
class UserAircraft(Base):
|
||||||
|
__tablename__ = "user_aircraft"
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||||
|
registration = Column(String(25), nullable=False, unique=True, index=True)
|
||||||
|
type_code = Column(String(30), nullable=False)
|
||||||
|
clean_reg = Column(String(25), nullable=False, index=True)
|
||||||
|
created_by = Column(String(16), nullable=False, index=True)
|
||||||
|
created_at = Column(DateTime, nullable=False, server_default=func.current_timestamp())
|
||||||
|
updated_at = Column(DateTime, nullable=False, server_default=func.current_timestamp(), onupdate=func.current_timestamp())
|
||||||
@@ -215,3 +215,23 @@ class Aircraft(AircraftBase):
|
|||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
|
# User Aircraft schemas
|
||||||
|
class UserAircraftBase(BaseModel):
|
||||||
|
registration: str
|
||||||
|
type_code: str
|
||||||
|
clean_reg: str
|
||||||
|
created_by: str
|
||||||
|
|
||||||
|
|
||||||
|
class UserAircraft(UserAircraftBase):
|
||||||
|
id: int
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
from_attributes = True
|
||||||
|
|
||||||
|
|
||||||
|
class UserAircraftCreate(BaseModel):
|
||||||
|
registration: str
|
||||||
|
type_code: str
|
||||||
+37
-3
@@ -1494,6 +1494,12 @@
|
|||||||
openNewPPRModal();
|
openNewPPRModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Press 'g' to book out local flight starting with G
|
||||||
|
if (e.key === 'g' || e.key === 'G') {
|
||||||
|
e.preventDefault();
|
||||||
|
openLocalFlightModal('LOCAL', 'G');
|
||||||
|
}
|
||||||
|
|
||||||
// Press 'l' to book out local flight (LOCAL type)
|
// Press 'l' to book out local flight (LOCAL type)
|
||||||
if (e.key === 'l' || e.key === 'L') {
|
if (e.key === 'l' || e.key === 'L') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -2624,6 +2630,9 @@
|
|||||||
document.getElementById('ppr-form').reset();
|
document.getElementById('ppr-form').reset();
|
||||||
document.getElementById('ppr-id').value = '';
|
document.getElementById('ppr-id').value = '';
|
||||||
|
|
||||||
|
// Clear the unsaved aircraft flag
|
||||||
|
document.getElementById('ppr-form').removeAttribute('data-unsaved-aircraft');
|
||||||
|
|
||||||
// Set default ETA and ETD
|
// Set default ETA and ETD
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const eta = new Date(now.getTime() + 60 * 60 * 1000); // +1 hour
|
const eta = new Date(now.getTime() + 60 * 60 * 1000); // +1 hour
|
||||||
@@ -3040,6 +3049,9 @@
|
|||||||
|
|
||||||
if (!accessToken) return;
|
if (!accessToken) return;
|
||||||
|
|
||||||
|
// Auto-save any unsaved aircraft types
|
||||||
|
await autoSaveUnsavedAircraft(this);
|
||||||
|
|
||||||
const formData = new FormData(this);
|
const formData = new FormData(this);
|
||||||
const pprData = {};
|
const pprData = {};
|
||||||
|
|
||||||
@@ -3531,22 +3543,29 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Local Flight (Book Out) Modal Functions
|
// Local Flight (Book Out) Modal Functions
|
||||||
function openLocalFlightModal(flightType = 'LOCAL') {
|
function openLocalFlightModal(flightType = 'LOCAL', prefillReg = '') {
|
||||||
document.getElementById('local-flight-form').reset();
|
document.getElementById('local-flight-form').reset();
|
||||||
document.getElementById('local-flight-id').value = '';
|
document.getElementById('local-flight-id').value = '';
|
||||||
document.getElementById('local-flight-modal-title').textContent = 'Book Out';
|
document.getElementById('local-flight-modal-title').textContent = 'Book Out';
|
||||||
document.getElementById('local_flight_type').value = flightType;
|
document.getElementById('local_flight_type').value = flightType;
|
||||||
document.getElementById('localFlightModal').style.display = 'block';
|
document.getElementById('localFlightModal').style.display = 'block';
|
||||||
|
|
||||||
|
// Clear the unsaved aircraft flag
|
||||||
|
document.getElementById('local-flight-form').removeAttribute('data-unsaved-aircraft');
|
||||||
|
|
||||||
// Clear aircraft lookup results
|
// Clear aircraft lookup results
|
||||||
clearLocalAircraftLookup();
|
clearLocalAircraftLookup();
|
||||||
|
|
||||||
// Update destination field visibility based on flight type
|
// Update destination field visibility based on flight type
|
||||||
handleFlightTypeChange(flightType);
|
handleFlightTypeChange(flightType);
|
||||||
|
|
||||||
// Auto-focus on registration field
|
// Auto-focus on registration field and prefill if provided
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.getElementById('local_registration').focus();
|
const regField = document.getElementById('local_registration');
|
||||||
|
regField.focus();
|
||||||
|
if (prefillReg) {
|
||||||
|
regField.value = prefillReg;
|
||||||
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3555,6 +3574,9 @@
|
|||||||
document.getElementById('book-in-id').value = '';
|
document.getElementById('book-in-id').value = '';
|
||||||
document.getElementById('bookInModal').style.display = 'block';
|
document.getElementById('bookInModal').style.display = 'block';
|
||||||
|
|
||||||
|
// Clear the unsaved aircraft flag
|
||||||
|
document.getElementById('book-in-form').removeAttribute('data-unsaved-aircraft');
|
||||||
|
|
||||||
// Clear aircraft lookup results
|
// Clear aircraft lookup results
|
||||||
clearBookInAircraftLookup();
|
clearBookInAircraftLookup();
|
||||||
clearBookInArrivalAirportLookup();
|
clearBookInArrivalAirportLookup();
|
||||||
@@ -3573,6 +3595,9 @@
|
|||||||
document.getElementById('overflight-id').value = '';
|
document.getElementById('overflight-id').value = '';
|
||||||
document.getElementById('overflightModal').style.display = 'block';
|
document.getElementById('overflightModal').style.display = 'block';
|
||||||
|
|
||||||
|
// Clear the unsaved aircraft flag
|
||||||
|
document.getElementById('overflight-form').removeAttribute('data-unsaved-aircraft');
|
||||||
|
|
||||||
// Clear aircraft lookup results
|
// Clear aircraft lookup results
|
||||||
clearOverflightAircraftLookup();
|
clearOverflightAircraftLookup();
|
||||||
clearOverflightDepartureAirportLookup();
|
clearOverflightDepartureAirportLookup();
|
||||||
@@ -4502,6 +4527,9 @@
|
|||||||
|
|
||||||
if (!accessToken) return;
|
if (!accessToken) return;
|
||||||
|
|
||||||
|
// Auto-save any unsaved aircraft types
|
||||||
|
await autoSaveUnsavedAircraft(this);
|
||||||
|
|
||||||
const formData = new FormData(this);
|
const formData = new FormData(this);
|
||||||
const flightType = formData.get('flight_type');
|
const flightType = formData.get('flight_type');
|
||||||
const flightData = {};
|
const flightData = {};
|
||||||
@@ -4585,6 +4613,9 @@
|
|||||||
|
|
||||||
if (!accessToken) return;
|
if (!accessToken) return;
|
||||||
|
|
||||||
|
// Auto-save any unsaved aircraft types
|
||||||
|
await autoSaveUnsavedAircraft(this);
|
||||||
|
|
||||||
const formData = new FormData(this);
|
const formData = new FormData(this);
|
||||||
const arrivalData = {};
|
const arrivalData = {};
|
||||||
|
|
||||||
@@ -4664,6 +4695,9 @@
|
|||||||
|
|
||||||
if (!accessToken) return;
|
if (!accessToken) return;
|
||||||
|
|
||||||
|
// Auto-save any unsaved aircraft types
|
||||||
|
await autoSaveUnsavedAircraft(this);
|
||||||
|
|
||||||
const formData = new FormData(this);
|
const formData = new FormData(this);
|
||||||
const overflightData = {};
|
const overflightData = {};
|
||||||
|
|
||||||
|
|||||||
@@ -692,6 +692,9 @@
|
|||||||
document.getElementById('ppr-form').addEventListener('submit', async function(e) {
|
document.getElementById('ppr-form').addEventListener('submit', async function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Auto-save any unsaved aircraft types
|
||||||
|
await autoSaveUnsavedAircraft(this);
|
||||||
|
|
||||||
const formData = new FormData(this);
|
const formData = new FormData(this);
|
||||||
const pprData = {};
|
const pprData = {};
|
||||||
|
|
||||||
|
|||||||
+137
-4
@@ -163,15 +163,26 @@ function createLookup(fieldId, resultsId, selectCallback, options = {}) {
|
|||||||
const resultsDiv = document.getElementById(resultsId);
|
const resultsDiv = document.getElementById(resultsId);
|
||||||
|
|
||||||
if (config.isAircraft) {
|
if (config.isAircraft) {
|
||||||
// Aircraft lookup: auto-populate on single match, format input on no match
|
// Aircraft lookup: auto-populate on single match, mark form for auto-save on no match
|
||||||
if (!results || results.length === 0) {
|
if (!results || results.length === 0) {
|
||||||
// Format the aircraft registration and auto-populate
|
// Format the aircraft registration
|
||||||
const formatted = formatAircraftRegistration(searchTerm);
|
const formatted = formatAircraftRegistration(searchTerm);
|
||||||
const field = document.getElementById(fieldId);
|
const field = document.getElementById(fieldId);
|
||||||
if (field) {
|
if (field) {
|
||||||
field.value = formatted;
|
field.value = formatted;
|
||||||
|
// Mark the form for auto-saving this aircraft
|
||||||
|
const form = field.closest('form');
|
||||||
|
if (form) {
|
||||||
|
form.setAttribute('data-unsaved-aircraft', fieldId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
resultsDiv.innerHTML = ''; // Clear results, field is auto-populated
|
|
||||||
|
// Show message that type will be saved
|
||||||
|
resultsDiv.innerHTML = `
|
||||||
|
<div class="aircraft-no-match">
|
||||||
|
No match found - aircraft type will be saved automatically when you submit
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
} else if (results.length === 1) {
|
} else if (results.length === 1) {
|
||||||
// Single match - auto-populate
|
// Single match - auto-populate
|
||||||
const aircraft = results[0];
|
const aircraft = results[0];
|
||||||
@@ -183,7 +194,14 @@ function createLookup(fieldId, resultsId, selectCallback, options = {}) {
|
|||||||
|
|
||||||
// Auto-populate the form fields
|
// Auto-populate the form fields
|
||||||
const field = document.getElementById(fieldId);
|
const field = document.getElementById(fieldId);
|
||||||
if (field) field.value = aircraft.registration;
|
if (field) {
|
||||||
|
field.value = aircraft.registration;
|
||||||
|
// Clear the unsaved aircraft flag since we found a match
|
||||||
|
const form = field.closest('form');
|
||||||
|
if (form) {
|
||||||
|
form.removeAttribute('data-unsaved-aircraft');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Also populate type field
|
// Also populate type field
|
||||||
let typeFieldId;
|
let typeFieldId;
|
||||||
@@ -208,6 +226,14 @@ function createLookup(fieldId, resultsId, selectCallback, options = {}) {
|
|||||||
Multiple matches found (${results.length}) - please be more specific
|
Multiple matches found (${results.length}) - please be more specific
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
// Clear the unsaved aircraft flag since multiple matches found
|
||||||
|
const field = document.getElementById(fieldId);
|
||||||
|
if (field) {
|
||||||
|
const form = field.closest('form');
|
||||||
|
if (form) {
|
||||||
|
form.removeAttribute('data-unsaved-aircraft');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Airport lookup: show list of options with keyboard navigation
|
// Airport lookup: show list of options with keyboard navigation
|
||||||
@@ -501,3 +527,110 @@ function selectBookInAircraft(registration) {
|
|||||||
function selectBookInArrivalAirport(icaoCode) {
|
function selectBookInArrivalAirport(icaoCode) {
|
||||||
lookupManager.selectItem('book-in-arrival-airport-lookup-results', 'book_in_from', icaoCode);
|
lookupManager.selectItem('book-in-arrival-airport-lookup-results', 'book_in_from', icaoCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save user aircraft type for future lookups
|
||||||
|
async function saveUserAircraft(registrationFieldId, resultsDivId) {
|
||||||
|
const regField = document.getElementById(registrationFieldId);
|
||||||
|
if (!regField || !regField.value.trim()) {
|
||||||
|
showNotification('Please enter a registration first', true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the type field ID based on registration field
|
||||||
|
let typeFieldId;
|
||||||
|
if (registrationFieldId === 'ac_reg') {
|
||||||
|
typeFieldId = 'ac_type';
|
||||||
|
} else if (registrationFieldId === 'local_registration') {
|
||||||
|
typeFieldId = 'local_type';
|
||||||
|
} else if (registrationFieldId === 'book_in_registration') {
|
||||||
|
typeFieldId = 'book_in_type';
|
||||||
|
} else if (registrationFieldId === 'overflight_registration') {
|
||||||
|
typeFieldId = 'overflight_type';
|
||||||
|
}
|
||||||
|
|
||||||
|
const typeField = document.getElementById(typeFieldId);
|
||||||
|
if (!typeField || !typeField.value.trim()) {
|
||||||
|
showNotification('Please enter an aircraft type first', true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await authenticatedFetch('/api/v1/aircraft/user-aircraft', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
registration: regField.value.trim(),
|
||||||
|
type_code: typeField.value.trim()
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
showNotification('Aircraft type saved for future use');
|
||||||
|
|
||||||
|
// Clear the results div
|
||||||
|
const resultsDiv = document.getElementById(resultsDivId);
|
||||||
|
if (resultsDiv) {
|
||||||
|
resultsDiv.innerHTML = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const error = await response.json();
|
||||||
|
showNotification(error.detail || 'Failed to save aircraft', true);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error saving aircraft:', error);
|
||||||
|
showNotification('Error saving aircraft', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-save unsaved aircraft before form submission
|
||||||
|
async function autoSaveUnsavedAircraft(form) {
|
||||||
|
const unsavedFieldId = form.getAttribute('data-unsaved-aircraft');
|
||||||
|
if (!unsavedFieldId) return; // No unsaved aircraft to save
|
||||||
|
|
||||||
|
const regField = document.getElementById(unsavedFieldId);
|
||||||
|
if (!regField || !regField.value.trim()) return;
|
||||||
|
|
||||||
|
// Determine the type field ID
|
||||||
|
let typeFieldId;
|
||||||
|
if (unsavedFieldId === 'ac_reg') {
|
||||||
|
typeFieldId = 'ac_type';
|
||||||
|
} else if (unsavedFieldId === 'local_registration') {
|
||||||
|
typeFieldId = 'local_type';
|
||||||
|
} else if (unsavedFieldId === 'book_in_registration') {
|
||||||
|
typeFieldId = 'book_in_type';
|
||||||
|
} else if (unsavedFieldId === 'overflight_registration') {
|
||||||
|
typeFieldId = 'overflight_type';
|
||||||
|
}
|
||||||
|
|
||||||
|
const typeField = document.getElementById(typeFieldId);
|
||||||
|
if (!typeField || !typeField.value.trim()) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await authenticatedFetch('/api/v1/aircraft/user-aircraft', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
registration: regField.value.trim(),
|
||||||
|
type_code: typeField.value.trim()
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
// Successfully saved, remove the flag
|
||||||
|
form.removeAttribute('data-unsaved-aircraft');
|
||||||
|
console.log('Auto-saved aircraft type for', regField.value.trim());
|
||||||
|
} else if (response.status === 400) {
|
||||||
|
// Already exists, just remove the flag
|
||||||
|
form.removeAttribute('data-unsaved-aircraft');
|
||||||
|
} else {
|
||||||
|
console.error('Failed to auto-save aircraft');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error auto-saving aircraft:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user