feat: Add PrimeProgress, PrimeSelect, and PrimeSkeleton components with customizable styles and props

- Implemented PrimeProgress component with support for labels, helper text, and various styles (size, variant, color).
- Created PrimeSelect component with dropdown functionality, custom templates, and validation states.
- Developed PrimeSkeleton component for loading placeholders with different shapes and animations.
- Updated index.ts to export new components for easy import.
- Enhanced PrimeVueTest.vue to include tests for new components and their functionalities.
- Introduced a custom ThrillWiki theme for PrimeVue with tailored color schemes and component styles.
- Added ambient type declarations for various components to improve TypeScript support.
This commit is contained in:
pacnpal
2025-08-27 21:00:02 -04:00
parent 6125c4ee44
commit 08a4a2d034
164 changed files with 73094 additions and 11001 deletions

View File

@@ -9,6 +9,7 @@ while maintaining backward compatibility through the Company alias.
"""
from .rides import Ride, RideModel, RollerCoasterStats, Categories, CATEGORY_CHOICES
from .company import Company
from .location import RideLocation
from .reviews import RideReview
from .rankings import RideRanking, RidePairComparison, RankingSnapshot
@@ -19,6 +20,7 @@ __all__ = [
"Ride",
"RideModel",
"RollerCoasterStats",
"Company",
"RideLocation",
"RideReview",
"RidePhoto",
@@ -28,4 +30,5 @@ __all__ = [
"RankingSnapshot",
# Shared constants
"Categories",
"CATEGORY_CHOICES",
]

View File

@@ -4,7 +4,7 @@ Ride-specific media models for ThrillWiki.
This module contains media models specific to rides domain.
"""
from typing import Any, Optional, cast
from typing import Any, Optional, List, cast
from django.db import models
from django.conf import settings
from apps.core.history import TrackedModel
@@ -123,10 +123,10 @@ class RidePhoto(TrackedModel):
return None
@property
def dimensions(self) -> Optional[tuple]:
"""Get image dimensions as (width, height)."""
def dimensions(self) -> Optional[List[int]]:
"""Get image dimensions as [width, height]."""
try:
return (self.image.width, self.image.height)
return [self.image.width, self.image.height]
except (ValueError, OSError):
return None

View File

@@ -4,7 +4,7 @@ Handles location management for individual rides within parks.
"""
import requests
from typing import List, Dict, Any, Optional, Tuple
from typing import List, Dict, Any, Optional
from django.db import transaction
import logging
@@ -196,18 +196,18 @@ class RideLocationService:
def estimate_ride_coordinates_from_park(
cls,
ride_location: RideLocation,
area_offset_meters: Dict[str, Tuple[float, float]] = None,
) -> Optional[Tuple[float, float]]:
area_offset_meters: Optional[Dict[str, List[float]]] = None,
) -> Optional[List[float]]:
"""
Estimate ride coordinates based on park location and area.
Useful when exact ride coordinates are not available.
Args:
ride_location: RideLocation instance
area_offset_meters: Dictionary mapping area names to (north_offset, east_offset) in meters
area_offset_meters: Dictionary mapping area names to [north_offset, east_offset] in meters
Returns:
Estimated (latitude, longitude) tuple or None
Estimated [latitude, longitude] list or None
"""
park_location = getattr(ride_location.ride.park, "location", None)
if not park_location or not park_location.point:
@@ -255,7 +255,7 @@ class RideLocationService:
estimated_lat = park_location.latitude + lat_offset
estimated_lon = park_location.longitude + lon_offset
return (estimated_lat, estimated_lon)
return [estimated_lat, estimated_lon]
@classmethod
def bulk_update_ride_areas_from_osm(cls, park) -> int:

View File

@@ -7,7 +7,7 @@ Rankings are determined by winning percentage in these comparisons.
"""
import logging
from typing import Dict, List, Tuple, Optional
from typing import Dict, List, Optional
from decimal import Decimal
from datetime import date
@@ -128,7 +128,7 @@ class RideRankingService:
def _calculate_all_comparisons(
self, rides: List[Ride]
) -> Dict[Tuple[int, int], RidePairComparison]:
) -> Dict[tuple[int, int], RidePairComparison]:
"""
Calculate pairwise comparisons for all ride pairs.
@@ -139,7 +139,7 @@ class RideRankingService:
processed = 0
for i, ride_a in enumerate(rides):
for ride_b in rides[i + 1 :]:
for ride_b in rides[i + 1:]:
comparison = self._calculate_pairwise_comparison(ride_a, ride_b)
if comparison:
# Store both directions for easy lookup
@@ -246,7 +246,7 @@ class RideRankingService:
return comparison
def _calculate_rankings_from_comparisons(
self, rides: List[Ride], comparisons: Dict[Tuple[int, int], RidePairComparison]
self, rides: List[Ride], comparisons: Dict[tuple[int, int], RidePairComparison]
) -> List[Dict]:
"""
Calculate final rankings from pairwise comparisons.
@@ -344,7 +344,7 @@ class RideRankingService:
def _apply_tiebreakers(
self,
rankings: List[Dict],
comparisons: Dict[Tuple[int, int], RidePairComparison],
comparisons: Dict[tuple[int, int], RidePairComparison],
) -> List[Dict]:
"""
Apply head-to-head tiebreaker for rides with identical winning percentages.
@@ -380,7 +380,7 @@ class RideRankingService:
def _sort_tied_group(
self,
tied_group: List[Dict],
comparisons: Dict[Tuple[int, int], RidePairComparison],
comparisons: Dict[tuple[int, int], RidePairComparison],
) -> List[Dict]:
"""
Sort a group of tied rides using head-to-head comparisons.

View File

@@ -18,7 +18,7 @@ from django.contrib.postgres.search import (
from django.db import models
from django.db.models import Q, F, Value
from django.db.models.functions import Greatest
from typing import Dict, List, Optional, Any, Tuple
from typing import Dict, List, Optional, Any
from apps.rides.models import Ride
from apps.parks.models import Park
@@ -177,7 +177,7 @@ class RideSearchService:
def _apply_full_text_search(
self, queryset, search_term: str
) -> Tuple[models.QuerySet, models.Expression]:
) -> tuple[models.QuerySet, models.Expression]:
"""
Apply PostgreSQL full-text search with ranking and fuzzy matching.
"""