| @@ -9,7 +9,6 @@ | |||||
| <div> | <div> | ||||
| <app-trip-form | <app-trip-form | ||||
| [data]="trip" | [data]="trip" | ||||
| (submit)="onFormUpdate($event)" | |||||
| ></app-trip-form> | ></app-trip-form> | ||||
| </div> | </div> | ||||
| </mat-tab> | </mat-tab> | ||||
| @@ -33,10 +32,10 @@ | |||||
| <div> | <div> | ||||
| <app-user-trip-event-list | <app-user-trip-event-list | ||||
| [trip]="trip" | [trip]="trip" | ||||
| [showCreateButton]="false" | |||||
| > | > | ||||
| </app-user-trip-event-list> | </app-user-trip-event-list> | ||||
| </div> | </div> | ||||
| </mat-tab> | </mat-tab> | ||||
| </mat-tab-group> | </mat-tab-group> | ||||
| } | } | ||||
| @@ -24,34 +24,15 @@ import {TranslateService} from "@ngx-translate/core"; | |||||
| templateUrl: './trip-detail.component.html', | templateUrl: './trip-detail.component.html', | ||||
| styleUrl: './trip-detail.component.scss' | styleUrl: './trip-detail.component.scss' | ||||
| }) | }) | ||||
| export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| export class TripDetailComponent implements OnInit { | |||||
| protected trip!: TripJsonld; | protected trip!: TripJsonld; | ||||
| protected readonly FormMode = FormMode; | |||||
| protected originalUserTrips: UserTripJsonld[] = []; | |||||
| protected tripLocations: TripLocationJsonld[] = []; | |||||
| protected userTrips: UserTripJsonld[] = []; | |||||
| protected userTripEvents: UserTripEventJsonld[] = []; | |||||
| protected users: UserJsonld[] = []; | protected users: UserJsonld[] = []; | ||||
| protected locationForms: FormGroup[] = []; | |||||
| protected locationColDefinitions: ListColDefinition[] = SearchSelectComponent.getDefaultColDefLocations(); | |||||
| protected userForms: FormGroup[] = []; | |||||
| protected userColDefinitions: ListColDefinition[] = SearchSelectComponent.getDefaultColDefUsers(); | |||||
| protected originalTripLocations: TripLocation[] = []; | |||||
| @ViewChildren(SearchSelectComponent) searchSelects!: QueryList<SearchSelectComponent>; | |||||
| constructor( | constructor( | ||||
| private tripService: TripService, | private tripService: TripService, | ||||
| private tripLocationService: TripLocationService, | |||||
| private locationService: LocationService, | |||||
| private userTripService: UserTripService, | |||||
| private userTripEventService: UserTripEventService, | |||||
| private userService: UserService, | |||||
| protected appHelperService: AppHelperService, | protected appHelperService: AppHelperService, | ||||
| protected translateService: TranslateService, | protected translateService: TranslateService, | ||||
| private route: ActivatedRoute, | private route: ActivatedRoute, | ||||
| private fb: FormBuilder | |||||
| ) {} | ) {} | ||||
| ngOnInit() { | ngOnInit() { | ||||
| @@ -59,268 +40,8 @@ export class TripDetailComponent implements OnInit, AfterViewInit { | |||||
| this.tripService.tripsIdGet(params['id']).subscribe( | this.tripService.tripsIdGet(params['id']).subscribe( | ||||
| data => { | data => { | ||||
| this.trip = data; | this.trip = data; | ||||
| this.loadTripLocations(); | |||||
| this.loadUserTrips(); | |||||
| this.loadUserTripEvents(); | |||||
| } | } | ||||
| ); | ); | ||||
| }); | }); | ||||
| } | } | ||||
| ngAfterViewInit() { | |||||
| // Reinitialize search selects when they change | |||||
| this.searchSelects.changes.subscribe(components => { | |||||
| components.forEach((component: SearchSelectComponent) => { | |||||
| // Force search selects to initialize | |||||
| if (component.dataSet) { | |||||
| component.ngAfterViewInit(); | |||||
| } | |||||
| }); | |||||
| }); | |||||
| } | |||||
| loadTripLocations() { | |||||
| this.tripLocationService.tripLocationsGetCollection( | |||||
| 1, | |||||
| 200, | |||||
| this.trip !== undefined ? this.trip.id : undefined, | |||||
| ).subscribe( | |||||
| data => { | |||||
| this.tripLocations = data.member; | |||||
| // Create a form for each trip location | |||||
| this.locationForms = []; | |||||
| this.originalTripLocations = JSON.parse(JSON.stringify(this.tripLocations)); | |||||
| this.tripLocations.forEach((tripLocation) => { | |||||
| this.locationForms.push(this.createLocationForm(tripLocation.location?.id ?? null)); | |||||
| }); | |||||
| } | |||||
| ); | |||||
| } | |||||
| createLocationForm(locationIri: string | null): FormGroup { | |||||
| return this.fb.group({ | |||||
| location: [locationIri] | |||||
| }); | |||||
| } | |||||
| createUserForm(): FormGroup { | |||||
| return this.fb.group({ | |||||
| user: [null] | |||||
| }); | |||||
| } | |||||
| getLocations = (page: number, pageSize: number, term?: string): Observable<any> => { | |||||
| return this.locationService.locationsGetCollection(page, pageSize, term); | |||||
| } | |||||
| getUsers = (page: number, pageSize: number, term?: string): Observable<any> => { | |||||
| // Sammeln Sie alle aktuell ausgewählten Benutzer-IDs (sowohl gespeicherte als auch nicht gespeicherte) | |||||
| const assignedUserIds: string[] = []; | |||||
| // IDs aus bestehenden UserTrips (mit gültiger ID) | |||||
| this.userTrips | |||||
| .filter(ut => ut.user && ut.user.id) | |||||
| .forEach(ut => assignedUserIds.push(this.appHelperService.extractId(ut.user?.id!))); | |||||
| // IDs aus aktuellen Formularwerten (auch für noch nicht gespeicherte Einträge) | |||||
| this.userForms.forEach(form => { | |||||
| const userValue = form.get('user')?.value; | |||||
| if (userValue) { | |||||
| assignedUserIds.push(this.appHelperService.extractId(userValue)); | |||||
| } | |||||
| }); | |||||
| // Filtere Benutzer, die bereits ausgewählt sind (gespeichert oder nicht) | |||||
| return this.userService.usersGetCollection( | |||||
| page, | |||||
| pageSize, | |||||
| undefined, | |||||
| undefined, | |||||
| term, | |||||
| '{"isPilot":true}' | |||||
| ).pipe( | |||||
| map(response => { | |||||
| response.member = response.member.filter(user => | |||||
| !assignedUserIds.includes(this.appHelperService.extractId(user.id!)) | |||||
| ); | |||||
| return response; | |||||
| }) | |||||
| ); | |||||
| } | |||||
| onUserSelectChange(index: number) { | |||||
| // Erzwingen Sie eine Aktualisierung aller anderen SearchSelect-Komponenten | |||||
| setTimeout(() => { | |||||
| if (this.searchSelects) { | |||||
| this.searchSelects.forEach((component, i) => { | |||||
| // Überspringen Sie das aktuelle SearchSelect (es muss nicht aktualisiert werden) | |||||
| if (i !== index) { | |||||
| component.ngAfterViewInit(); | |||||
| } | |||||
| }); | |||||
| } | |||||
| }); | |||||
| } | |||||
| onFormUpdate(event: FormSubmitEvent<TripJsonld>) { | |||||
| if (event.status === ModalStatus.Submitted && event.data) { | |||||
| this.trip = event.data; | |||||
| } | |||||
| } | |||||
| addNewUserTrip() { | |||||
| // Erstelle ein unvollständiges Objekt (ohne user-Property) | |||||
| const newUserTrip: UserTripJsonld = { | |||||
| tripIri: this.trip.id!, | |||||
| userIri: null, | |||||
| completed: false, | |||||
| approved: false, | |||||
| }; | |||||
| // Füge es als UserTripJsonld hinzu | |||||
| this.userTrips.push(newUserTrip as UserTripJsonld); | |||||
| this.userForms.push(this.createUserForm()); | |||||
| // Rest unverändert... | |||||
| 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({ | |||||
| next: (data) => { | |||||
| this.userTrips = data.member; | |||||
| this.originalUserTrips = [...data.member]; // Kopie der ursprünglichen UserTrips speichern | |||||
| // Formulare für jeden UserTrip erstellen | |||||
| this.userForms = []; | |||||
| this.userTrips.forEach((userTrip, index) => { | |||||
| const form = this.createUserForm(); | |||||
| // Formularwerte initialisieren | |||||
| if (userTrip.userIri || (userTrip.user && userTrip.user.id)) { | |||||
| form.get('user')?.setValue(userTrip.userIri || userTrip.user?.id); | |||||
| } | |||||
| this.userForms.push(form); | |||||
| }); | |||||
| }, | |||||
| error: (error) => { | |||||
| console.error('Fehler beim Laden der Benutzerzuweisungen:', error); | |||||
| } | |||||
| }); | |||||
| } | |||||
| loadUserTripEvents() { | |||||
| this.userTripEventService.userTripEventsGetCollection( | |||||
| 1, | |||||
| 200, | |||||
| undefined, | |||||
| undefined, | |||||
| this.trip.dbId!, | |||||
| ).subscribe({ | |||||
| next: (data) => { | |||||
| this.userTripEvents = data.member; | |||||
| } | |||||
| }) | |||||
| } | |||||
| saveAllUserTrips() { | |||||
| // Aktuelle IDs speichern, um später gelöschte Einträge zu identifizieren | |||||
| let originalUserTripIds: string[] = []; | |||||
| // Zuerst alle existierenden UserTrips vom Server holen | |||||
| this.userTripService.userTripsGetCollection( | |||||
| 1, 200, this.trip.dbId?.toString() | |||||
| ).subscribe({ | |||||
| next: (existingUserTrips) => { | |||||
| // IDs der existierenden UserTrips speichern | |||||
| originalUserTripIds = existingUserTrips.member | |||||
| .filter(userTrip => userTrip.id) | |||||
| .map(userTrip => this.appHelperService.extractId(userTrip.id!)); | |||||
| // Aktualisieren der user objects in unserem userTrips-Array | |||||
| this.userTrips.forEach((userTrip, index) => { | |||||
| const userFormValue = this.userForms[index].get('user')?.value; | |||||
| // User setzen, wenn verfügbar | |||||
| if (userFormValue) { | |||||
| if (typeof userFormValue === 'string') { | |||||
| userTrip.userIri = userFormValue; | |||||
| } | |||||
| } | |||||
| }); | |||||
| // Filtern: Nur UserTrips mit gültigen User-Zuweisungen behalten | |||||
| const validUserTrips = this.userTrips.filter(ut => ut.userIri || (ut.user && ut.user.id)); | |||||
| if (validUserTrips.length === 0 && this.userTrips.length > 0) { | |||||
| window.alert('Bitte wähle für jeden Eintrag einen Benutzer aus oder entferne ungenutzte Einträge.'); | |||||
| return; | |||||
| } | |||||
| // Array für alle Operationen erstellen | |||||
| const allPromises: Promise<any>[] = []; | |||||
| // 1. Neue UserTrips erstellen und existierende aktualisieren | |||||
| validUserTrips.forEach(userTrip => { | |||||
| if (userTrip.id) { | |||||
| // Existierenden UserTrip aktualisieren | |||||
| const id = this.appHelperService.extractId(userTrip.id); | |||||
| // ID aus der Liste der zu löschenden IDs entfernen | |||||
| const idIndex = originalUserTripIds.indexOf(id); | |||||
| if (idIndex > -1) { | |||||
| originalUserTripIds.splice(idIndex, 1); | |||||
| } | |||||
| // Update-Promise hinzufügen | |||||
| allPromises.push( | |||||
| firstValueFrom(this.userTripService.userTripsIdPatch( | |||||
| id, | |||||
| this.appHelperService.convertJsonldToJson(userTrip) | |||||
| )) | |||||
| ); | |||||
| } else { | |||||
| // Neuen UserTrip erstellen | |||||
| allPromises.push( | |||||
| firstValueFrom(this.userTripService.userTripsPost(userTrip)) | |||||
| ); | |||||
| } | |||||
| }); | |||||
| // 2. Gelöschte UserTrips von der Datenbank entfernen | |||||
| originalUserTripIds.forEach(id => { | |||||
| allPromises.push( | |||||
| firstValueFrom(this.userTripService.userTripsIdDelete(id)) | |||||
| ); | |||||
| }); | |||||
| // Alle Operationen ausführen | |||||
| Promise.all(allPromises) | |||||
| .then(() => { | |||||
| // Nach dem Speichern alle UserTrips neu laden | |||||
| this.loadUserTrips(); | |||||
| }) | |||||
| .catch(error => { | |||||
| console.error('Fehler beim Speichern der Benutzerzuweisungen:', error); | |||||
| window.alert('Beim Speichern der Benutzerzuweisungen ist ein Fehler aufgetreten. Bitte versuche es erneut.'); | |||||
| }); | |||||
| }, | |||||
| error: (error) => { | |||||
| console.error('Fehler beim Laden der existierenden Benutzerzuweisungen:', error); | |||||
| window.alert('Die aktuellen Benutzerzuweisungen konnten nicht geladen werden. Bitte versuche es erneut.'); | |||||
| } | |||||
| }); | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,72 @@ | |||||
| <div class="spt-container"> | |||||
| @if (!isEditMode()) { | |||||
| <div class="spt-headline d-flex justify-content-between align-items-start"> | |||||
| <h2>{{ ('basic.create') | translate }} {{ 'model.event' | translate }}</h2> | |||||
| </div> | |||||
| } @else { | |||||
| <div class="spt-headline d-flex justify-content-between align-items-start"> | |||||
| <h2>{{ ('basic.edit') | translate }} {{ 'model.trip' | translate }}: {{ data?.event?.name }}</h2> | |||||
| </div> | |||||
| } | |||||
| <div class="spt-form"> | |||||
| @if (data !== undefined) { | |||||
| <form [formGroup]="userTripEventForm" (ngSubmit)="onSubmit()"> | |||||
| <input id="userTripIri" type="hidden" formControlName="userTripIri" required/> | |||||
| <div class="col-12 mb-3"> | |||||
| <label for="eventIri" class="form-label">{{ 'model.event' | translate }}*:</label> | |||||
| <app-search-select #eventSearchSelect | |||||
| [formId]="'eventIri'" | |||||
| [formLabelLangKey]="'model.event'" | |||||
| [documentForm]="form" | |||||
| [getDataFunction]="getEvents" | |||||
| [displayedDataField]="'name'" | |||||
| [listColDefinitions]="eventColDefinitions" | |||||
| [dataSet]="data.event" | |||||
| > | |||||
| </app-search-select> | |||||
| <input id="eventIri" type="hidden" formControlName="eventIri" required/> | |||||
| </div> | |||||
| <div class="col-12 mb-3"> | |||||
| <label for="locationIri" class="form-label">{{ 'model.location' | translate }}*:</label> | |||||
| <app-search-select #locationSearchSelect | |||||
| [formId]="'locationIri'" | |||||
| [formLabelLangKey]="'model.location'" | |||||
| [documentForm]="form" | |||||
| [getDataFunction]="getLocations" | |||||
| [displayedDataField]="'name'" | |||||
| [listColDefinitions]="locationColDefinitions" | |||||
| [dataSet]="data.location" | |||||
| > | |||||
| </app-search-select> | |||||
| <input id="locationIri" type="hidden" formControlName="locationIri" required/> | |||||
| </div> | |||||
| <div class="col-12 col-lg-6 mb-3"> | |||||
| <app-datetime-picker | |||||
| [label]="'common.date' | translate" | |||||
| [inputId]="'startDate'" | |||||
| [initialValue]="form.get('date')?.value ?? null" | |||||
| (dateTimeChange)="onDateChange($event, 'date')" | |||||
| ></app-datetime-picker> | |||||
| </div> | |||||
| <div class="col-12 col-lg-6 mb-3"> | |||||
| <label for="note" class="form-label">{{ 'common.note' | translate }}:</label> | |||||
| <textarea class="form-control" id="note" formControlName="note"></textarea> | |||||
| </div> | |||||
| </form> | |||||
| } | |||||
| </div> | |||||
| <div class="row"> | |||||
| <div class="col-12 mb-3"> | |||||
| <button type="submit" class="btn btn-primary" (click)="onSubmit()"> | |||||
| {{ 'basic.save' | translate }} | |||||
| </button> | |||||
| @if (isEditMode()) { | |||||
| <button type="button" class="ms-3 btn btn-primary" (click)="onDelete()"> | |||||
| {{ 'basic.delete' | translate }} {{ 'model.user_trip_event' | translate }} | |||||
| </button> | |||||
| } | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| @@ -0,0 +1,23 @@ | |||||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { UserTripEventFormComponent } from './user-trip-event-form.component'; | |||||
| describe('UserTripEventFormComponent', () => { | |||||
| let component: UserTripEventFormComponent; | |||||
| let fixture: ComponentFixture<UserTripEventFormComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [UserTripEventFormComponent] | |||||
| }) | |||||
| .compileComponents(); | |||||
| fixture = TestBed.createComponent(UserTripEventFormComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); | |||||
| @@ -0,0 +1,80 @@ | |||||
| import { Component } from '@angular/core'; | |||||
| import { | |||||
| EventService, LocationService, | |||||
| UserTripEventJsonld, | |||||
| UserTripEventService, UserTripJsonld, | |||||
| } from "@app/core/api/v1"; | |||||
| import {tripForm, userTripEventForm} from "@app/_forms/apiForms"; | |||||
| import {AbstractDataFormComponent} from "@app/_components/_abstract/abstract-data-form-component"; | |||||
| import {AppHelperService} from "@app/_helpers/app-helper.service"; | |||||
| import {TranslateService} from "@ngx-translate/core"; | |||||
| import {Router} from "@angular/router"; | |||||
| import {ListGetDataFunctionType} from "@app/_components/list/list-get-data-function-type"; | |||||
| import {SearchSelectComponent} from "@app/_components/search-select/search-select.component"; | |||||
| import {ListColDefinition} from "@app/_components/list/list-col-definition"; | |||||
| @Component({ | |||||
| selector: 'app-user-trip-event-form', | |||||
| templateUrl: './user-trip-event-form.component.html', | |||||
| styleUrl: './user-trip-event-form.component.scss' | |||||
| }) | |||||
| export class UserTripEventFormComponent extends AbstractDataFormComponent<UserTripEventJsonld> { | |||||
| protected readonly SearchSelectComponent = SearchSelectComponent; | |||||
| protected readonly userTripEventForm = userTripEventForm; | |||||
| protected userTrip?: UserTripJsonld; | |||||
| protected eventColDefinitions: ListColDefinition[] = SearchSelectComponent.getDefaultColDefEvents(); | |||||
| protected locationColDefinitions: ListColDefinition[] = SearchSelectComponent.getDefaultColDefLocations(); | |||||
| constructor( | |||||
| protected userTripEventService: UserTripEventService, | |||||
| protected eventService: EventService, | |||||
| protected locationService: LocationService, | |||||
| appHelperService: AppHelperService, | |||||
| translateService: TranslateService, | |||||
| router: Router | |||||
| ) { | |||||
| super( | |||||
| userTripEventForm, | |||||
| appHelperService, | |||||
| (data: UserTripEventJsonld) => { | |||||
| return this.userTripEventService.userTripEventsPost(data); | |||||
| }, | |||||
| (id: string | number, data: UserTripEventJsonld) => | |||||
| this.userTripEventService.userTripEventsIdPatch( | |||||
| id.toString(), | |||||
| this.appHelperService.convertJsonldToJson(data) | |||||
| ), | |||||
| (id: string | number) => this.userTripEventService.userTripEventsIdDelete(id.toString()), | |||||
| translateService, | |||||
| router | |||||
| ); | |||||
| //this.redirectAfterDelete = '/' + ROUTE_USER_TRIPS; | |||||
| } | |||||
| override ngOnInit() { | |||||
| super.ngOnInit(); | |||||
| this.form.get('userTripIri')?.setValue(this.userTrip?.id!); | |||||
| } | |||||
| getEvents: ListGetDataFunctionType = ( | |||||
| index: number, | |||||
| pageSize: number, | |||||
| term?: string, | |||||
| ) => { | |||||
| return this.eventService.eventsGetCollection( | |||||
| index, | |||||
| pageSize, | |||||
| term | |||||
| ); | |||||
| } | |||||
| getLocations: ListGetDataFunctionType = (index: number, pageSize: number, term?: string) => { | |||||
| return this.locationService.locationsGetCollection( | |||||
| index, | |||||
| pageSize, | |||||
| term, | |||||
| ); | |||||
| } | |||||
| } | |||||
| @@ -2,6 +2,10 @@ | |||||
| <app-list #listComponent | <app-list #listComponent | ||||
| [listId]="'userTripEventList'" | [listId]="'userTripEventList'" | ||||
| [getDataFunction]="getData" | [getDataFunction]="getData" | ||||
| [showCreateButton]="showCreateButton" | |||||
| [listColDefinitions]="listColDefinitions" | [listColDefinitions]="listColDefinitions" | ||||
| [dataFormComponent]="userTripEventFormComponent" | |||||
| [dataFormComponentData]="dataFormComponentData" | |||||
| [deleteItemFunction]="deleteItemFunction" | |||||
| ></app-list> | ></app-list> | ||||
| </div> | </div> | ||||
| @@ -1,10 +1,14 @@ | |||||
| import {Component, Input, ViewChild} from '@angular/core'; | import {Component, Input, ViewChild} from '@angular/core'; | ||||
| import {ListComponent} from "@app/_components/list/list.component"; | import {ListComponent} from "@app/_components/list/list.component"; | ||||
| import {ListColDefinition} from "@app/_components/list/list-col-definition"; | import {ListColDefinition} from "@app/_components/list/list-col-definition"; | ||||
| import {TripJsonld, UserTripEventService} from "@app/core/api/v1"; | |||||
| import {TripJsonld, UserTripEventService, UserTripJsonld} from "@app/core/api/v1"; | |||||
| import {AppHelperService} from "@app/_helpers/app-helper.service"; | import {AppHelperService} from "@app/_helpers/app-helper.service"; | ||||
| import {FilterBarComponent} from "@app/_components/filter-bar/filter-bar.component"; | import {FilterBarComponent} from "@app/_components/filter-bar/filter-bar.component"; | ||||
| import {ListGetDataFunctionType} from "@app/_components/list/list-get-data-function-type"; | import {ListGetDataFunctionType} from "@app/_components/list/list-get-data-function-type"; | ||||
| import { | |||||
| UserTripEventFormComponent | |||||
| } from "@app/_views/user-trip-event/user-trip-event-form/user-trip-event-form.component"; | |||||
| import {Observable} from "rxjs"; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-user-trip-event-list', | selector: 'app-user-trip-event-list', | ||||
| @@ -13,9 +17,13 @@ import {ListGetDataFunctionType} from "@app/_components/list/list-get-data-funct | |||||
| }) | }) | ||||
| export class UserTripEventListComponent { | export class UserTripEventListComponent { | ||||
| @ViewChild("listComponent", {static: false}) listComponent!: ListComponent; | @ViewChild("listComponent", {static: false}) listComponent!: ListComponent; | ||||
| @Input() public userTrip?: UserTripJsonld; | |||||
| @Input() public trip?: TripJsonld; | @Input() public trip?: TripJsonld; | ||||
| @Input() public showCreateButton: boolean; | |||||
| protected readonly userTripEventFormComponent = UserTripEventFormComponent; | |||||
| protected listColDefinitions!: ListColDefinition[]; | protected listColDefinitions!: ListColDefinition[]; | ||||
| protected dataFormComponentData: any; | |||||
| constructor( | constructor( | ||||
| private userTripEventService: UserTripEventService, | private userTripEventService: UserTripEventService, | ||||
| @@ -75,10 +83,13 @@ export class UserTripEventListComponent { | |||||
| filterType: FilterBarComponent.FILTER_TYPE_DATE, | filterType: FilterBarComponent.FILTER_TYPE_DATE, | ||||
| } as ListColDefinition, | } as ListColDefinition, | ||||
| ]; | ]; | ||||
| this.showCreateButton = true; | |||||
| } | } | ||||
| ngOnInit() { | ngOnInit() { | ||||
| this.dataFormComponentData = { | |||||
| userTrip: this.userTrip, | |||||
| }; | |||||
| } | } | ||||
| ngAfterViewInit(): void { | ngAfterViewInit(): void { | ||||
| @@ -93,11 +104,15 @@ export class UserTripEventListComponent { | |||||
| return this.userTripEventService.userTripEventsGetCollection( | return this.userTripEventService.userTripEventsGetCollection( | ||||
| index, | index, | ||||
| pageSize, | pageSize, | ||||
| undefined, | |||||
| this.userTrip !== undefined ? this.userTrip.id! : undefined, | |||||
| undefined, | undefined, | ||||
| this.trip !== undefined ? this.trip.dbId! : undefined, | this.trip !== undefined ? this.trip.dbId! : undefined, | ||||
| this.listComponent.getFilterJsonString(), | this.listComponent.getFilterJsonString(), | ||||
| this.listComponent.getSortingJsonString() | this.listComponent.getSortingJsonString() | ||||
| ); | ); | ||||
| } | } | ||||
| get deleteItemFunction(): (id: string) => Observable<any> { | |||||
| return (id: string) => this.userTripEventService.userTripEventsIdDelete(id); | |||||
| } | |||||
| } | } | ||||
| @@ -15,91 +15,11 @@ | |||||
| </mat-tab> | </mat-tab> | ||||
| <mat-tab label="{{ 'user_trip.events' | translate }}"> | <mat-tab label="{{ 'user_trip.events' | translate }}"> | ||||
| <div> | <div> | ||||
| <h4 class="mb-4">{{ 'user_trip.events' | translate }}</h4> | |||||
| <div *ngFor="let userTripEvent of userTripEvents; let i = index" class="p-2 mb-2 changing-list"> | |||||
| <div class="row"> | |||||
| <div class="col-12 col-md-6 mb-3"> | |||||
| <label [for]="'event_' + i" class="form-label">{{ 'model.event' | translate }}*:</label> | |||||
| <app-search-select | |||||
| [formId]="'eventIri'" | |||||
| [formLabelLangKey]="'model.event'" | |||||
| [documentForm]="eventForms[i]" | |||||
| [getDataFunction]="getEvents" | |||||
| [displayedDataField]="'name'" | |||||
| [listColDefinitions]="eventColDefinitions" | |||||
| [dataSet]="userTripEvent.event" | |||||
| > | |||||
| </app-search-select> | |||||
| </div> | |||||
| <div class="col-12 col-md-6 mb-3"> | |||||
| <label [for]="'location_' + i" class="form-label">{{ 'model.location' | translate }}*:</label> | |||||
| <app-search-select | |||||
| [formId]="'locationIri'" | |||||
| [formLabelLangKey]="'model.location'" | |||||
| [documentForm]="eventForms[i]" | |||||
| [getDataFunction]="getLocations" | |||||
| [displayedDataField]="'name'" | |||||
| [listColDefinitions]="locationColDefinitions" | |||||
| [dataSet]="userTripEvent.location" | |||||
| > | |||||
| </app-search-select> | |||||
| </div> | |||||
| <div class="col-12 col-md-3 mb-1"> | |||||
| <label class="form-label">{{ 'user_trip.event_date' | translate }} ({{ 'common.date' | translate }}):</label> | |||||
| <div> | |||||
| <input | |||||
| type="date" | |||||
| class="form-control" | |||||
| [value]="formatDateForInput(userTripEvent.date)" | |||||
| (change)="onDateInputChange($event, i)" | |||||
| /> | |||||
| </div> | |||||
| </div> | |||||
| <div class="col-12 col-md-3 mb-1"> | |||||
| <label class="form-label">{{ 'user_trip.event_date' | translate }} ({{ 'common.time' | translate }}):</label> | |||||
| <div> | |||||
| <input | |||||
| type="time" | |||||
| class="form-control" | |||||
| [value]="formatTimeForInput(userTripEvent.date)" | |||||
| (change)="onTimeInputChange($event, i)" | |||||
| /> | |||||
| </div> | |||||
| </div> | |||||
| <div class="col-12 col-md-4 mb-1"> | |||||
| <label [for]="'note_' + i" class="form-label">{{ 'common.note' | translate }}:</label> | |||||
| <textarea | |||||
| class="form-control" | |||||
| [id]="'note_' + i" | |||||
| rows="2" | |||||
| [(ngModel)]="userTripEvent.note" | |||||
| ></textarea> | |||||
| </div> | |||||
| <div class="col-12 col-md-2 mb-1 d-flex align-items-end"> | |||||
| <button type="button" class="btn btn-danger" (click)="removeUserTripEvent(i)">X</button> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="row"> | |||||
| <div class="col-12 col-lg-6 mb-3"> | |||||
| <button type="button" class="btn btn-primary" (click)="addNewUserTripEvent()">+</button> | |||||
| </div> | |||||
| </div> | |||||
| <div class="row"> | |||||
| <div class="col-12 col-lg-6 mb-3"> | |||||
| <button type="button" class="btn btn-primary" (click)="saveAllUserTripEvents()"> | |||||
| {{ 'basic.save' | translate }} | |||||
| </button> | |||||
| </div> | |||||
| </div> | |||||
| <app-user-trip-event-list | |||||
| [userTrip]="userTrip" | |||||
| [showCreateButton]="true" | |||||
| > | |||||
| </app-user-trip-event-list> | |||||
| </div> | </div> | ||||
| </mat-tab> | </mat-tab> | ||||
| </mat-tab-group> | </mat-tab-group> | ||||
| @@ -73,6 +73,7 @@ import { UserFormComponent } from './_views/user/user-form/user-form.component'; | |||||
| import { ImageUploadComponent } from './_components/image-upload/image-upload.component'; | import { ImageUploadComponent } from './_components/image-upload/image-upload.component'; | ||||
| import { TripLocationListComponent } from './_views/trip/trip-location-list/trip-location-list.component'; | import { TripLocationListComponent } from './_views/trip/trip-location-list/trip-location-list.component'; | ||||
| import { TripLocationFormComponent } from './_views/trip/trip-location-form/trip-location-form.component'; | import { TripLocationFormComponent } from './_views/trip/trip-location-form/trip-location-form.component'; | ||||
| import { UserTripEventFormComponent } from './_views/user-trip-event/user-trip-event-form/user-trip-event-form.component'; | |||||
| registerLocaleData(localeDe, 'de-DE'); | registerLocaleData(localeDe, 'de-DE'); | ||||
| @@ -171,6 +172,7 @@ export function HttpLoaderFactory(http: HttpClient) { | |||||
| ImageUploadComponent, | ImageUploadComponent, | ||||
| TripLocationListComponent, | TripLocationListComponent, | ||||
| TripLocationFormComponent, | TripLocationFormComponent, | ||||
| UserTripEventFormComponent, | |||||
| ], | ], | ||||
| providers: [ | providers: [ | ||||
| {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}, | {provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true}, | ||||
| @@ -75,6 +75,7 @@ | |||||
| "trip_location": "Itinerary location", | "trip_location": "Itinerary location", | ||||
| "user": "User", | "user": "User", | ||||
| "user_trip": "Pilotage", | "user_trip": "Pilotage", | ||||
| "user_trip_event": "Pilotage event", | |||||
| "vessel": "Vessel", | "vessel": "Vessel", | ||||
| "zone": "Zone" | "zone": "Zone" | ||||
| }, | }, | ||||
| @@ -89,7 +90,7 @@ | |||||
| "customer_reference": "Customer reference", | "customer_reference": "Customer reference", | ||||
| "end_date": "End date", | "end_date": "End date", | ||||
| "end_location": "End location", | "end_location": "End location", | ||||
| "events": "Events", | |||||
| "events": "Events (accumulated)", | |||||
| "is_arrival": "Arrival", | "is_arrival": "Arrival", | ||||
| "is_departure": "Departure", | "is_departure": "Departure", | ||||
| "is_transit": "Transit", | "is_transit": "Transit", | ||||