import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { UntypedFormArray, UntypedFormBuilder, UntypedFormControl, UntypedFormGroup } 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, map, startWith, 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: UntypedFormGroup; info: EmployeeAttendance = new EmployeeAttendance(); attendanceTypes: AttendanceType[] = []; displayedColumns = ['date', 'status', 'prints']; employees: Observable; constructor( private route: ActivatedRoute, private router: Router, private fb: UntypedFormBuilder, private dialog: MatDialog, private toaster: ToasterService, private auth: AuthService, private ser: EmployeeAttendanceService, private employeeSer: EmployeeService, ) { this.form = this.fb.group({ startDate: '', finishDate: '', employee: '', attendances: this.fb.array([]), }); // Listen to Employee Value Changes this.employees = (this.form.get('employee') as UntypedFormControl).valueChanges.pipe( startWith(null), map((x) => (x !== null && x.length >= 1 ? x : null)), 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.get('startDate') as UntypedFormControl).setValue( moment(this.info.startDate, 'DD-MMM-YYYY').toDate(), ); (this.form.get('finishDate') as UntypedFormControl).setValue( moment(this.info.finishDate, 'DD-MMM-YYYY').toDate(), ); (this.form.get('employee') as UntypedFormControl).setValue(this.info.employee); this.form.setControl( 'attendances', this.fb.array( this.info.body.map((x) => this.fb.group({ attendanceType: x.attendanceType.id, }), ), ), ); 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 { return employee ? employee.name : ''; } selected(event: MatAutocompleteSelectedEvent): void { this.info.employee = event.option.value; } getClass(index: number) { const array = this.form.get('attendances') as UntypedFormArray; 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'); 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.get('attendances') as UntypedFormArray; this.info.body.forEach((item, index) => { item.attendanceType.id = array.controls[index].value.attendanceType; }); return this.info; } get attendancesArray(): UntypedFormArray { return this.form.get('attendances') as UntypedFormArray; } }