import { AfterViewInit, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { FormArray, FormBuilder, FormGroup } from '@angular/forms'; import { MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; import { BehaviorSubject, Observable, of as observableOf } from 'rxjs'; import { EmployeeAttendanceDataSource } from './employee-attendance-datasource'; import * as moment from 'moment'; import { AuthService } from '../auth/auth.service'; import { ToasterService } from '../core/toaster.service'; import { EmployeeAttendanceService } from './employee-attendance.service'; import { EmployeeAttendance, EmployeeAttendanceItem } from './employee-attendance'; import { EmployeeService } from '../employee/employee.service'; import { Employee } from '../employee/employee'; import { debounceTime, distinctUntilChanged, map, startWith, switchMap } from 'rxjs/operators'; import { AttendanceType } from '../attendance/attendance-type'; @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; form: FormGroup; info: EmployeeAttendance; attendanceTypes: AttendanceType[]; displayedColumns = ['date', 'status', 'prints']; employees: Observable; constructor( private route: ActivatedRoute, private router: Router, private fb: FormBuilder, private dialog: MatDialog, private toaster: ToasterService, private auth: AuthService, private ser: EmployeeAttendanceService, private employeeSer: EmployeeService, ) { this.createForm(); this.listenToEmployeeValueChanges(); } ngOnInit() { this.route.data.subscribe( (data: { info: EmployeeAttendance; attendanceTypes: AttendanceType[] }) => { this.info = data.info; this.attendanceTypes = data.attendanceTypes; this.form.get('startDate').setValue(moment(this.info.startDate, 'DD-MMM-YYYY').toDate()); this.form.get('finishDate').setValue(moment(this.info.finishDate, 'DD-MMM-YYYY').toDate()); this.form.get('employee').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(() => { this.employeeElement.nativeElement.focus(); }, 0); } createForm() { this.form = this.fb.group({ startDate: '', finishDate: '', employee: '', attendances: this.fb.array([]), }); } listenToEmployeeValueChanges() { this.employees = this.form.get('employee').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))), ); } displayFn(employee?: Employee): string | undefined { return employee ? employee.name : undefined; } selected(event: MatAutocompleteSelectedEvent): void { this.info.employee = event.option.value; } getClass(index: number) { const array = this.form.get('attendances') as FormArray; const id = array.controls[index].value.attendanceType; const name: string = this.attendanceTypes.filter((x) => x.id === id)[0].name; 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( (result) => { 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 FormArray; this.info.body.forEach((item, index) => { item.attendanceType.id = array.controls[index].value.attendanceType; }); return this.info; } }