import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { FormArray, FormControl, FormGroup } from '@angular/forms'; import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; import * as moment from 'moment'; import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'; import { AttendanceType } from '../attendance/attendance-type'; import { AuthService } from '../auth/auth.service'; import { ToasterService } from '../core/toaster.service'; import { Employee } from '../employee/employee'; import { EmployeeService } from '../employee/employee.service'; import { EmployeeAttendance } from './employee-attendance'; import { EmployeeAttendanceDataSource } from './employee-attendance-datasource'; import { EmployeeAttendanceItem } from './employee-attendance-item'; import { EmployeeAttendanceService } from './employee-attendance.service'; @Component({ selector: 'app-employee-attendance', templateUrl: './employee-attendance.component.html', styleUrls: ['./employee-attendance.component.css'], }) export class EmployeeAttendanceComponent implements OnInit, AfterViewInit { @ViewChild('employeeElement', { static: true }) employeeElement?: ElementRef; public employeeAttendanceObservable = new BehaviorSubject([]); dataSource: EmployeeAttendanceDataSource = new EmployeeAttendanceDataSource(this.employeeAttendanceObservable); form: FormGroup<{ startDate: FormControl; finishDate: FormControl; employee: FormControl; attendances: FormArray< FormGroup<{ attendanceType: FormControl; }> >; }>; info: EmployeeAttendance = new EmployeeAttendance(); attendanceTypes: AttendanceType[] = []; displayedColumns = ['date', 'status', 'prints']; employees: Observable; constructor( private route: ActivatedRoute, private router: Router, private dialog: MatDialog, private toaster: ToasterService, private auth: AuthService, private ser: EmployeeAttendanceService, private employeeSer: EmployeeService, ) { this.form = new FormGroup({ startDate: new FormControl(new Date(), { nonNullable: true }), finishDate: new FormControl(new Date(), { nonNullable: true }), employee: new FormControl(null), attendances: new FormArray }>>([]), }); // Listen to Employee Value Changes this.employees = this.form.controls.employee.valueChanges.pipe( debounceTime(150), distinctUntilChanged(), switchMap((x) => (x === null ? observableOf([]) : this.employeeSer.autocomplete(x))), ); } ngOnInit() { this.route.data.subscribe((value) => { const data = value as { info: EmployeeAttendance; attendanceTypes: AttendanceType[] }; this.info = data.info; this.attendanceTypes = data.attendanceTypes; this.form.controls.startDate.setValue(moment(this.info.startDate, 'DD-MMM-YYYY').toDate()); this.form.controls.finishDate.setValue(moment(this.info.finishDate, 'DD-MMM-YYYY').toDate()); this.form.controls.employee.setValue(this.info.employee?.name ?? ''); this.form.controls.attendances.clear(); this.info.body.forEach((x) => this.form.controls.attendances.push( new FormGroup({ attendanceType: new FormControl(x.attendanceType.id, { nonNullable: true }), }), ), ); this.dataSource = new EmployeeAttendanceDataSource(this.employeeAttendanceObservable); this.employeeAttendanceObservable.next(this.info.body); }); } ngAfterViewInit() { setTimeout(() => { if (this.employeeElement) { this.employeeElement.nativeElement.focus(); } }, 0); } displayFn(employee?: Employee | string): string { return !employee ? '' : typeof employee === 'string' ? employee : employee.name; } selected(event: MatAutocompleteSelectedEvent): void { this.info.employee = event.option.value as Employee; } getClass(index: number) { const array = this.form.controls.attendances; const id = array.controls[index].value.attendanceType; const { name } = this.attendanceTypes.filter((x) => x.id === id)[0]; return name.toLowerCase().replace(/(\s+\+\s+)|(\s+)/g, '-'); } show() { const formValue = this.form.value; this.info.startDate = moment(formValue.startDate).format('DD-MMM-YYYY'); this.info.finishDate = moment(formValue.finishDate).format('DD-MMM-YYYY'); if (this.info.employee) { this.router.navigate(['/employee-attendance', this.info.employee.id], { queryParams: { startDate: this.info.startDate, finishDate: this.info.finishDate, }, }); } } save() { this.ser.save(this.getEmployeeAttendance()).subscribe( () => { this.toaster.show('Success', ''); }, (error) => { this.toaster.show('Danger', error); }, ); } getEmployeeAttendance(): EmployeeAttendance { const formValue = this.form.value; this.info.startDate = moment(formValue.startDate).format('DD-MMM-YYYY'); this.info.finishDate = moment(formValue.finishDate).format('DD-MMM-YYYY'); const array = this.form.value.attendances; if (array) { this.info.body.forEach((item, index) => { item.attendanceType.id = array[index].attendanceType ?? 0; }); } return this.info; } }