From a21be9ec5588f0902970fc55f7b67eaca152920f Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 11 Mar 2025 17:43:34 +0200 Subject: [PATCH] wip --- .../trip-detail/trip-detail.component.html | 34 +++++ .../trip/trip-detail/trip-detail.component.ts | 128 +++++++++++++++++- httpdocs/src/Entity/UserTrip.php | 7 +- .../src/Mapper/UserTripApiToEntityMapper.php | 3 +- 4 files changed, 159 insertions(+), 13 deletions(-) diff --git a/angular/src/app/_views/trip/trip-detail/trip-detail.component.html b/angular/src/app/_views/trip/trip-detail/trip-detail.component.html index f6eefbc..b79ba61 100644 --- a/angular/src/app/_views/trip/trip-detail/trip-detail.component.html +++ b/angular/src/app/_views/trip/trip-detail/trip-detail.component.html @@ -90,7 +90,41 @@ +
+

{{ 'trip.user_assignments' | translate }}

+ +
+
+
+ + + +
+
+ +
+
+
+ +
+ +
+ +
+ +
+
diff --git a/angular/src/app/_views/trip/trip-detail/trip-detail.component.ts b/angular/src/app/_views/trip/trip-detail/trip-detail.component.ts index 0cf155d..f2b7fce 100644 --- a/angular/src/app/_views/trip/trip-detail/trip-detail.component.ts +++ b/angular/src/app/_views/trip/trip-detail/trip-detail.component.ts @@ -30,6 +30,8 @@ export class TripDetailComponent implements OnInit, AfterViewInit { protected users: UserJsonld[] = []; protected locationForms: FormGroup[] = []; protected locationColDefinitions: ListColDefinition[] = SearchSelectComponent.getDefaultColDefLocations(); + protected userForms: FormGroup[] = []; + protected userColDefinitions: ListColDefinition[] = SearchSelectComponent.getDefaultColDefUsers(); @ViewChildren(SearchSelectComponent) searchSelects!: QueryList; @@ -50,13 +52,7 @@ export class TripDetailComponent implements OnInit, AfterViewInit { data => { this.trip = data; this.loadTripLocations(); - this.userTripService.userTripsGetCollection( - ).subscribe( - data => { - this.userTrips = data.member; - console.log(this.userTrips); - } - ) + this.loadUserTrips(); // Verwenden Sie die neue loadUserTrips-Methode } ); }); @@ -97,10 +93,20 @@ export class TripDetailComponent implements OnInit, AfterViewInit { }); } + createUserForm(): FormGroup { + return this.fb.group({ + user: [null] + }); + } + getLocations = (page: number, pageSize: number, term?: string): Observable => { return this.locationService.locationsGetCollection(page, pageSize, undefined, term); } + getUsers = (page: number, pageSize: number, term?: string): Observable => { + return this.userService.usersGetCollection(page, pageSize, undefined, term); + } + onFormUpdate(event: FormSubmitEvent) { if (event.status === ModalStatus.Submitted && event.data) { this.trip = event.data; @@ -166,6 +172,46 @@ export class TripDetailComponent implements OnInit, AfterViewInit { }); } + addNewUserTrip() { + // Create a new empty user trip + const newUserTrip: UserTripJsonld = { + trip: { + 'id': this.trip.id + } as TripJsonld, + // No default user set + }; + + this.userTrips.push(newUserTrip); + this.userForms.push(this.createUserForm()); + + // Force update in the next event loop to properly initialize the search-select + setTimeout(() => { + if (this.searchSelects) { + const lastSelect = this.searchSelects.last; + if (lastSelect) { + lastSelect.ngAfterViewInit(); + } + } + }); + } + + loadUserTrips() { + this.userTripService.userTripsGetCollection( + 1, + 200, + this.trip !== undefined ? this.trip.id : undefined, + ).subscribe( + data => { + this.userTrips = data.member; + // Create a form for each user trip + this.userForms = []; + this.userTrips.forEach(() => { + this.userForms.push(this.createUserForm()); + }); + } + ); + } + removeTripLocation(index: number) { const tripLocationId = this.tripLocations[index].id; @@ -184,6 +230,24 @@ export class TripDetailComponent implements OnInit, AfterViewInit { } } + removeUserTrip(index: number) { + const userTripId = this.userTrips[index].id; + + if (userTripId) { + // If it exists on the server, delete it + this.userTripService.userTripsIdDelete(this.appHelperService.extractId(userTripId)).subscribe( + () => { + this.userTrips.splice(index, 1); + this.userForms.splice(index, 1); + } + ); + } else { + // If it's only local, just remove it from the array + this.userTrips.splice(index, 1); + this.userForms.splice(index, 1); + } + } + saveAllTripLocations() { // First update the location objects in our tripLocations array this.tripLocations.forEach((tripLocation, index) => { @@ -233,4 +297,54 @@ export class TripDetailComponent implements OnInit, AfterViewInit { console.error('Error saving trip locations:', error); }); } + + saveAllUserTrips() { + // First update the user objects in our userTrips array + this.userTrips.forEach((userTrip, index) => { + const userFormValue = this.userForms[index].get('user')?.value; + + // Ensure we have a user + if (userFormValue) { + // If just an ID was set, create a proper user object + if (typeof userFormValue === 'string') { + userTrip.user = { + 'id': userFormValue + } as UserJsonld; + } + } else { + // If no user is set, show an error + return; + } + }); + + // Filter out user trips that have no user set + const validUserTrips = this.userTrips.filter(ut => ut.user); + + if (validUserTrips.length === 0) { + return; + } + + // Save all user trips + const savePromises = validUserTrips.map(userTrip => { + if (userTrip.id) { + // Update existing + return firstValueFrom(this.userTripService.userTripsIdPatch( + this.appHelperService.extractId(userTrip.id), + userTrip + )); + } else { + // Create new + return firstValueFrom(this.userTripService.userTripsPost(userTrip)); + } + }); + + Promise.all(savePromises) + .then(() => { + // Reload user trips to get updated data + this.loadUserTrips(); + }) + .catch(error => { + console.error('Error saving user trips:', error); + }); + } } \ No newline at end of file diff --git a/httpdocs/src/Entity/UserTrip.php b/httpdocs/src/Entity/UserTrip.php index 85aca36..a872cb3 100644 --- a/httpdocs/src/Entity/UserTrip.php +++ b/httpdocs/src/Entity/UserTrip.php @@ -35,7 +35,7 @@ class UserTrip private ?MediaObject $signature = null; #[ORM\Column(nullable: true)] - private DateTimeImmutable $completedDate; + private ?DateTimeImmutable $completedDate; #[ORM\Column] private DateTimeImmutable $createdAt; @@ -100,15 +100,14 @@ class UserTrip $this->signature = $signature; } - public function getCompletedDate(): DateTimeImmutable + public function getCompletedDate(): ?DateTimeImmutable { return $this->completedDate; } - public function setCompletedDate(DateTimeImmutable $completedDate): self + public function setCompletedDate(?DateTimeImmutable $completedDate): void { $this->completedDate = $completedDate; - return $this; } public function getUserTripEvents(): Collection diff --git a/httpdocs/src/Mapper/UserTripApiToEntityMapper.php b/httpdocs/src/Mapper/UserTripApiToEntityMapper.php index 10a40d3..93f3ed1 100644 --- a/httpdocs/src/Mapper/UserTripApiToEntityMapper.php +++ b/httpdocs/src/Mapper/UserTripApiToEntityMapper.php @@ -63,8 +63,7 @@ class UserTripApiToEntityMapper implements MapperInterface assert($entity instanceof UserTrip); $entity->setCaptainName($dto->captainName); - $entity->setStartDate($dto->startDate); - $entity->setCompletedDate($dto->endDate); + $entity->setCompletedDate($dto->completedDate); return $entity; }