Compare commits
3 Commits
8ca16936a8
...
d8f82bb2d1
| Author | SHA1 | Date | |
|---|---|---|---|
| d8f82bb2d1 | |||
| 390241aa53 | |||
| b323f7a29f |
@@ -22,8 +22,8 @@ export class CarClient {
|
|||||||
return this.http.post<Car>(`${this.apiBasePath}/v1/cars`, request);
|
return this.http.post<Car>(`${this.apiBasePath}/v1/cars`, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(request: UpdateCarRequest): Observable<Car> {
|
update(id: string, request: UpdateCarRequest): Observable<Car> {
|
||||||
return this.http.put<Car>(`${this.apiBasePath}/v1/cars`, request);
|
return this.http.put<Car>(`${this.apiBasePath}/v1/cars/${id}`, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(id: string): Observable<void> {
|
delete(id: string): Observable<void> {
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ export class ConsumptionClient {
|
|||||||
return this.http.get<ConsumptionEntry>(`${this.apiBasePath}/v1/consumptions/${id}`);
|
return this.http.get<ConsumptionEntry>(`${this.apiBasePath}/v1/consumptions/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
create(request: CreateCarRequest): Observable<ConsumptionEntry> {
|
create(request: CreateConsumptionEntry): Observable<ConsumptionEntry> {
|
||||||
return this.http.post<ConsumptionEntry>(`${this.apiBasePath}/v1/consumptions`, request);
|
return this.http.post<ConsumptionEntry>(`${this.apiBasePath}/v1/consumptions`, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(request: UpdateCarRequest): Observable<ConsumptionEntry> {
|
update(id: string, request: UpdateConsumptionEntry): Observable<ConsumptionEntry> {
|
||||||
return this.http.put<ConsumptionEntry>(`${this.apiBasePath}/v1/consumptions`, request);
|
return this.http.put<ConsumptionEntry>(`${this.apiBasePath}/v1/consumptions/${id}`, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(id: string): Observable<void> {
|
delete(id: string): Observable<void> {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Component, computed, inject, Signal } from '@angular/core';
|
import { Component, computed, DestroyRef, inject, input, Signal } from '@angular/core';
|
||||||
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
|
||||||
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
@@ -14,8 +14,11 @@ import { InputTextModule } from 'primeng/inputtext';
|
|||||||
import { MultiSelectModule } from 'primeng/multiselect';
|
import { MultiSelectModule } from 'primeng/multiselect';
|
||||||
import { SelectModule } from 'primeng/select';
|
import { SelectModule } from 'primeng/select';
|
||||||
import { SkeletonModule } from 'primeng/skeleton';
|
import { SkeletonModule } from 'primeng/skeleton';
|
||||||
import { map } from 'rxjs';
|
import { catchError, EMPTY, map, Observable, switchMap, tap, throwError } from 'rxjs';
|
||||||
import { RequiredMarkerComponent } from './components/required-marker.component';
|
import { RequiredMarkerComponent } from './components/required-marker.component';
|
||||||
|
import { ConsumptionClient } from '@vegasco-web/api/consumptions/consumption-client';
|
||||||
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
|
import { MessageService } from 'primeng/api';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-edit-entry',
|
selector: 'app-edit-entry',
|
||||||
@@ -40,14 +43,19 @@ import { RequiredMarkerComponent } from './components/required-marker.component'
|
|||||||
export class EditEntryComponent {
|
export class EditEntryComponent {
|
||||||
private readonly formBuilder = inject(FormBuilder);
|
private readonly formBuilder = inject(FormBuilder);
|
||||||
private readonly carClient = inject(CarClient);
|
private readonly carClient = inject(CarClient);
|
||||||
|
private readonly consumptionClient = inject(ConsumptionClient);
|
||||||
private readonly router = inject(Router);
|
private readonly router = inject(Router);
|
||||||
|
private readonly destroyRef = inject(DestroyRef);
|
||||||
|
private readonly messageService = inject(MessageService);
|
||||||
|
|
||||||
|
protected readonly entryId = input<string | undefined>(undefined);
|
||||||
|
|
||||||
protected readonly formFieldNames = {
|
protected readonly formFieldNames = {
|
||||||
car: 'car',
|
car: 'car',
|
||||||
date: 'date',
|
date: 'date',
|
||||||
mileage: 'mileage',
|
mileage: 'mileage',
|
||||||
amount: 'amount',
|
amount: 'amount',
|
||||||
}
|
} as const;
|
||||||
|
|
||||||
protected readonly formGroup = this.formBuilder.group({
|
protected readonly formGroup = this.formBuilder.group({
|
||||||
[this.formFieldNames.car]: [<Car | null>null, Validators.required],
|
[this.formFieldNames.car]: [<Car | null>null, Validators.required],
|
||||||
@@ -84,88 +92,82 @@ export class EditEntryComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onSubmit(): void {
|
onSubmit(): void {
|
||||||
// if (!this.entryId) {
|
var entryId = this.entryId();
|
||||||
// this.createEntry();
|
if (entryId === undefined || entryId === null) {
|
||||||
// return;
|
this.createEntry();
|
||||||
// }
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// this.updateEntry();
|
this.updateEntry(entryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getFormData() {
|
||||||
|
var dateTime = new Date((this.formGroup.controls[this.formFieldNames.date].value ?? new Date).setHours(0, 0, 0, 0));
|
||||||
|
|
||||||
|
return {
|
||||||
|
carId: this.formGroup.controls[this.formFieldNames.car].value!.id,
|
||||||
|
dateTime: dateTime.toISOString(),
|
||||||
|
distance: this.formGroup.controls[this.formFieldNames.mileage].value!,
|
||||||
|
amount: this.formGroup.controls[this.formFieldNames.amount].value!,
|
||||||
|
ignoreInCalculation: false,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
createEntry() {
|
createEntry() {
|
||||||
// this.api
|
var request: CreateConsumptionEntry = this.getFormData();
|
||||||
// .createWeightEntry(
|
this.consumptionClient.create(request)
|
||||||
// this.getWeighedAt(),
|
.pipe(
|
||||||
// this.formGroup.controls['weight'].value,
|
takeUntilDestroyed(this.destroyRef),
|
||||||
// this.formGroup.controls['comment'].value,
|
catchError((error) => this.handleError(error)),
|
||||||
// this.formGroup.controls['rabbit'].value!.id,
|
switchMap(() => this.router.navigateByUrl('/entries'))
|
||||||
// this.formGroup.controls['medicines'].value?.map((x) => x.id) ?? [],
|
)
|
||||||
// )
|
.subscribe();
|
||||||
// .subscribe({
|
|
||||||
// next: (_) => {
|
|
||||||
// this.router.navigateByUrl('/weight-entries');
|
|
||||||
// },
|
|
||||||
// error: (error: HttpErrorResponse) => {
|
|
||||||
// switch (true) {
|
|
||||||
// case error.status >= 500 && error.status <= 599:
|
|
||||||
// this.messageService.add({
|
|
||||||
// severity: 'error',
|
|
||||||
// summary: 'Serverfehler',
|
|
||||||
// detail:
|
|
||||||
// 'Beim Erstellen des Eintrags ist ein Fehler aufgetreten. Bitte versuche es erneut.',
|
|
||||||
// });
|
|
||||||
// break;
|
|
||||||
// case error.status == 400:
|
|
||||||
// this.messageService.add({
|
|
||||||
// severity: 'error',
|
|
||||||
// summary: 'Clientfehler',
|
|
||||||
// detail:
|
|
||||||
// 'Die Anwendung scheint falsche Daten an den Server zu senden.',
|
|
||||||
// });
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateEntry() {
|
updateEntry(id: string) {
|
||||||
// this.api
|
var request: UpdateConsumptionEntry = this.getFormData();
|
||||||
// .updateWeightEntry(
|
this.consumptionClient.update(id, request)
|
||||||
// this.entryId!,
|
.pipe(
|
||||||
// this.getWeighedAt(),
|
takeUntilDestroyed(this.destroyRef),
|
||||||
// this.formGroup.controls['weight'].value,
|
catchError((error) => this.handleError(error)),
|
||||||
// this.formGroup.controls['comment'].value,
|
switchMap(() => this.router.navigateByUrl('/entries'))
|
||||||
// this.formGroup.controls['rabbit'].value!.id,
|
)
|
||||||
// this.formGroup.controls['medicines'].value?.map((x) => x.id) ?? [],
|
.subscribe();
|
||||||
// )
|
}
|
||||||
// .subscribe({
|
|
||||||
// next: (_) => {
|
private handleError(error: unknown): Observable<never> {
|
||||||
// this.router.navigateByUrl('/weight-entries');
|
if (!(error instanceof HttpErrorResponse)) {
|
||||||
// },
|
return throwError(() => error);
|
||||||
// error: (error: HttpErrorResponse) => {
|
}
|
||||||
// switch (true) {
|
|
||||||
// case error.status >= 500 && error.status <= 599:
|
switch (true) {
|
||||||
// this.messageService.add({
|
case error.status >= 500 && error.status <= 599:
|
||||||
// severity: 'error',
|
this.messageService.add({
|
||||||
// summary: 'Serverfehler',
|
severity: 'error',
|
||||||
// detail:
|
summary: 'Serverfehler',
|
||||||
// 'Beim Aktualisieren des Eintrags ist ein Fehler aufgetreten. Bitte versuche es erneut.',
|
detail:
|
||||||
// });
|
'Beim Erstellen des Eintrags ist ein Fehler aufgetreten. Bitte versuche es erneut.',
|
||||||
// break;
|
});
|
||||||
// case error.status == 400:
|
break;
|
||||||
// this.messageService.add({
|
case error.status == 400:
|
||||||
// severity: 'error',
|
this.messageService.add({
|
||||||
// summary: 'Clientfehler',
|
severity: 'error',
|
||||||
// detail:
|
summary: 'Clientfehler',
|
||||||
// 'Die Anwendung scheint falsche Daten an den Server zu senden.',
|
detail:
|
||||||
// });
|
'Die Anwendung scheint falsche Daten an den Server zu senden.',
|
||||||
// break;
|
});
|
||||||
// default:
|
break;
|
||||||
// break;
|
default:
|
||||||
// }
|
console.error(error);
|
||||||
// },
|
this.messageService.add({
|
||||||
// });
|
severity: 'error',
|
||||||
|
summary: 'Unerwarteter Fehler',
|
||||||
|
detail:
|
||||||
|
'Beim Erstellen des Eintrags hat der Server eine unerwartete Antwort zurückgegeben.',
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
<p-scrollTop />
|
<p-scrollTop />
|
||||||
<div class="mb-4 flex gap-2 md:justify-between">
|
<div class="mb-4 flex gap-2 md:justify-between">
|
||||||
<div class="basis-full lg:basis-1/4 md:basis-1/2 p-0">
|
<div class="basis-full lg:basis-1/4 md:basis-1/2 p-0">
|
||||||
<!-- <p-select styleClass="w-full" [formControl]="selectedRabbit" placeholder="Kaninchen" [showClear]="true"
|
<p-select styleClass="w-full" [formControl]="selectedCar" placeholder="Auto" [showClear]="true"
|
||||||
[options]="(rabbits$ | async)!" optionLabel="name" /> -->
|
[options]="(cars$ | async)!" optionLabel="name" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p-button label="Erstellen" routerLink="/entries/create">
|
<p-button label="Erstellen" routerLink="/entries/create">
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
import { AsyncPipe, CommonModule } from '@angular/common';
|
import { AsyncPipe, CommonModule } from '@angular/common';
|
||||||
import { Component, inject } from '@angular/core';
|
import { Component, inject } from '@angular/core';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { FormControl, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { RouterLink } from '@angular/router';
|
import { RouterLink } from '@angular/router';
|
||||||
import { CarClient } from '@vegasco-web/api/cars/car-client';
|
import { CarClient } from '@vegasco-web/api/cars/car-client';
|
||||||
import { ConsumptionClient } from '@vegasco-web/api/consumptions/consumption-client';
|
import { ConsumptionClient } from '@vegasco-web/api/consumptions/consumption-client';
|
||||||
|
import { MessageService } from 'primeng/api';
|
||||||
import { ButtonModule } from 'primeng/button';
|
import { ButtonModule } from 'primeng/button';
|
||||||
import { DataViewModule } from 'primeng/dataview';
|
import { DataViewModule } from 'primeng/dataview';
|
||||||
import { ScrollTopModule } from 'primeng/scrolltop';
|
import { ScrollTopModule } from 'primeng/scrolltop';
|
||||||
import { SelectModule } from 'primeng/select';
|
import { SelectModule } from 'primeng/select';
|
||||||
import { SkeletonModule } from 'primeng/skeleton';
|
import { SkeletonModule } from 'primeng/skeleton';
|
||||||
import {
|
import {
|
||||||
|
BehaviorSubject,
|
||||||
|
combineLatest,
|
||||||
map,
|
map,
|
||||||
Observable,
|
Observable,
|
||||||
|
startWith,
|
||||||
tap
|
tap
|
||||||
} from 'rxjs';
|
} from 'rxjs';
|
||||||
|
|
||||||
@@ -35,29 +39,57 @@ import {
|
|||||||
export class EntriesComponent {
|
export class EntriesComponent {
|
||||||
private readonly consumptionClient = inject(ConsumptionClient);
|
private readonly consumptionClient = inject(ConsumptionClient);
|
||||||
private readonly carClient = inject(CarClient);
|
private readonly carClient = inject(CarClient);
|
||||||
|
private readonly messageService = inject(MessageService);
|
||||||
|
|
||||||
protected readonly consumptionEntries$: Observable<ConsumptionEntry[]>;
|
protected readonly consumptionEntries$: Observable<ConsumptionEntry[]>;
|
||||||
protected readonly cars$: Observable<Car[]>;
|
protected readonly cars$: Observable<Car[]>;
|
||||||
|
|
||||||
protected readonly skeletonsIterationSource = Array(10).fill(0);
|
protected readonly skeletonsIterationSource = Array(10).fill(0);
|
||||||
|
|
||||||
|
protected readonly selectedCar = new FormControl<Car | null | undefined>(null);
|
||||||
|
|
||||||
|
private readonly deletedEntries$ = new BehaviorSubject(<string[]>[]);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.consumptionEntries$ = this.consumptionClient.getAll()
|
const consumptionEntries = this.consumptionClient.getAll()
|
||||||
|
.pipe(
|
||||||
|
map(response => response.consumptions)
|
||||||
|
);
|
||||||
|
|
||||||
|
this.consumptionEntries$ = combineLatest([
|
||||||
|
consumptionEntries,
|
||||||
|
this.selectedCar.valueChanges.pipe(startWith(null)),
|
||||||
|
this.deletedEntries$,
|
||||||
|
])
|
||||||
.pipe(
|
.pipe(
|
||||||
takeUntilDestroyed(),
|
takeUntilDestroyed(),
|
||||||
tap((response) => {
|
map(([entries, selectedCar, deletedEntries]) => {
|
||||||
console.log('Entries response:', response);
|
const nonDeletedEntries =
|
||||||
}),
|
deletedEntries.length === 0
|
||||||
map(response => response.consumptions)
|
? entries
|
||||||
|
: entries.filter(entry => !deletedEntries.includes(entry.id));
|
||||||
|
|
||||||
|
if (!selectedCar) {
|
||||||
|
return nonDeletedEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nonDeletedEntries.filter(entry => entry.carId === selectedCar.id);
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
this.cars$ = this.carClient.getAll()
|
this.cars$ = this.carClient.getAll()
|
||||||
.pipe(
|
.pipe(
|
||||||
takeUntilDestroyed(),
|
takeUntilDestroyed(),
|
||||||
tap((response) => {
|
|
||||||
console.log('Cars response:', response);
|
|
||||||
}),
|
|
||||||
map(response => response.cars)
|
map(response => response.cars)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onEntryDeleted(entry: ConsumptionEntry): void {
|
||||||
|
this.deletedEntries$.next([...this.deletedEntries$.value, entry.id]);
|
||||||
|
this.messageService.add({
|
||||||
|
severity: 'success',
|
||||||
|
summary: 'Eintrag gelöscht',
|
||||||
|
detail: 'Der Eintrag wurde erfolgreich gelöscht.',
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user