178 lines
5.5 KiB
TypeScript
178 lines
5.5 KiB
TypeScript
import { AfterContentInit, Component, HostListener, Input, OnDestroy, OnInit, forwardRef } from '@angular/core';
|
|
import { FormBuilder, FormControl, FormGroup, NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
import { Trial } from '@app/domain/models/subscription.model';
|
|
import { BaseComp } from '@app/shared/base/base.component';
|
|
import { GC } from '@app/shared/global';
|
|
import { DateUtils } from '@app/shared/utils';
|
|
import { SelectItem } from 'primeng-lts/api';
|
|
|
|
const MIN_DAYS = 7;
|
|
|
|
@Component({
|
|
selector: 'trial',
|
|
templateUrl: './trial.component.html',
|
|
styleUrls: ['./trial.component.css'],
|
|
providers: [
|
|
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TrialComponent), multi: true },
|
|
{ provide: NG_VALIDATORS, useExisting: forwardRef(() => TrialComponent), multi: true }
|
|
]
|
|
})
|
|
export class TrialComponent extends BaseComp implements OnDestroy, OnInit, AfterContentInit {
|
|
@Input() trialDays: number[];
|
|
@Input() trials: Trial;
|
|
@Input() disable: boolean;
|
|
|
|
DAYS = GC.DAYS;
|
|
BYDATE = GC.BYDATE;
|
|
|
|
dayItems: SelectItem[];
|
|
form: FormGroup;
|
|
toDate: Date;
|
|
error: string;
|
|
calMinDate: Date;
|
|
calMaxDate: Date;
|
|
onChange: any = () => { };
|
|
onTouched: any = () => { };
|
|
|
|
constructor(
|
|
private readonly fb: FormBuilder
|
|
) {
|
|
super();
|
|
const ONE_YEAR = 1;
|
|
this.calMinDate = new Date();
|
|
this.calMinDate.setDate(this.calMinDate.getDate() + MIN_DAYS);
|
|
this.calMinDate.setHours(0, 0, 0);
|
|
this.calMaxDate = new Date();
|
|
this.calMaxDate.setFullYear(this.calMaxDate.getFullYear() + ONE_YEAR);
|
|
}
|
|
|
|
get value() {
|
|
return this.form.value;
|
|
}
|
|
|
|
set value(val) {
|
|
this.writeValue(val);
|
|
this.onChange(val);
|
|
this.onTouched(val);
|
|
}
|
|
|
|
ngOnInit(): void {
|
|
this.form = this.fb.group({
|
|
selected: new FormControl({ value: false, disabled: this.disable }),
|
|
type: new FormControl({ value: '', disabled: this.disable }),
|
|
startDate: [],
|
|
lastEndDate: [],
|
|
lastStartDate: [],
|
|
trialDays: new FormControl({ value: '', disabled: this.disable }),
|
|
byDate: []
|
|
});
|
|
this.dayItems = this.trialDays?.map((day) => ({ label: `${day}`, value: day }));
|
|
|
|
this.sub$.add(this.form.valueChanges.subscribe((val) => {
|
|
this.onChange(val);
|
|
this.onTouched(val);
|
|
}));
|
|
}
|
|
|
|
ngAfterContentInit() {
|
|
const hasExistingTrial = this.trials?.type && (this.trials.trialDays >= MIN_DAYS || this.trials.byDate);
|
|
if (hasExistingTrial) {
|
|
if (this.trials.type === this.BYDATE && this.trials.byDate) {
|
|
this.toDate = new Date(this.trials.byDate);
|
|
this.form.patchValue({ ...this.trials, selected: true });
|
|
} else if (this.trials.type === this.DAYS && this.trials.trialDays >= MIN_DAYS) {
|
|
this.form.patchValue({ ...this.trials, selected: true });
|
|
} else {
|
|
this.form.patchValue({ ...this.trials });
|
|
}
|
|
}
|
|
}
|
|
|
|
writeValue(val): void {
|
|
if (val) {
|
|
this.form.patchValue(val);
|
|
}
|
|
}
|
|
|
|
registerOnChange(fn: any): void {
|
|
this.onChange = fn;
|
|
}
|
|
|
|
registerOnTouched(fn: any): void {
|
|
this.onTouched = fn;
|
|
}
|
|
|
|
validate() {
|
|
this.checkAndDisplayErr();
|
|
const isTrial = this.form.value.selected;
|
|
const isInValid = !this.isValidTrialDays() && !this.isValidBydate();
|
|
return isTrial ? isInValid ? { trials: { valid: false } } : null : null;
|
|
}
|
|
|
|
isValidTrialDays() {
|
|
return this.form.value.type === this.DAYS && this.form.value.trialDays && !isNaN(this.form.value.trialDays) && this.form.value.trialDays >= MIN_DAYS;
|
|
}
|
|
|
|
isValidBydate() {
|
|
return this.form.value.type === this.BYDATE && this.form.value.byDate;
|
|
}
|
|
|
|
change() {
|
|
const noPrevTrial = !this.form.value.type;
|
|
if (noPrevTrial) {
|
|
this.form.patchValue({ type: this.DAYS });
|
|
}
|
|
|
|
const trialDays = this.form.value.trialDays;
|
|
const notExistItem = this.dayItems?.every((item) => item.value != trialDays);
|
|
if (this.isValidTrialDays() && notExistItem) {
|
|
this.dayItems.push({ label: `${trialDays}`, value: Number(trialDays) });
|
|
this.dayItems.sort((a, b) => a.value - b.value);
|
|
this.appConf.saveTrialDays(this.dayItems?.map((item) => item.value));
|
|
}
|
|
|
|
this.form.updateValueAndValidity();
|
|
}
|
|
|
|
changeCal() {
|
|
this.form.patchValue({
|
|
...this.trials,
|
|
type: this.BYDATE,
|
|
byDate: DateUtils.tsToDate(
|
|
DateUtils.endUtcTS(
|
|
DateUtils.dateToTS(this.toDate)))
|
|
});
|
|
this.form.updateValueAndValidity();
|
|
}
|
|
|
|
checkAndDisplayErr() {
|
|
this.error = '';
|
|
if (this.form.value.selected && this.form.value.type === this.BYDATE) {
|
|
if (!this.toDate) {
|
|
return this.error = `Please fill in end date MM/DD/YYYY from <the mininum ${MIN_DAYS} days ahead>`;
|
|
}
|
|
} else if (this.form.value.selected && this.form.value.type === this.DAYS) {
|
|
if (!this.form.value.trialDays) {
|
|
return this.error = 'Please fill in the number of end days';
|
|
} else if (isNaN(this.form.value.trialDays) || this.form.value.trialDays < MIN_DAYS) {
|
|
return this.error = `Number of days must be number greater than <the mininum ${MIN_DAYS} days ahead>.`;
|
|
}
|
|
}
|
|
return this.error;
|
|
}
|
|
|
|
remove(item) {
|
|
this.dayItems = this.dayItems?.filter((day) => day.label !== item.label);
|
|
this.appConf.saveTrialDays(this.dayItems?.map((item) => item.value));
|
|
}
|
|
|
|
@HostListener('document:keydown.enter', ['$event']) onKeydownHandler(e: KeyboardEvent) {
|
|
const target = <HTMLInputElement>e.target;
|
|
if (target.name === this.BYDATE) this.changeCal();
|
|
}
|
|
|
|
ngOnDestroy(): void {
|
|
super.ngOnDestroy();
|
|
}
|
|
}
|