feat: Enhance frontend loading experience and service status handling
Some checks failed
Integration Tests / integration-tests (push) Failing after 20s
Integration Tests / performance-tests (push) Has been skipped
Service Adapters (Python FastAPI) / test (3.11) (push) Failing after 23s
Frontend (React) / test (20) (push) Failing after 1m3s
Frontend (React) / build (push) Has been skipped
Frontend (React) / lighthouse (push) Has been skipped
Service Adapters (Python FastAPI) / test (3.12) (push) Failing after 23s
Service Adapters (Python FastAPI) / test (3.13) (push) Failing after 20s
Service Adapters (Python FastAPI) / build (push) Has been skipped
Some checks failed
Integration Tests / integration-tests (push) Failing after 20s
Integration Tests / performance-tests (push) Has been skipped
Service Adapters (Python FastAPI) / test (3.11) (push) Failing after 23s
Frontend (React) / test (20) (push) Failing after 1m3s
Frontend (React) / build (push) Has been skipped
Frontend (React) / lighthouse (push) Has been skipped
Service Adapters (Python FastAPI) / test (3.12) (push) Failing after 23s
Service Adapters (Python FastAPI) / test (3.13) (push) Failing after 20s
Service Adapters (Python FastAPI) / build (push) Has been skipped
### Summary of Changes - Removed proxy configuration in `rsbuild.config.js` as the API Gateway is not running. - Added smooth transitions and gentle loading overlays in CSS for improved user experience during data loading. - Updated `Dashboard` component to conditionally display loading spinner and gentle loading overlay based on data fetching state. - Enhanced `useOfflineAwareServiceStatus` and `useOfflineAwareSystemData` hooks to manage loading states and service status more effectively. - Increased refresh intervals for service status and system data to reduce API call frequency. ### Expected Results - Improved user experience with smoother loading transitions and better feedback during data refreshes. - Enhanced handling of service status checks, providing clearer information when services are unavailable. - Streamlined code for managing loading states, making it easier to maintain and extend in the future.
This commit is contained in:
@@ -1,9 +1,14 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
from fastapi import APIRouter
|
||||
|
||||
from models.schemas import HealthResponse, RootResponse, ServiceStatus
|
||||
from services.config import SERVICES
|
||||
from services.status_checker import status_checker
|
||||
|
||||
# Configure logger
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@@ -29,9 +34,91 @@ async def root():
|
||||
)
|
||||
async def health_check():
|
||||
"""Check the health status of the service adapters"""
|
||||
logger.debug("Health check endpoint called")
|
||||
return HealthResponse(status="healthy", timestamp=datetime.now().isoformat())
|
||||
|
||||
|
||||
@router.get(
|
||||
"/debug/logging",
|
||||
summary="Logging Debug Info",
|
||||
description="Get current logging configuration and test log levels",
|
||||
tags=["Debug"],
|
||||
)
|
||||
async def debug_logging():
|
||||
"""Debug endpoint to test unified logging configuration"""
|
||||
# Test different log levels
|
||||
logger.debug("This is a DEBUG message from routes.general")
|
||||
logger.info("This is an INFO message from routes.general")
|
||||
logger.warning("This is a WARNING message from routes.general")
|
||||
logger.error("This is an ERROR message from routes.general")
|
||||
|
||||
# Test request logger
|
||||
from services.logging_config import get_request_logger
|
||||
request_logger = get_request_logger()
|
||||
request_logger.info("This is a request logger message")
|
||||
|
||||
# Test application logger
|
||||
from services.logging_config import get_application_logger
|
||||
app_logger = get_application_logger()
|
||||
app_logger.info("This is an application logger message")
|
||||
|
||||
# Get current logging configuration
|
||||
root_logger = logging.getLogger()
|
||||
config_info = {
|
||||
"root_level": logging.getLevelName(root_logger.level),
|
||||
"handlers": [str(h) for h in root_logger.handlers],
|
||||
"handler_count": len(root_logger.handlers),
|
||||
"status_checker_level": logging.getLevelName(logging.getLogger("services.status_checker").level),
|
||||
"general_level": logging.getLevelName(logging.getLogger("routes.general").level),
|
||||
"request_logger_level": logging.getLevelName(request_logger.level),
|
||||
"application_logger_level": logging.getLevelName(app_logger.level),
|
||||
"uvicorn_access_level": logging.getLevelName(logging.getLogger("uvicorn.access").level),
|
||||
}
|
||||
|
||||
logger.info("Unified logging debug info requested")
|
||||
return {
|
||||
"message": "Unified log messages sent to console",
|
||||
"config": config_info,
|
||||
"note": "All logs now use the same format and handler"
|
||||
}
|
||||
|
||||
|
||||
@router.get(
|
||||
"/debug/sensor/{service_name}",
|
||||
summary="Debug Sensor Data",
|
||||
description="Get raw sensor data for debugging health check issues",
|
||||
tags=["Debug"],
|
||||
)
|
||||
async def debug_sensor(service_name: str):
|
||||
"""Debug endpoint to inspect raw sensor data"""
|
||||
from services.config import SERVICES
|
||||
from services.health_checkers import factory
|
||||
|
||||
if service_name not in SERVICES:
|
||||
return {"error": f"Service {service_name} not found"}
|
||||
|
||||
config = SERVICES[service_name]
|
||||
if config.get("health_check_type") != "sensor":
|
||||
return {"error": f"Service {service_name} is not using sensor health checking"}
|
||||
|
||||
try:
|
||||
# Create sensor checker
|
||||
checker = factory.create_checker("sensor", timeout=10.0)
|
||||
|
||||
# Get raw sensor data
|
||||
result = await checker.check_health(service_name, config)
|
||||
|
||||
return {
|
||||
"service_name": service_name,
|
||||
"config": config,
|
||||
"result": result.to_dict(),
|
||||
"raw_sensor_data": result.metadata
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"Error debugging sensor for {service_name}: {e}")
|
||||
return {"error": str(e)}
|
||||
|
||||
|
||||
@router.get(
|
||||
"/services",
|
||||
response_model=dict,
|
||||
@@ -41,11 +128,23 @@ async def health_check():
|
||||
)
|
||||
async def get_services():
|
||||
"""Get status of all configured external services (Home Assistant, Frigate, Immich, n8n)"""
|
||||
logger.info("Service status endpoint called - checking all services")
|
||||
|
||||
# Check all services concurrently
|
||||
status_results = await status_checker.check_all_services()
|
||||
|
||||
service_status = {}
|
||||
for service_name, config in SERVICES.items():
|
||||
status_info = status_results.get(service_name, {})
|
||||
service_status[service_name] = ServiceStatus(
|
||||
enabled=config["enabled"],
|
||||
url=config["url"],
|
||||
status="unknown", # Would check actual service status
|
||||
status=status_info.get("status", "unknown"),
|
||||
response_time=status_info.get("response_time"),
|
||||
error=status_info.get("error"),
|
||||
uptime=status_info.get("uptime"),
|
||||
metadata=status_info.get("metadata", {})
|
||||
)
|
||||
|
||||
logger.info(f"Service status check completed - returning status for {len(service_status)} services")
|
||||
return service_status
|
||||
|
||||
Reference in New Issue
Block a user