import { AsyncPipe, DatePipe } from '@angular/common'; import { ChangeDetectionStrategy, Component, inject, signal, } from '@angular/core'; import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { DialogService } from '@ngneat/dialog'; import { debounceTime, distinctUntilChanged, filter, switchMap, tap, } from 'rxjs'; import { Ticket, Tour, } from '../../../core/data-access/graphql/generated/generated'; import { TicketViewComponent } from '../ticket-view/ticket-view.component'; import { TicketsService } from '../tickets.service'; import { format, isAfter } from 'date-fns'; import { useTicketSearch } from 'src/app/core/tickets/tickets.queries'; import { NgIcon, provideIcons } from '@ng-icons/core'; import { HlmIcon } from '@spartan-ng/helm/icon'; import { lucideCircleAlert, lucideCalendarClock, lucideCar, } from '@ng-icons/lucide'; @Component({ template: `
Ticket suchen

Einsatznummer oder Patient
@if (searchQuery.isLoading()) {

Suche Tickets ...

} @if (searchQuery.data(); as result) { @for (ticket of result; track ticket.id) {
{{ ticket.patientName }}
@if (ticket.nextStart) {
{{ ticket.nextStart | date: 'dd.MM. HH:mm' }}
} @else { Bereits gefahren }
{{ ticket.tourCount }}
} }
`, imports: [ MatFormFieldModule, MatInputModule, FormsModule, NgIcon, HlmIcon, DatePipe, ], providers: [ provideIcons({ lucideCircleAlert, lucideCalendarClock, lucideCar, }), ], changeDetection: ChangeDetectionStrategy.OnPush, }) export class TicketsSearchDialogComponent { search = signal(''); searchQuery = useTicketSearch(this.search); private ticketsService = inject(TicketsService); private dialog = inject(DialogService); searchCtrl = new FormControl(''); tickets$ = this.searchCtrl.valueChanges.pipe( debounceTime(200), distinctUntilChanged(), filter((val) => !!val && val?.length > 2), switchMap((query) => this.ticketsService.searchTickets(query as string)), ); showTicketView(ticket: unknown): void { const dialogRef = this.dialog.open(TicketViewComponent, { data: (ticket as Ticket)?.id as string, width: '60vw', minHeight: '400px', }); dialogRef.afterClosed$ .pipe(tap((result) => result && this.showTicketView(result))) .subscribe(); } getToursLength(ticket: unknown) { return (ticket as Ticket & { tours: Tour[] }).tours.filter( ({ check }) => check === 0, ).length; } getNextStart(tours: Partial[]) { const sortedStartDates = [ ...tours.map(({ startDate }) => new Date(startDate)), ].sort((a, b) => a.getTime() - b.getTime()); for (let i = 0; i < sortedStartDates.length; i++) { const currentDate = sortedStartDates.at(i); if (currentDate && isAfter(currentDate, new Date())) { return format(currentDate, 'HH:mm | dd.MM.yy'); } } const latestDate = sortedStartDates.at(-1); return latestDate ? format(latestDate, 'HH:mm | dd.MM.yy') : 'No Tours'; } }