import { AfterViewChecked, AfterViewInit, Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; import { IcsNotificationService } from './ics-notification.service'; import { FormValues } from './types/form-values'; import { NotificationRule } from './types/notification-rule'; import { AbstractControl, Form, FormArray, FormBuilder, FormControl, FormGroup, ValidationErrors, Validators } from '@angular/forms'; import { Notification } from './types/notification'; import { formValues } from './mock-data/form-values'; import { IcsToastService } from '@varmasagi/ics-toast'; import { FormUtil } from './utils/form-util'; import { IMAGES } from './config'; import { NotificationInputs } from './types/notification-inputs'; import { NameValue } from '@varmasagi/ics-common-types'; import { Observable, Subscriber } from 'rxjs'; import { catchError, map, startWith } from 'rxjs/operators'; import { TimePickerComponent } from './time-picker/time-picker.component'; import { Time } from './types/time'; import { IcsDialogService, DialogData } from '@varmasagi/ics-dialog'; @Component({ selector: 'ics-notification', templateUrl: './ics-notification.component.html', styleUrls: ['./ics-notification-component.scss'] }) export class IcsNotificationComponent implements OnInit { @Input() inputs: NotificationInputs; @Output() exit$: EventEmitter; @ViewChild(TimePickerComponent) private timePicker: TimePickerComponent; private subscriptionId: number; public formValues: FormValues; public formGroup: FormGroup; public images: any = IMAGES; public time: any; public filteredZones: Observable; public frequencies$: Observable; private notification: Notification; public notificationId: number; private frequenciesCache: any = {}; constructor( private service: IcsNotificationService, private toast: IcsToastService, private formBuilder: FormBuilder, private dialog: IcsDialogService ) { this.exit$ = new EventEmitter(); this.notification = new Notification(); } fetchFormValues = ()=>{ this.service .fetchFormValues( this.inputs.application.value, this.inputs.platform.value, this.inputs.context.value ) .subscribe( response => { const message = response.message; if (!message) { // response is instance of FormValues this.formValues = response; this.initializeFormGroup(); } else { //case when no more rules available to subscribe, show the message no notifications this.toast.success(message); this.exit$.emit(); } }, error1 => { const message = error1.error.message || ''; this.toast.error(message); this.exit$.emit(); } ); } ngOnInit() { if (this.inputs.subscriptionId) { this.subscriptionId = this.inputs.subscriptionId; this.getNotification(this.subscriptionId); } else{ this.fetchFormValues(); } } initializeFormGroup() { if(this.subscriptionId){ let filteredRule = this.formValues.rules.filter(rule=>this.notification.rule.ruleId==rule.ruleId); if(filteredRule.length==0) this.formValues.rules.unshift(this.notification.rule); this.notification.rule = this.formValues.rules[0]; this.frequencies$ = this.service.fetchFrequencies(this.notification.rule.ruleId); this.frequencies$.subscribe(); } this.formGroup = this.formBuilder.group({ rule: [this.notification.rule, [Validators.required]], frequency: [this.notification.frequency, [Validators.required]], types: [this.notification.types, [Validators.required]], zone: [this.notification.zone, [Validators.required]], hour: [this.notification.time.hour, [Validators.required]], minute: [this.notification.time.minute, [Validators.required]] }); this.filteredZones = this.formGroup.get('zone').valueChanges.pipe( startWith(''), map(value => (typeof value === 'string' ? value : value.name)), map( name => (name ? this.filterZones(name) : this.formValues.zones.slice()) ) ); } getDescription() { const value: NotificationRule = this.formGroup.get('rule').value; return value ? value.description : ''; } onSubscribe() { FormUtil.markFormGroupTouched(this.formGroup); if (this.formGroup.valid) { this.buildNotification(); this.service.createNotification(this.notification).subscribe( res => { const message = res.message; this.toast.success(message); this.exit$.emit(); }, error1 => { const message = error1.message; this.toast.error(message); this.exit$.emit(); } ); } } buildNotification() { this.notification = this.formGroup.value; this.notification.time = new Time(); this.notification.time.hour = this.formGroup.value.hour; this.notification.time.minute = this.formGroup.value.minute; this.notification.platformId = this.inputs.platform.value; this.notification.applicationId = this.inputs.application.value; } onNotificationRuleChange(rule: NotificationRule) { const frequencyControl = this.formGroup.get('frequency'); const frequencies = this.frequenciesCache[rule.ruleId]; if (frequencies) { this.frequencies$ = new Observable( (subscriber: Subscriber) => subscriber.next(frequencies) ); return; } this.frequencies$ = this.service.fetchFrequencies(rule.ruleId); this.frequencies$.subscribe(res => { this.frequenciesCache[rule.value] = res; const firstValue = res[0]; frequencyControl.patchValue(firstValue); }); } fieldError(key: string): string { let error = ''; try { const abstractControl: AbstractControl = this.formGroup.get(key); if (!abstractControl.touched) { return error; } const controlErrors: ValidationErrors = abstractControl.errors; if (controlErrors != null) { Object.keys(controlErrors).forEach(keyError => { error += key + ' is ' + keyError; }); } } catch (e) {} return error; } private filterZones(name: string): NameValue[] { const filterValue = name.toLowerCase(); return this.formValues.zones.filter(option => option.name.toLowerCase().includes(filterValue) ); } displayFn(pair?: NameValue): string | undefined { return pair ? pair.name : undefined; } compareRules(a: NotificationRule, b: NotificationRule){ return a.value === b.value; } compareWith(a: NameValue, b: NameValue) { return a.name === b.name && a.value === b.value; } /** * returns the notification corresponding to the subscription Id. * @param - Subscription Id. */ getNotification = (subscriptionId: number) => { this.service.getNotification(subscriptionId).subscribe( response => { this.notification = response.raw; this.notificationId = response.id; this.fetchFormValues(); }, error => { this.notification = new Notification(); this.toast.error(error.message||'Could not fetch notification!'); this.exit$.emit(); } ); }; update = () => { this.buildNotification(); this.service .updateNotification(this.notificationId, this.notification,this.subscriptionId) .subscribe( res => { const message = res.message; this.toast.success(message); this.exit$.emit(); }, error1 => { const message = error1.message; this.toast.error(message); this.exit$.emit(); } ); }; unSubscribe = () =>{ let dialogData: DialogData = new DialogData(); dialogData.title = 'Are you sure you want to unsubscribe?'; dialogData.message = 'Unsubscribing will stop notifications for '+this.notification.rule.name; this.dialog.confirm(dialogData).subscribe(response=>{ if(response){ this.service.updateSubscription(this.subscriptionId,false).subscribe( res => { const message = res.message; this.toast.success(message); this.exit$.emit(); }, error1 => { const message = error1.message; this.toast.error(message); this.exit$.emit(); } ); } }); } }