| @@ -1685,6 +1685,18 @@ paths: | |||||
| style: form | style: form | ||||
| explode: true | explode: true | ||||
| allowReserved: false | allowReserved: false | ||||
| - | |||||
| name: tripId | |||||
| in: query | |||||
| description: 'Filter UserTripEvents by Trip ID' | |||||
| required: false | |||||
| deprecated: false | |||||
| allowEmptyValue: false | |||||
| schema: | |||||
| type: integer | |||||
| style: form | |||||
| explode: false | |||||
| allowReserved: false | |||||
| - | - | ||||
| name: custom_json_filter | name: custom_json_filter | ||||
| in: query | in: query | ||||
| @@ -2327,6 +2339,9 @@ components: | |||||
| type: string | type: string | ||||
| code: | code: | ||||
| type: string | type: string | ||||
| zoneName: | |||||
| readOnly: true | |||||
| type: string | |||||
| isZone: | isZone: | ||||
| type: boolean | type: boolean | ||||
| isPlace: | isPlace: | ||||
| @@ -2389,6 +2404,9 @@ components: | |||||
| type: string | type: string | ||||
| code: | code: | ||||
| type: string | type: string | ||||
| zoneName: | |||||
| readOnly: true | |||||
| type: string | |||||
| isZone: | isZone: | ||||
| type: boolean | type: boolean | ||||
| isPlace: | isPlace: | ||||
| @@ -2405,31 +2423,6 @@ components: | |||||
| - zoneIri | - zoneIri | ||||
| - name | - name | ||||
| - code | - code | ||||
| MediaObject: | |||||
| type: object | |||||
| description: '' | |||||
| deprecated: false | |||||
| properties: | |||||
| id: | |||||
| readOnly: true | |||||
| type: integer | |||||
| file: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| format: binary | |||||
| filePath: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| createdBy: | |||||
| $ref: '#/components/schemas/User' | |||||
| createdAt: | |||||
| readOnly: true | |||||
| type: string | |||||
| format: date-time | |||||
| required: | |||||
| - file | |||||
| MediaObject.jsonld: | MediaObject.jsonld: | ||||
| type: object | type: object | ||||
| description: '' | description: '' | ||||
| @@ -2849,11 +2842,16 @@ components: | |||||
| lastName: | lastName: | ||||
| type: string | type: string | ||||
| image: | image: | ||||
| anyOf: | |||||
| - | |||||
| $ref: '#/components/schemas/MediaObject' | |||||
| - | |||||
| type: 'null' | |||||
| readOnly: true | |||||
| type: string | |||||
| format: iri-reference | |||||
| example: 'https://example.com/' | |||||
| imageIri: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| format: iri-reference | |||||
| example: 'https://example.com/' | |||||
| imageUrl: | imageUrl: | ||||
| readOnly: true | readOnly: true | ||||
| type: | type: | ||||
| @@ -2867,7 +2865,9 @@ components: | |||||
| password: | password: | ||||
| writeOnly: true | writeOnly: true | ||||
| description: 'The plaintext password when being set or changed.' | description: 'The plaintext password when being set or changed.' | ||||
| type: string | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| active: | active: | ||||
| type: boolean | type: boolean | ||||
| roles: | roles: | ||||
| @@ -2931,11 +2931,14 @@ components: | |||||
| lastName: | lastName: | ||||
| type: string | type: string | ||||
| image: | image: | ||||
| anyOf: | |||||
| - | |||||
| $ref: '#/components/schemas/MediaObject.jsonld' | |||||
| - | |||||
| type: 'null' | |||||
| readOnly: true | |||||
| $ref: '#/components/schemas/MediaObject.jsonld' | |||||
| imageIri: | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| format: iri-reference | |||||
| example: 'https://example.com/' | |||||
| imageUrl: | imageUrl: | ||||
| readOnly: true | readOnly: true | ||||
| type: | type: | ||||
| @@ -2949,7 +2952,9 @@ components: | |||||
| password: | password: | ||||
| writeOnly: true | writeOnly: true | ||||
| description: 'The plaintext password when being set or changed.' | description: 'The plaintext password when being set or changed.' | ||||
| type: string | |||||
| type: | |||||
| - string | |||||
| - 'null' | |||||
| active: | active: | ||||
| type: boolean | type: boolean | ||||
| roles: | roles: | ||||
| @@ -3164,6 +3169,11 @@ components: | |||||
| - 'null' | - 'null' | ||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| user: | |||||
| readOnly: true | |||||
| type: string | |||||
| format: iri-reference | |||||
| example: 'https://example.com/' | |||||
| date: | date: | ||||
| type: string | type: string | ||||
| format: date-time | format: date-time | ||||
| @@ -3242,6 +3252,9 @@ components: | |||||
| - 'null' | - 'null' | ||||
| format: iri-reference | format: iri-reference | ||||
| example: 'https://example.com/' | example: 'https://example.com/' | ||||
| user: | |||||
| readOnly: true | |||||
| $ref: '#/components/schemas/User.jsonld' | |||||
| date: | date: | ||||
| type: string | type: string | ||||
| format: date-time | format: date-time | ||||
| @@ -15,6 +15,7 @@ export const locationForm = new FormGroup({ | |||||
| zoneIri: new FormControl(null, [Validators.required]), | zoneIri: new FormControl(null, [Validators.required]), | ||||
| name: new FormControl(null, [Validators.required]), | name: new FormControl(null, [Validators.required]), | ||||
| code: new FormControl(null, [Validators.required]), | code: new FormControl(null, [Validators.required]), | ||||
| zoneName: new FormControl(null, []), | |||||
| isZone: new FormControl(null, []), | isZone: new FormControl(null, []), | ||||
| isPlace: new FormControl(null, []), | isPlace: new FormControl(null, []), | ||||
| isPort: new FormControl(null, []), | isPort: new FormControl(null, []), | ||||
| @@ -27,20 +28,13 @@ export const locationJsonldForm = new FormGroup({ | |||||
| zoneIri: new FormControl(null, [Validators.required]), | zoneIri: new FormControl(null, [Validators.required]), | ||||
| name: new FormControl(null, [Validators.required]), | name: new FormControl(null, [Validators.required]), | ||||
| code: new FormControl(null, [Validators.required]), | code: new FormControl(null, [Validators.required]), | ||||
| zoneName: new FormControl(null, []), | |||||
| isZone: new FormControl(null, []), | isZone: new FormControl(null, []), | ||||
| isPlace: new FormControl(null, []), | isPlace: new FormControl(null, []), | ||||
| isPort: new FormControl(null, []), | isPort: new FormControl(null, []), | ||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| }); | }); | ||||
| export const mediaObjectForm = new FormGroup({ | |||||
| id: new FormControl(null, []), | |||||
| file: new FormControl(null, [Validators.required]), | |||||
| filePath: new FormControl(null, []), | |||||
| createdBy: new FormControl(null, []), | |||||
| createdAt: new FormControl(null, []) | |||||
| }); | |||||
| export const mediaObjectJsonldForm = new FormGroup({ | export const mediaObjectJsonldForm = new FormGroup({ | ||||
| dbId: new FormControl(null, []), | dbId: new FormControl(null, []), | ||||
| contentUrl: new FormControl(null, []), | contentUrl: new FormControl(null, []), | ||||
| @@ -125,6 +119,7 @@ export const userForm = new FormGroup({ | |||||
| referenceId: new FormControl(null, [Validators.required]), | referenceId: new FormControl(null, [Validators.required]), | ||||
| lastName: new FormControl(null, [Validators.required]), | lastName: new FormControl(null, [Validators.required]), | ||||
| image: new FormControl(null, []), | image: new FormControl(null, []), | ||||
| imageIri: new FormControl(null, []), | |||||
| imageUrl: new FormControl(null, []), | imageUrl: new FormControl(null, []), | ||||
| fullName: new FormControl(null, []), | fullName: new FormControl(null, []), | ||||
| password: new FormControl(null, []), | password: new FormControl(null, []), | ||||
| @@ -140,6 +135,7 @@ export const userJsonldForm = new FormGroup({ | |||||
| referenceId: new FormControl(null, [Validators.required]), | referenceId: new FormControl(null, [Validators.required]), | ||||
| lastName: new FormControl(null, [Validators.required]), | lastName: new FormControl(null, [Validators.required]), | ||||
| image: new FormControl(null, []), | image: new FormControl(null, []), | ||||
| imageIri: new FormControl(null, []), | |||||
| imageUrl: new FormControl(null, []), | imageUrl: new FormControl(null, []), | ||||
| fullName: new FormControl(null, []), | fullName: new FormControl(null, []), | ||||
| password: new FormControl(null, []), | password: new FormControl(null, []), | ||||
| @@ -186,6 +182,7 @@ export const userTripEventForm = new FormGroup({ | |||||
| eventIri: new FormControl(null, [Validators.required]), | eventIri: new FormControl(null, [Validators.required]), | ||||
| location: new FormControl(null, []), | location: new FormControl(null, []), | ||||
| locationIri: new FormControl(null, [Validators.required]), | locationIri: new FormControl(null, [Validators.required]), | ||||
| user: new FormControl(null, []), | |||||
| date: new FormControl(null, [Validators.required]), | date: new FormControl(null, [Validators.required]), | ||||
| note: new FormControl(null, []), | note: new FormControl(null, []), | ||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| @@ -199,6 +196,7 @@ export const userTripEventJsonldForm = new FormGroup({ | |||||
| eventIri: new FormControl(null, [Validators.required]), | eventIri: new FormControl(null, [Validators.required]), | ||||
| location: new FormControl(null, []), | location: new FormControl(null, []), | ||||
| locationIri: new FormControl(null, [Validators.required]), | locationIri: new FormControl(null, [Validators.required]), | ||||
| user: new FormControl(null, []), | |||||
| date: new FormControl(null, [Validators.required]), | date: new FormControl(null, [Validators.required]), | ||||
| note: new FormControl(null, []), | note: new FormControl(null, []), | ||||
| createdAt: new FormControl(null, []) | createdAt: new FormControl(null, []) | ||||
| @@ -127,6 +127,14 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </mat-tab> | </mat-tab> | ||||
| <mat-tab label="{{ 'trip.events' | translate }}"> | |||||
| <div> | |||||
| <app-user-trip-event-list | |||||
| [trip]="trip" | |||||
| > | |||||
| </app-user-trip-event-list> | |||||
| </div> | |||||
| </mat-tab> | |||||
| </mat-tab-group> | </mat-tab-group> | ||||
| } | } | ||||
| @@ -7,7 +7,7 @@ import { | |||||
| TripService, | TripService, | ||||
| LocationService, | LocationService, | ||||
| LocationJsonld, | LocationJsonld, | ||||
| UserTripService, UserService, UserTripJsonld, UserJsonld | |||||
| UserTripService, UserService, UserTripJsonld, UserJsonld, UserTripEventJsonld, UserTripEventService | |||||
| } from "@app/core/api/v1"; | } from "@app/core/api/v1"; | ||||
| import { AppHelperService } from "@app/_helpers/app-helper.service"; | import { AppHelperService } from "@app/_helpers/app-helper.service"; | ||||
| import { ActivatedRoute } from "@angular/router"; | import { ActivatedRoute } from "@angular/router"; | ||||
| @@ -29,6 +29,7 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| protected originalUserTrips: UserTripJsonld[] = []; | protected originalUserTrips: UserTripJsonld[] = []; | ||||
| protected tripLocations: TripLocationJsonld[] = []; | protected tripLocations: TripLocationJsonld[] = []; | ||||
| protected userTrips: UserTripJsonld[] = []; | protected userTrips: UserTripJsonld[] = []; | ||||
| protected userTripEvents: UserTripEventJsonld[] = []; | |||||
| protected users: UserJsonld[] = []; | protected users: UserJsonld[] = []; | ||||
| protected locationForms: FormGroup[] = []; | protected locationForms: FormGroup[] = []; | ||||
| protected locationColDefinitions: ListColDefinition[] = SearchSelectComponent.getDefaultColDefLocations(); | protected locationColDefinitions: ListColDefinition[] = SearchSelectComponent.getDefaultColDefLocations(); | ||||
| @@ -42,6 +43,7 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| private tripLocationService: TripLocationService, | private tripLocationService: TripLocationService, | ||||
| private locationService: LocationService, | private locationService: LocationService, | ||||
| private userTripService: UserTripService, | private userTripService: UserTripService, | ||||
| private userTripEventService: UserTripEventService, | |||||
| private userService: UserService, | private userService: UserService, | ||||
| protected appHelperService: AppHelperService, | protected appHelperService: AppHelperService, | ||||
| private route: ActivatedRoute, | private route: ActivatedRoute, | ||||
| @@ -54,7 +56,8 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| data => { | data => { | ||||
| this.trip = data; | this.trip = data; | ||||
| this.loadTripLocations(); | this.loadTripLocations(); | ||||
| this.loadUserTrips(); // Verwenden Sie die neue loadUserTrips-Methode | |||||
| this.loadUserTrips(); | |||||
| this.loadUserTripEvents(); | |||||
| } | } | ||||
| ); | ); | ||||
| }); | }); | ||||
| @@ -263,6 +266,20 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| }); | }); | ||||
| } | } | ||||
| loadUserTripEvents() { | |||||
| this.userTripEventService.userTripEventsGetCollection( | |||||
| 1, | |||||
| 200, | |||||
| undefined, | |||||
| undefined, | |||||
| this.trip.dbId!, | |||||
| ).subscribe({ | |||||
| next: (data) => { | |||||
| this.userTripEvents = data.member; | |||||
| } | |||||
| }) | |||||
| } | |||||
| removeTripLocation(index: number) { | removeTripLocation(index: number) { | ||||
| const tripLocationId = this.tripLocations[index].id; | const tripLocationId = this.tripLocations[index].id; | ||||
| @@ -0,0 +1,7 @@ | |||||
| <div class="spt-container"> | |||||
| <app-list #listComponent | |||||
| [listId]="'userTripEventList'" | |||||
| [getDataFunction]="getData" | |||||
| [listColDefinitions]="listColDefinitions" | |||||
| ></app-list> | |||||
| </div> | |||||
| @@ -0,0 +1,23 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { UserTripEventListComponent } from './user-trip-event-list.component'; | |||||
| describe('UserTripEventListComponent', () => { | |||||
| let component: UserTripEventListComponent; | |||||
| let fixture: ComponentFixture<UserTripEventListComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [UserTripEventListComponent] | |||||
| }) | |||||
| .compileComponents(); | |||||
| fixture = TestBed.createComponent(UserTripEventListComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,103 @@ | |||||
| import {Component, Input, ViewChild} from '@angular/core'; | |||||
| import {ListComponent} from "@app/_components/list/list.component"; | |||||
| import {ListColDefinition} from "@app/_components/list/list-col-definition"; | |||||
| import {TripJsonld, UserTripEventService} from "@app/core/api/v1"; | |||||
| import {AppHelperService} from "@app/_helpers/app-helper.service"; | |||||
| import {FilterBarComponent} from "@app/_components/filter-bar/filter-bar.component"; | |||||
| import {ListGetDataFunctionType} from "@app/_components/list/list-get-data-function-type"; | |||||
| @Component({ | |||||
| selector: 'app-user-trip-event-list', | |||||
| templateUrl: './user-trip-event-list.component.html', | |||||
| styleUrl: './user-trip-event-list.component.scss' | |||||
| }) | |||||
| export class UserTripEventListComponent { | |||||
| @ViewChild("listComponent", {static: false}) listComponent!: ListComponent; | |||||
| @Input() public trip?: TripJsonld; | |||||
| protected listColDefinitions!: ListColDefinition[]; | |||||
| constructor( | |||||
| private userTripEventService: UserTripEventService, | |||||
| protected appHelperService: AppHelperService, | |||||
| ) { | |||||
| this.listColDefinitions = [ | |||||
| { | |||||
| name: 'eventName', | |||||
| text: 'model.event', | |||||
| type: ListComponent.COLUMN_TYPE_TEXT_BOLD, | |||||
| subResource: 'event', | |||||
| field: 'name', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'user', | |||||
| text: 'model.user', | |||||
| type: ListComponent.COLUMN_TYPE_TEXT, | |||||
| subResource: 'user', | |||||
| field: 'fullName', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'location', | |||||
| text: 'model.location', | |||||
| type: ListComponent.COLUMN_TYPE_TEXT_BOLD, | |||||
| field: 'name', | |||||
| subResource: 'location', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'zone', | |||||
| text: 'model.zone', | |||||
| type: ListComponent.COLUMN_TYPE_TEXT, | |||||
| field: 'zoneName', | |||||
| subResource: 'location', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_TEXT, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'date', | |||||
| text: 'basic.date', | |||||
| type: ListComponent.COLUMN_TYPE_DATE, | |||||
| field: 'date', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_DATE, | |||||
| } as ListColDefinition, | |||||
| { | |||||
| name: 'createdAt', | |||||
| text: 'common.created_at', | |||||
| type: ListComponent.COLUMN_TYPE_DATE, | |||||
| field: 'createdAt', | |||||
| sortable: true, | |||||
| filterType: FilterBarComponent.FILTER_TYPE_DATE, | |||||
| } as ListColDefinition, | |||||
| ]; | |||||
| } | |||||
| ngOnInit() { | |||||
| } | |||||
| ngAfterViewInit(): void { | |||||
| this.listComponent.getData(); | |||||
| } | |||||
| getData: ListGetDataFunctionType = ( | |||||
| index: number, | |||||
| pageSize: number, | |||||
| term?: string, | |||||
| ) => { | |||||
| return this.userTripEventService.userTripEventsGetCollection( | |||||
| index, | |||||
| pageSize, | |||||
| undefined, | |||||
| undefined, | |||||
| this.trip !== undefined ? this.trip.dbId! : undefined, | |||||
| this.listComponent.getFilterJsonString(), | |||||
| this.listComponent.getSortingJsonString() | |||||
| ); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1 @@ | |||||
| <p>user-trip-event works!</p> | |||||
| @@ -0,0 +1,23 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { UserTripEventComponent } from './user-trip-event.component'; | |||||
| describe('UserTripEventComponent', () => { | |||||
| let component: UserTripEventComponent; | |||||
| let fixture: ComponentFixture<UserTripEventComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [UserTripEventComponent] | |||||
| }) | |||||
| .compileComponents(); | |||||
| fixture = TestBed.createComponent(UserTripEventComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,10 @@ | |||||
| import { Component } from '@angular/core'; | |||||
| @Component({ | |||||
| selector: 'app-user-trip-event', | |||||
| templateUrl: './user-trip-event.component.html', | |||||
| styleUrl: './user-trip-event.component.scss' | |||||
| }) | |||||
| export class UserTripEventComponent { | |||||
| } | |||||
| @@ -78,11 +78,6 @@ export class UserTripFormComponent extends AbstractDataFormComponent<UserTripJso | |||||
| } | } | ||||
| } | } | ||||
| getFileNameFromUrl(url: string | null | undefined): string { | |||||
| if (!url) return ''; | |||||
| return url.split('/').pop() || ''; | |||||
| } | |||||
| markSignatureForRemoval(): void { | markSignatureForRemoval(): void { | ||||
| // Speichere die aktuelle signatureIri, um sie später zu löschen | // Speichere die aktuelle signatureIri, um sie später zu löschen | ||||
| this.signatureToDelete = this.form.get('signatureIri')?.value; | this.signatureToDelete = this.form.get('signatureIri')?.value; | ||||
| @@ -4,6 +4,16 @@ | |||||
| </div> | </div> | ||||
| <mat-tab-group> | <mat-tab-group> | ||||
| <mat-tab label="{{ 'basic.details' | translate }}"> | <mat-tab label="{{ 'basic.details' | translate }}"> | ||||
| <app-user-form | |||||
| [data]="user" | |||||
| [mode]="FormMode.Edit" | |||||
| [id]="appHelperService.extractId(user.id!)" | |||||
| (submit)="onFormUpdate($event)" | |||||
| > | |||||
| </app-user-form> | |||||
| <div class="card contacts-detail"> | <div class="card contacts-detail"> | ||||
| <div class="card-body row"> | <div class="card-body row"> | ||||
| <div class="spt-col col-12 col-sm-6 col-lg-8"> | <div class="spt-col col-12 col-sm-6 col-lg-8"> | ||||
| @@ -3,6 +3,7 @@ import {UserJsonld, UserService} from "@app/core/api/v1"; | |||||
| import {AccountService} from "@app/_services"; | import {AccountService} from "@app/_services"; | ||||
| import {AppHelperService} from "@app/_helpers/app-helper.service"; | import {AppHelperService} from "@app/_helpers/app-helper.service"; | ||||
| import {ActivatedRoute} from "@angular/router"; | import {ActivatedRoute} from "@angular/router"; | ||||
| import {FormMode} from "@app/_components/_abstract/abstract-data-form-component"; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-user-detail', | selector: 'app-user-detail', | ||||
| @@ -54,4 +55,6 @@ export class UserDetailComponent implements OnInit, AfterViewInit { | |||||
| this.isCurrentUser = this.appHelperService.extractId(this.user.id) == user?.id; | this.isCurrentUser = this.appHelperService.extractId(this.user.id) == user?.id; | ||||
| } | } | ||||
| } | } | ||||
| protected readonly FormMode = FormMode; | |||||
| } | } | ||||
| @@ -0,0 +1,42 @@ | |||||
| <div class="spt-container"> | |||||
| @if (!isEditMode()) { | |||||
| <div class="spt-headline d-flex justify-content-between align-items-start"> | |||||
| <h2>{{ ('basic.new') | translate }} {{ 'model.user' | translate }}</h2> | |||||
| </div> | |||||
| } | |||||
| <div class="spt-form"> | |||||
| <form [formGroup]="userForm" (ngSubmit)="onSubmit()"> | |||||
| <div class="mb-3"> | |||||
| <label for="email" class="form-label">{{ 'users.email' | translate }}:</label> | |||||
| <input type="text" class="form-control" id="email" formControlName="email"/> | |||||
| </div> | |||||
| <div class="mb-3"> | |||||
| <label for="lastName" class="form-label">{{ 'users.lastname' | translate }}:</label> | |||||
| <input type="text" class="form-control" id="lastName" formControlName="lastName"/> | |||||
| </div> | |||||
| <div class="mb-3"> | |||||
| <label for="referenceId" class="form-label">{{ 'users.pilotIdNo' | translate }}:</label> | |||||
| <input type="text" class="form-control" id="referenceId" formControlName="referenceId"/> | |||||
| </div> | |||||
| <div class="mb-3"> | |||||
| <label for="password" class="form-label">{{ 'users.password' | translate }}:</label> | |||||
| <input type="text" class="form-control" id="password" formControlName="password"/> | |||||
| </div> | |||||
| <div class="flex gap-2"> | |||||
| <button type="submit" class="btn btn-primary" [disabled]="form.invalid"> | |||||
| {{ 'basic.save' | translate }} | |||||
| </button> | |||||
| @if (isEditMode()) { | |||||
| <button type="button" class="ms-3 btn btn-primary" (click)="onDelete()"> | |||||
| {{ 'basic.delete' | translate }} {{ 'model.trip' | translate }} | |||||
| </button> | |||||
| } | |||||
| </div> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| @@ -0,0 +1,23 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { UserFormComponent } from './user-form.component'; | |||||
| describe('UserFormComponent', () => { | |||||
| let component: UserFormComponent; | |||||
| let fixture: ComponentFixture<UserFormComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [UserFormComponent] | |||||
| }) | |||||
| .compileComponents(); | |||||
| fixture = TestBed.createComponent(UserFormComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,40 @@ | |||||
| import { Component } from '@angular/core'; | |||||
| import {AbstractDataFormComponent} from "@app/_components/_abstract/abstract-data-form-component"; | |||||
| import {UserJsonld, UserService} from "@app/core/api/v1"; | |||||
| import {AppHelperService} from "@app/_helpers/app-helper.service"; | |||||
| import {TranslateService} from "@ngx-translate/core"; | |||||
| import {Router} from "@angular/router"; | |||||
| import {ROUTE_USERS} from "@app/app-routing.module"; | |||||
| import {userForm} from "@app/_forms/apiForms"; | |||||
| @Component({ | |||||
| selector: 'app-user-form', | |||||
| templateUrl: './user-form.component.html', | |||||
| styleUrl: './user-form.component.scss' | |||||
| }) | |||||
| export class UserFormComponent extends AbstractDataFormComponent<UserJsonld> { | |||||
| protected readonly userForm = userForm; | |||||
| constructor( | |||||
| private userService: UserService, | |||||
| private appHelperService: AppHelperService, | |||||
| translateService: TranslateService, | |||||
| router: Router | |||||
| ) { | |||||
| super( | |||||
| userForm, | |||||
| (data: UserJsonld) => this.userService.usersPost(data), | |||||
| (id: string | number, data: UserJsonld) => | |||||
| this.userService.usersIdPatch( | |||||
| id.toString(), | |||||
| this.appHelperService.convertJsonldToJson(data) | |||||
| ), | |||||
| (id: string | number) => this.userService.usersIdDelete(id.toString()), | |||||
| translateService, | |||||
| router | |||||
| ); | |||||
| this.redirectAfterDelete = '/' + ROUTE_USERS; | |||||
| } | |||||
| } | |||||
| @@ -67,6 +67,9 @@ import { UserTripComponent } from './_views/user-trip/user-trip.component'; | |||||
| import { UserTripListComponent } from './_views/user-trip/user-trip-list/user-trip-list.component'; | import { UserTripListComponent } from './_views/user-trip/user-trip-list/user-trip-list.component'; | ||||
| import { UserTripDetailComponent } from './_views/user-trip/user-trip-detail/user-trip-detail.component'; | import { UserTripDetailComponent } from './_views/user-trip/user-trip-detail/user-trip-detail.component'; | ||||
| import { UserTripFormComponent } from './_views/user-trip/user-trip-form/user-trip-form.component'; | import { UserTripFormComponent } from './_views/user-trip/user-trip-form/user-trip-form.component'; | ||||
| import { UserTripEventComponent } from './_views/user-trip-event/user-trip-event.component'; | |||||
| import { UserTripEventListComponent } from './_views/user-trip-event/user-trip-event-list/user-trip-event-list.component'; | |||||
| import { UserFormComponent } from './_views/user/user-form/user-form.component'; | |||||
| registerLocaleData(localeDe, 'de-DE'); | registerLocaleData(localeDe, 'de-DE'); | ||||
| @@ -159,6 +162,9 @@ export function HttpLoaderFactory(http: HttpClient) { | |||||
| UserTripListComponent, | UserTripListComponent, | ||||
| UserTripDetailComponent, | UserTripDetailComponent, | ||||
| UserTripFormComponent, | UserTripFormComponent, | ||||
| UserTripEventComponent, | |||||
| UserTripEventListComponent, | |||||
| UserFormComponent, | |||||
| ], | ], | ||||
| providers: [ | providers: [ | ||||
| {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}, | {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}, | ||||
| @@ -39,7 +39,6 @@ model/eventJsonldContext.ts | |||||
| model/eventJsonldContextOneOf.ts | model/eventJsonldContextOneOf.ts | ||||
| model/location.ts | model/location.ts | ||||
| model/locationJsonld.ts | model/locationJsonld.ts | ||||
| model/mediaObject.ts | |||||
| model/mediaObjectJsonld.ts | model/mediaObjectJsonld.ts | ||||
| model/models.ts | model/models.ts | ||||
| model/shippingCompany.ts | model/shippingCompany.ts | ||||
| @@ -49,9 +48,7 @@ model/tripJsonld.ts | |||||
| model/tripLocation.ts | model/tripLocation.ts | ||||
| model/tripLocationJsonld.ts | model/tripLocationJsonld.ts | ||||
| model/user.ts | model/user.ts | ||||
| model/userImage.ts | |||||
| model/userJsonld.ts | model/userJsonld.ts | ||||
| model/userJsonldImage.ts | |||||
| model/userTrip.ts | model/userTrip.ts | ||||
| model/userTripEvent.ts | model/userTripEvent.ts | ||||
| model/userTripEventJsonld.ts | model/userTripEventJsonld.ts | ||||
| @@ -102,15 +102,16 @@ export class UserTripEventService { | |||||
| * @param itemsPerPage The number of items per page | * @param itemsPerPage The number of items per page | ||||
| * @param userTrip | * @param userTrip | ||||
| * @param userTrip2 | * @param userTrip2 | ||||
| * @param tripId Filter UserTripEvents by Trip ID | |||||
| * @param customJsonFilter | * @param customJsonFilter | ||||
| * @param customJsonOrder | * @param customJsonOrder | ||||
| * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | * @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body. | ||||
| * @param reportProgress flag to report request and response progress. | * @param reportProgress flag to report request and response progress. | ||||
| */ | */ | ||||
| public userTripEventsGetCollection(page?: number, itemsPerPage?: number, userTrip?: string, userTrip2?: Array<string>, customJsonFilter?: string, customJsonOrder?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json', context?: HttpContext, transferCache?: boolean}): Observable<ApiUserTripEventsGetCollection200Response>; | |||||
| public userTripEventsGetCollection(page?: number, itemsPerPage?: number, userTrip?: string, userTrip2?: Array<string>, customJsonFilter?: string, customJsonOrder?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json', context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<ApiUserTripEventsGetCollection200Response>>; | |||||
| public userTripEventsGetCollection(page?: number, itemsPerPage?: number, userTrip?: string, userTrip2?: Array<string>, customJsonFilter?: string, customJsonOrder?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json', context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<ApiUserTripEventsGetCollection200Response>>; | |||||
| public userTripEventsGetCollection(page?: number, itemsPerPage?: number, userTrip?: string, userTrip2?: Array<string>, customJsonFilter?: string, customJsonOrder?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/ld+json', context?: HttpContext, transferCache?: boolean}): Observable<any> { | |||||
| public userTripEventsGetCollection(page?: number, itemsPerPage?: number, userTrip?: string, userTrip2?: Array<string>, tripId?: number, customJsonFilter?: string, customJsonOrder?: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json', context?: HttpContext, transferCache?: boolean}): Observable<ApiUserTripEventsGetCollection200Response>; | |||||
| public userTripEventsGetCollection(page?: number, itemsPerPage?: number, userTrip?: string, userTrip2?: Array<string>, tripId?: number, customJsonFilter?: string, customJsonOrder?: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json', context?: HttpContext, transferCache?: boolean}): Observable<HttpResponse<ApiUserTripEventsGetCollection200Response>>; | |||||
| public userTripEventsGetCollection(page?: number, itemsPerPage?: number, userTrip?: string, userTrip2?: Array<string>, tripId?: number, customJsonFilter?: string, customJsonOrder?: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/ld+json', context?: HttpContext, transferCache?: boolean}): Observable<HttpEvent<ApiUserTripEventsGetCollection200Response>>; | |||||
| public userTripEventsGetCollection(page?: number, itemsPerPage?: number, userTrip?: string, userTrip2?: Array<string>, tripId?: number, customJsonFilter?: string, customJsonOrder?: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/ld+json', context?: HttpContext, transferCache?: boolean}): Observable<any> { | |||||
| let localVarQueryParameters = new HttpParams({encoder: this.encoder}); | let localVarQueryParameters = new HttpParams({encoder: this.encoder}); | ||||
| if (page !== undefined && page !== null) { | if (page !== undefined && page !== null) { | ||||
| @@ -131,6 +132,10 @@ export class UserTripEventService { | |||||
| <any>element, 'userTrip[]'); | <any>element, 'userTrip[]'); | ||||
| }) | }) | ||||
| } | } | ||||
| if (tripId !== undefined && tripId !== null) { | |||||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | |||||
| <any>tripId, 'tripId'); | |||||
| } | |||||
| if (customJsonFilter !== undefined && customJsonFilter !== null) { | if (customJsonFilter !== undefined && customJsonFilter !== null) { | ||||
| localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | localVarQueryParameters = this.addToHttpParams(localVarQueryParameters, | ||||
| <any>customJsonFilter, 'custom_json_filter'); | <any>customJsonFilter, 'custom_json_filter'); | ||||
| @@ -20,6 +20,7 @@ export interface Location { | |||||
| zoneIri: string | null; | zoneIri: string | null; | ||||
| name: string; | name: string; | ||||
| code: string; | code: string; | ||||
| readonly zoneName?: string; | |||||
| isZone?: boolean; | isZone?: boolean; | ||||
| isPlace?: boolean; | isPlace?: boolean; | ||||
| isPort?: boolean; | isPort?: boolean; | ||||
| @@ -25,6 +25,7 @@ export interface LocationJsonld { | |||||
| zoneIri: string | null; | zoneIri: string | null; | ||||
| name: string; | name: string; | ||||
| code: string; | code: string; | ||||
| readonly zoneName?: string; | |||||
| isZone?: boolean; | isZone?: boolean; | ||||
| isPlace?: boolean; | isPlace?: boolean; | ||||
| isPort?: boolean; | isPort?: boolean; | ||||
| @@ -19,7 +19,6 @@ export * from './eventJsonldContext'; | |||||
| export * from './eventJsonldContextOneOf'; | export * from './eventJsonldContextOneOf'; | ||||
| export * from './location'; | export * from './location'; | ||||
| export * from './locationJsonld'; | export * from './locationJsonld'; | ||||
| export * from './mediaObject'; | |||||
| export * from './mediaObjectJsonld'; | export * from './mediaObjectJsonld'; | ||||
| export * from './shippingCompany'; | export * from './shippingCompany'; | ||||
| export * from './shippingCompanyJsonld'; | export * from './shippingCompanyJsonld'; | ||||
| @@ -28,9 +27,7 @@ export * from './tripJsonld'; | |||||
| export * from './tripLocation'; | export * from './tripLocation'; | ||||
| export * from './tripLocationJsonld'; | export * from './tripLocationJsonld'; | ||||
| export * from './user'; | export * from './user'; | ||||
| export * from './userImage'; | |||||
| export * from './userJsonld'; | export * from './userJsonld'; | ||||
| export * from './userJsonldImage'; | |||||
| export * from './userTrip'; | export * from './userTrip'; | ||||
| export * from './userTripEvent'; | export * from './userTripEvent'; | ||||
| export * from './userTripEventJsonld'; | export * from './userTripEventJsonld'; | ||||
| @@ -9,7 +9,6 @@ | |||||
| * https://openapi-generator.tech | * https://openapi-generator.tech | ||||
| * Do not edit the class manually. | * Do not edit the class manually. | ||||
| */ | */ | ||||
| import { UserImage } from './userImage'; | |||||
| /** | /** | ||||
| @@ -21,13 +20,14 @@ export interface User { | |||||
| firstName: string; | firstName: string; | ||||
| referenceId: string; | referenceId: string; | ||||
| lastName: string; | lastName: string; | ||||
| image?: UserImage; | |||||
| readonly image?: string; | |||||
| imageIri?: string | null; | |||||
| readonly imageUrl?: string | null; | readonly imageUrl?: string | null; | ||||
| readonly fullName?: string | null; | readonly fullName?: string | null; | ||||
| /** | /** | ||||
| * The plaintext password when being set or changed. | * The plaintext password when being set or changed. | ||||
| */ | */ | ||||
| password?: string; | |||||
| password?: string | null; | |||||
| active?: boolean; | active?: boolean; | ||||
| roles?: Array<string>; | roles?: Array<string>; | ||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| @@ -9,7 +9,7 @@ | |||||
| * https://openapi-generator.tech | * https://openapi-generator.tech | ||||
| * Do not edit the class manually. | * Do not edit the class manually. | ||||
| */ | */ | ||||
| import { UserJsonldImage } from './userJsonldImage'; | |||||
| import { MediaObjectJsonld } from './mediaObjectJsonld'; | |||||
| import { EventJsonldContext } from './eventJsonldContext'; | import { EventJsonldContext } from './eventJsonldContext'; | ||||
| @@ -25,13 +25,14 @@ export interface UserJsonld { | |||||
| firstName: string; | firstName: string; | ||||
| referenceId: string; | referenceId: string; | ||||
| lastName: string; | lastName: string; | ||||
| image?: UserJsonldImage; | |||||
| readonly image?: MediaObjectJsonld; | |||||
| imageIri?: string | null; | |||||
| readonly imageUrl?: string | null; | readonly imageUrl?: string | null; | ||||
| readonly fullName?: string | null; | readonly fullName?: string | null; | ||||
| /** | /** | ||||
| * The plaintext password when being set or changed. | * The plaintext password when being set or changed. | ||||
| */ | */ | ||||
| password?: string; | |||||
| password?: string | null; | |||||
| active?: boolean; | active?: boolean; | ||||
| roles?: Array<string>; | roles?: Array<string>; | ||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| @@ -23,6 +23,7 @@ export interface UserTripEvent { | |||||
| eventIri: string | null; | eventIri: string | null; | ||||
| readonly location?: string; | readonly location?: string; | ||||
| locationIri: string | null; | locationIri: string | null; | ||||
| readonly user?: string; | |||||
| date: string; | date: string; | ||||
| note?: string | null; | note?: string | null; | ||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| @@ -10,6 +10,7 @@ | |||||
| * Do not edit the class manually. | * Do not edit the class manually. | ||||
| */ | */ | ||||
| import { UserTripJsonld } from './userTripJsonld'; | import { UserTripJsonld } from './userTripJsonld'; | ||||
| import { UserJsonld } from './userJsonld'; | |||||
| import { EventJsonld } from './eventJsonld'; | import { EventJsonld } from './eventJsonld'; | ||||
| import { EventJsonldContext } from './eventJsonldContext'; | import { EventJsonldContext } from './eventJsonldContext'; | ||||
| import { LocationJsonld } from './locationJsonld'; | import { LocationJsonld } from './locationJsonld'; | ||||
| @@ -29,6 +30,7 @@ export interface UserTripEventJsonld { | |||||
| eventIri: string | null; | eventIri: string | null; | ||||
| readonly location?: LocationJsonld; | readonly location?: LocationJsonld; | ||||
| locationIri: string | null; | locationIri: string | null; | ||||
| readonly user?: UserJsonld; | |||||
| date: string; | date: string; | ||||
| note?: string | null; | note?: string | null; | ||||
| readonly createdAt?: string | null; | readonly createdAt?: string | null; | ||||
| @@ -34,7 +34,8 @@ | |||||
| "remove_itinerary_location": "Remove itinerary location", | "remove_itinerary_location": "Remove itinerary location", | ||||
| "save_itinerary": "Save itinerary", | "save_itinerary": "Save itinerary", | ||||
| "assigned_users": "Assigned Users (User Trips)", | "assigned_users": "Assigned Users (User Trips)", | ||||
| "save_user_assignments": "Save user assignments" | |||||
| "save_user_assignments": "Save user assignments", | |||||
| "events": "Events" | |||||
| }, | }, | ||||
| "user_trip": | "user_trip": | ||||
| { | { | ||||
| @@ -119,7 +120,8 @@ | |||||
| "firstname": "Firstname", | "firstname": "Firstname", | ||||
| "lastname": "Lastname", | "lastname": "Lastname", | ||||
| "userTrips": "User trips", | "userTrips": "User trips", | ||||
| "pilotIdNo": "#Pilot id" | |||||
| "pilotIdNo": "#Pilot id", | |||||
| "password": "Password" | |||||
| }, | }, | ||||
| "form": | "form": | ||||
| { | { | ||||
| @@ -84,6 +84,9 @@ class LocationApi | |||||
| #[Assert\NotBlank] | #[Assert\NotBlank] | ||||
| public string $code; | public string $code; | ||||
| #[ApiProperty(writable: false)] | |||||
| public string $zoneName; | |||||
| public bool $isZone; | public bool $isZone; | ||||
| public bool $isPlace; | public bool $isPlace; | ||||
| @@ -23,6 +23,7 @@ use App\Filter\CustomJsonOrderFilter; | |||||
| use App\Filter\UserNameSearchFilter; | use App\Filter\UserNameSearchFilter; | ||||
| use App\State\EntityClassDtoStateProcessor; | use App\State\EntityClassDtoStateProcessor; | ||||
| use App\State\EntityToDtoStateProvider; | use App\State\EntityToDtoStateProvider; | ||||
| use Symfony\Component\PropertyInfo\Type; | |||||
| use Symfony\Component\Validator\Constraints as Assert; | use Symfony\Component\Validator\Constraints as Assert; | ||||
| #[ApiResource( | #[ApiResource( | ||||
| @@ -75,7 +76,24 @@ class UserApi | |||||
| #[Assert\NotBlank] | #[Assert\NotBlank] | ||||
| public string $lastName; | public string $lastName; | ||||
| public ?MediaObject $image = null; | |||||
| /** | |||||
| * @var MediaObjectApi | |||||
| */ | |||||
| #[ApiProperty( | |||||
| writable: false, | |||||
| readableLink: true, | |||||
| writableLink: false, | |||||
| builtinTypes: [ | |||||
| new Type( | |||||
| 'object', | |||||
| class: MediaObjectApi::class, | |||||
| ) | |||||
| ] | |||||
| )] | |||||
| public ?MediaObjectApi $image = null; | |||||
| #[ApiProperty(writable: true)] | |||||
| public ?MediaObjectApi $imageIri = null; | |||||
| #[ApiProperty(writable: false)] | #[ApiProperty(writable: false)] | ||||
| public ?string $imageUrl = null; | public ?string $imageUrl = null; | ||||
| @@ -16,6 +16,7 @@ use App\Entity\UserTrip; | |||||
| use App\Entity\UserTripEvent; | use App\Entity\UserTripEvent; | ||||
| use App\Filter\CustomJsonFilter; | use App\Filter\CustomJsonFilter; | ||||
| use App\Filter\CustomJsonOrderFilter; | use App\Filter\CustomJsonOrderFilter; | ||||
| use App\Filter\UserTripEventFilter; | |||||
| use App\State\EntityClassDtoStateProcessor; | use App\State\EntityClassDtoStateProcessor; | ||||
| use App\State\EntityToDtoStateProvider; | use App\State\EntityToDtoStateProvider; | ||||
| use Symfony\Component\Validator\Constraints as Assert; | use Symfony\Component\Validator\Constraints as Assert; | ||||
| @@ -41,6 +42,7 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||||
| security: 'is_granted("ROLE_ADMIN")' | security: 'is_granted("ROLE_ADMIN")' | ||||
| ) | ) | ||||
| ], | ], | ||||
| order: ['date' => 'ASC'], | |||||
| security: 'is_granted("ROLE_USER")', | security: 'is_granted("ROLE_USER")', | ||||
| provider: EntityToDtoStateProvider::class, | provider: EntityToDtoStateProvider::class, | ||||
| processor: EntityClassDtoStateProcessor::class, | processor: EntityClassDtoStateProcessor::class, | ||||
| @@ -48,6 +50,7 @@ use Symfony\Component\Validator\Constraints\NotBlank; | |||||
| )] | )] | ||||
| #[ApiFilter(SearchFilter::class, properties: ['userTrip' => 'exact'])] | #[ApiFilter(SearchFilter::class, properties: ['userTrip' => 'exact'])] | ||||
| #[ApiFilter(UserTripEventFilter::class)] | |||||
| #[ApiFilter(CustomJsonFilter::class)] | #[ApiFilter(CustomJsonFilter::class)] | ||||
| #[ApiFilter(CustomJsonOrderFilter::class)] | #[ApiFilter(CustomJsonOrderFilter::class)] | ||||
| class UserTripEventApi | class UserTripEventApi | ||||
| @@ -118,6 +121,22 @@ class UserTripEventApi | |||||
| #[ApiProperty(writable: true)] | #[ApiProperty(writable: true)] | ||||
| public ?LocationApi $locationIri = null; | public ?LocationApi $locationIri = null; | ||||
| /** | |||||
| * @var UserApi | |||||
| */ | |||||
| #[ApiProperty( | |||||
| writable: false, | |||||
| readableLink: true, | |||||
| writableLink: false, | |||||
| builtinTypes: [ | |||||
| new Type( | |||||
| 'object', | |||||
| class: UserApi::class, | |||||
| ) | |||||
| ] | |||||
| )] | |||||
| public ?UserApi $user = null; | |||||
| #[Assert\NotBlank] | #[Assert\NotBlank] | ||||
| public \DateTimeImmutable $date; | public \DateTimeImmutable $date; | ||||
| @@ -0,0 +1,47 @@ | |||||
| <?php | |||||
| namespace App\Filter; | |||||
| use ApiPlatform\Doctrine\Orm\Filter\AbstractFilter; | |||||
| use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface; | |||||
| use ApiPlatform\Metadata\ApiFilter; | |||||
| use Doctrine\ORM\QueryBuilder; | |||||
| use ApiPlatform\Metadata\Operation; | |||||
| #[ApiFilter(UserTripEventFilter::class)] | |||||
| class UserTripEventFilter extends AbstractFilter | |||||
| { | |||||
| protected function filterProperty( | |||||
| string $property, | |||||
| mixed $value, | |||||
| QueryBuilder $queryBuilder, | |||||
| QueryNameGeneratorInterface $queryNameGenerator, | |||||
| string $resourceClass, | |||||
| ?Operation $operation = null, | |||||
| array $context = [] | |||||
| ): void { | |||||
| if ($property !== 'tripId') { | |||||
| return; | |||||
| } | |||||
| $rootAlias = $queryBuilder->getRootAliases()[0]; | |||||
| $parameterName = $queryNameGenerator->generateParameterName('tripId'); | |||||
| $queryBuilder | |||||
| ->join("$rootAlias.userTrip", "userTrip") | |||||
| ->join("userTrip.trip", "trip") | |||||
| ->andWhere("trip.id = :$parameterName") | |||||
| ->setParameter($parameterName, $value); | |||||
| } | |||||
| public function getDescription(string $resourceClass): array | |||||
| { | |||||
| return [ | |||||
| 'tripId' => [ | |||||
| 'property' => 'tripId', | |||||
| 'type' => 'int', | |||||
| 'required' => false, | |||||
| 'description' => 'Filter UserTripEvents by Trip ID', | |||||
| ], | |||||
| ]; | |||||
| } | |||||
| } | |||||
| @@ -37,6 +37,7 @@ class LocationEntityToApiMapper implements MapperInterface | |||||
| $dto->dbId = $entity->getId(); | $dto->dbId = $entity->getId(); | ||||
| $dto->name = $entity->getName(); | $dto->name = $entity->getName(); | ||||
| $dto->zoneName = $entity->getZone()->getName(); | |||||
| $dto->code = $entity->getCode(); | $dto->code = $entity->getCode(); | ||||
| $dto->isZone = $entity->isZone(); | $dto->isZone = $entity->isZone(); | ||||
| $dto->isPlace = $entity->isPlace(); | $dto->isPlace = $entity->isPlace(); | ||||
| @@ -5,6 +5,7 @@ namespace App\Mapper; | |||||
| use App\ApiResource\UserApi; | use App\ApiResource\UserApi; | ||||
| use App\Entity\User; | use App\Entity\User; | ||||
| use App\Entity\Posting; | use App\Entity\Posting; | ||||
| use App\Repository\MediaObjectRepository; | |||||
| use App\Repository\UserRepository; | use App\Repository\UserRepository; | ||||
| use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; | use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; | ||||
| use Symfonycasts\MicroMapper\AsMapper; | use Symfonycasts\MicroMapper\AsMapper; | ||||
| @@ -16,6 +17,7 @@ class UserApiToEntityMapper implements MapperInterface | |||||
| public function __construct( | public function __construct( | ||||
| private UserRepository $repository, | private UserRepository $repository, | ||||
| private UserPasswordHasherInterface $userPasswordHasher, | private UserPasswordHasherInterface $userPasswordHasher, | ||||
| private MediaObjectRepository $mediaObjectRepository, | |||||
| ) | ) | ||||
| { | { | ||||
| } | } | ||||
| @@ -48,6 +50,16 @@ class UserApiToEntityMapper implements MapperInterface | |||||
| $entity->setPassword($this->userPasswordHasher->hashPassword($entity, $dto->password)); | $entity->setPassword($this->userPasswordHasher->hashPassword($entity, $dto->password)); | ||||
| } | } | ||||
| if ($dto->imageIri) { | |||||
| $image = $this->mediaObjectRepository->find($dto->imageIri->id); | |||||
| if (!$image) { | |||||
| throw new \Exception('Image not found'); | |||||
| } | |||||
| $entity->setImage($image); | |||||
| } else { | |||||
| $entity->setImage(null); | |||||
| } | |||||
| return $entity; | return $entity; | ||||
| } | } | ||||
| } | } | ||||
| @@ -2,6 +2,7 @@ | |||||
| namespace App\Mapper; | namespace App\Mapper; | ||||
| use App\ApiResource\MediaObjectApi; | |||||
| use App\ApiResource\UserApi; | use App\ApiResource\UserApi; | ||||
| use App\Entity\User; | use App\Entity\User; | ||||
| use App\Service\FileUrlService; | use App\Service\FileUrlService; | ||||
| @@ -42,8 +43,15 @@ class UserEntityToApiMapper implements MapperInterface | |||||
| $dto->referenceId = $entity->getReferenceId(); | $dto->referenceId = $entity->getReferenceId(); | ||||
| $dto->firstName = $entity->getFirstName(); | $dto->firstName = $entity->getFirstName(); | ||||
| $dto->lastName = $entity->getLastName(); | $dto->lastName = $entity->getLastName(); | ||||
| $dto->image = $entity->getImage(); | |||||
| $dto->roles = $entity->getRoles(); | $dto->roles = $entity->getRoles(); | ||||
| $dto->imageIri = $dto->image = null; | |||||
| if ($entity->getImage() !== null) { | |||||
| $dto->imageIri = $dto->image = $this->microMapper->map($entity->getImage(), MediaObjectApi::class, [ | |||||
| MicroMapperInterface::MAX_DEPTH => 1, | |||||
| ]); | |||||
| } | |||||
| $dto->imageUrl = $this->fileUrlService->getFileUrl($entity->getImage()); | $dto->imageUrl = $this->fileUrlService->getFileUrl($entity->getImage()); | ||||
| $dto->fullName = $entity->getFirstName() . " " . $entity->getLastName(); | $dto->fullName = $entity->getFirstName() . " " . $entity->getLastName(); | ||||
| $dto->createdAt = $entity->getCreatedAt(); | $dto->createdAt = $entity->getCreatedAt(); | ||||
| @@ -19,8 +19,6 @@ class UserTripApiToEntityMapper implements MapperInterface | |||||
| { | { | ||||
| public function __construct( | public function __construct( | ||||
| private UserTripRepository $repository, | private UserTripRepository $repository, | ||||
| private TripRepository $tripRepository, | |||||
| private UserRepository $userRepository, | |||||
| private MediaObjectRepository $mediaObjectRepository, | private MediaObjectRepository $mediaObjectRepository, | ||||
| private MicroMapperInterface $microMapper | private MicroMapperInterface $microMapper | ||||
| ) { | ) { | ||||
| @@ -4,6 +4,7 @@ namespace App\Mapper; | |||||
| use App\ApiResource\EventApi; | use App\ApiResource\EventApi; | ||||
| use App\ApiResource\LocationApi; | use App\ApiResource\LocationApi; | ||||
| use App\ApiResource\UserApi; | |||||
| use App\ApiResource\UserTripApi; | use App\ApiResource\UserTripApi; | ||||
| use App\ApiResource\UserTripEventApi; | use App\ApiResource\UserTripEventApi; | ||||
| use App\Entity\UserTripEvent; | use App\Entity\UserTripEvent; | ||||
| @@ -54,6 +55,10 @@ class UserTripEventEntityToApiMapper implements MapperInterface | |||||
| MicroMapperInterface::MAX_DEPTH => 1, | MicroMapperInterface::MAX_DEPTH => 1, | ||||
| ]); | ]); | ||||
| $dto->user = $this->microMapper->map($entity->getUserTrip()->getUser(), UserApi::class, [ | |||||
| MicroMapperInterface::MAX_DEPTH => 1, | |||||
| ]); | |||||
| return $dto; | return $dto; | ||||
| } | } | ||||
| } | } | ||||