feat: implement hx-boost for reliable loading indication

This commit is contained in:
Björn Fromme
2026-03-16 11:59:12 +01:00
parent 602fb31f27
commit 1e107c68b4
32 changed files with 163 additions and 271 deletions
+8 -62
View File
@@ -17,13 +17,11 @@ use Symfony\Contracts\Cache\ItemInterface;
/**
* Handles loading and initializing booking data for edit mode.
*
* Encapsulates the logic for loading booking data from session or API,
* refreshing availability data, and detecting session staleness.
* Encapsulates the logic for loading booking data from session or API
* and refreshing availability data.
*/
class BookingEditDataLoaderService
{
private const STALENESS_THRESHOLD_SECONDS = 300; // 5 minutes
public function __construct(
private readonly ApiClient $apiClient,
private readonly BookingDataProcessor $bookingDataProcessor,
@@ -36,23 +34,19 @@ class BookingEditDataLoaderService
/**
* Loads booking data from session or initializes from API on first load.
*
* @return array{bookingDto: BookingDto|null, stalenessWarning: string|null}
*/
public function loadFormData(Request $request, int $bookingId, string $email, string $password): array
public function loadFormData(Request $request, int $bookingId, string $email, string $password): ?BookingDto
{
$formData = $this->bookingService->getBookingDto($request, BookingDto::MODE_EDIT);
if (null === $formData) {
$bookingDto = $this->initializeFromApi($request, $bookingId, $email, $password);
return [
'bookingDto' => $bookingDto,
'stalenessWarning' => null,
];
return $this->initializeFromApi($request, $bookingId, $email, $password);
}
return $this->refreshFromSession($formData);
// Refresh availability data
$this->travelDataService->enrichWithFreshAvailabilities($formData->travel);
return $formData;
}
/**
@@ -91,25 +85,6 @@ class BookingEditDataLoaderService
return $formData;
}
/**
* Refreshes booking data loaded from session with latest availability.
*
* @return array{bookingDto: BookingDto, stalenessWarning: string|null}
*/
public function refreshFromSession(BookingDto $formData): array
{
// Refresh availability data
$this->travelDataService->enrichWithFreshAvailabilities($formData->travel);
// Check for staleness
$stalenessWarning = $this->getStalenessWarning($formData);
return [
'bookingDto' => $formData,
'stalenessWarning' => $stalenessWarning,
];
}
/**
* Fetches booking data from API with caching.
*/
@@ -139,33 +114,4 @@ class BookingEditDataLoaderService
// Ignore cache deletion errors
}
}
/**
* Resets the staleness timer on the booking DTO.
*/
public function resetStalenessTimer(Request $request, BookingDto $bookingDto): void
{
$bookingDto->lastSessionUpdate = new \DateTimeImmutable();
$this->bookingService->saveBookingDto($request, $bookingDto, BookingDto::MODE_EDIT);
}
/**
* Generates a staleness warning message if session is older than threshold.
*/
private function getStalenessWarning(BookingDto $formData): ?string
{
if (null === $formData->lastSessionUpdate) {
return null;
}
$ageInSeconds = (new \DateTimeImmutable())->getTimestamp() - $formData->lastSessionUpdate->getTimestamp();
if ($ageInSeconds <= self::STALENESS_THRESHOLD_SECONDS) {
return null;
}
$minutes = (int) ceil($ageInSeconds / 60);
return sprintf('Sie bearbeiten diese Buchung seit %d Minuten. Die Daten könnten veraltet sein.', $minutes);
}
}
-3
View File
@@ -93,9 +93,6 @@ class BookingService
*/
public function saveBookingDto(Request $request, BookingDto $bookingDto, string $mode): void
{
// Track last session update for staleness detection
$bookingDto->lastSessionUpdate = new \DateTimeImmutable();
$sessionKey = $this->getSessionKey($mode);
$request->getSession()->set($sessionKey, $bookingDto);
}