105 lines
2.9 KiB
TypeScript
105 lines
2.9 KiB
TypeScript
import { Component, Input, OnInit } from '@angular/core';
|
|
import { AbstractControl, FormControl, ValidationErrors } from '@angular/forms';
|
|
import { AutoUnsubscribe } from 'ngx-auto-unsubscribe-decorator';
|
|
import {
|
|
DecodedPref,
|
|
PrefValueType,
|
|
} from 'picsur-shared/dist/dto/preferences.dto';
|
|
import { AsyncFailable, HasFailed } from 'picsur-shared/dist/types/failable';
|
|
import { filter } from 'rxjs';
|
|
import { ZodTypeAny } from 'zod';
|
|
import { Required } from '../../models/decorators/required.decorator';
|
|
import { Logger } from '../../services/logger/logger.service';
|
|
import { ErrorService } from '../../util/error-manager/error.service';
|
|
import { Throttle } from '../../util/throttle';
|
|
|
|
@Component({
|
|
selector: 'pref-option',
|
|
templateUrl: './pref-option.component.html',
|
|
styleUrls: ['./pref-option.component.scss'],
|
|
})
|
|
export class PrefOptionComponent implements OnInit {
|
|
private readonly logger = new Logger(PrefOptionComponent.name);
|
|
|
|
public formControl = new FormControl<any>(undefined, {
|
|
updateOn: 'blur',
|
|
validators: this.syncValidator.bind(this),
|
|
});
|
|
|
|
private pref: DecodedPref;
|
|
@Input('pref') set prefSet(pref: DecodedPref) {
|
|
this.pref = pref;
|
|
this.formControl.setValue(pref.value);
|
|
}
|
|
get type() {
|
|
return this.pref.type;
|
|
}
|
|
|
|
@Input('update') @Required updateFunction: (
|
|
key: string,
|
|
pref: PrefValueType,
|
|
) => AsyncFailable<any>;
|
|
|
|
@Input() @Required name = '';
|
|
@Input() helpText = '';
|
|
@Input() validator?: ZodTypeAny = undefined;
|
|
|
|
constructor(private readonly errorService: ErrorService) {}
|
|
|
|
ngOnInit(): void {
|
|
this.subscribeUpdate();
|
|
}
|
|
|
|
getErrorMessage() {
|
|
if (this.formControl.errors) {
|
|
const errors = this.formControl.errors;
|
|
if (errors['error']) {
|
|
return errors['error'];
|
|
}
|
|
return 'Invalid value';
|
|
}
|
|
return '';
|
|
}
|
|
|
|
private syncValidator(control: AbstractControl): ValidationErrors | null {
|
|
if (!this.validator) return null;
|
|
|
|
const result = this.validator.safeParse(control.value);
|
|
|
|
if (!result.success) {
|
|
return { error: result.error.issues[0]?.message ?? 'Invalid value' };
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private async updatePreference(value: PrefValueType) {
|
|
const result = await this.updateFunction(this.pref.key, value);
|
|
if (!HasFailed(result)) {
|
|
const message =
|
|
this.pref.type === 'string'
|
|
? `Updated ${this.name}`
|
|
: this.pref.type === 'number'
|
|
? `Updated ${this.name}`
|
|
: this.pref.type === 'boolean'
|
|
? value
|
|
? `Enabled ${this.name}`
|
|
: `Disabled ${this.name}`
|
|
: '';
|
|
this.errorService.success(message);
|
|
} else {
|
|
this.errorService.showFailure(result, this.logger);
|
|
}
|
|
}
|
|
|
|
@AutoUnsubscribe()
|
|
subscribeUpdate() {
|
|
return this.formControl.valueChanges
|
|
.pipe(
|
|
filter(() => this.formControl.errors === null),
|
|
Throttle(300),
|
|
)
|
|
.subscribe(this.updatePreference.bind(this));
|
|
}
|
|
}
|