Warning, /firebird/firebird-ng/src/app/utils/config-property.ts is written in an unsupported language. File is not indexed.
0001 import {BehaviorSubject, Observable} from 'rxjs';
0002
0003
0004 /**
0005 * Storage general interface for storing ConfigProperty-ies.
0006 * ConfigProperty uses the storage to save and load values
0007 */
0008 interface ConfigPropertyStorage {
0009 getItem(key: string): string | null;
0010 setItem(key: string, value: string): void;
0011 }
0012
0013 /**
0014 * Use local storage to save load ConfigProperty
0015 */
0016 class ConfigPropertyLocalStorage implements ConfigPropertyStorage {
0017 getItem(key: string): string | null {
0018 return localStorage.getItem(key);
0019 }
0020
0021 setItem(key: string, value: string): void {
0022 localStorage.setItem(key, value);
0023 }
0024 }
0025
0026 /**
0027 * Manages an individual configuration property. Provides reactive updates to subscribers,
0028 * persistence to localStorage, and optional value validation.
0029 *
0030 * @template T The type of the configuration value.
0031 */
0032 export class ConfigProperty<T> {
0033 public subject: BehaviorSubject<T>;
0034
0035 /** Observable for subscribers to react to changes in the property value. */
0036 public changes$: Observable<T>;
0037
0038 /**
0039 * Creates an instance of ConfigProperty.
0040 *
0041 * @param {string} key The localStorage key under which the property value is stored.
0042 * @param {T} defaultValue The default value of the property if not previously stored.
0043 * @param storage
0044 * @param {() => void} saveCallback The callback to execute after setting a new value.
0045 * @param {(value: T) => boolean} [validator] Optional validator function to validate the property value.
0046 */
0047 constructor(
0048 private key: string,
0049 private defaultValue: T,
0050 private saveCallback?: () => void,
0051 private validator?: (value: T) => boolean,
0052 private storage: ConfigPropertyStorage = new ConfigPropertyLocalStorage(),
0053 ) {
0054 const value = this.loadValue();
0055 this.subject = new BehaviorSubject<T>(value);
0056 this.changes$ = this.subject.asObservable();
0057
0058 }
0059
0060
0061 /**
0062 * Loads the property value from localStorage or returns the default value if not found or invalid.
0063 *
0064 * @returns {T} The loaded or default value of the property.
0065 */
0066 private loadValue(): T {
0067 let storedValue: string|null = null;
0068 let parsedValue: any = undefined;
0069 try {
0070 storedValue = this.storage.getItem(this.key);
0071
0072 if (storedValue !== null) {
0073 parsedValue = (typeof this.defaultValue) !== 'string' ? JSON.parse(storedValue) : storedValue;
0074 } else {
0075 parsedValue = this.defaultValue;
0076 }
0077 return this.validator && !this.validator(parsedValue) ? this.defaultValue : parsedValue;
0078 } catch (error) {
0079 console.error(`Error at ConfigProperty.loadValue, key='${this.key}'`);
0080 console.log(' storedValue', storedValue);
0081 console.log(' parsedValue', parsedValue);
0082 console.log(' Default value will be used: ', this.defaultValue);
0083 console.log(error);
0084
0085 return this.defaultValue;
0086 }
0087 }
0088
0089 /**
0090 * Sets the property value after validation. If the value is valid, it updates the property and calls the save callback.
0091 *
0092 * @param {T} value The new value to set for the property.
0093 */
0094 set value(value: T) {
0095 if (this.validator && !this.validator(value)) {
0096 console.error('Validation failed for:', value);
0097 return;
0098 }
0099 this.storage.setItem(this.key, typeof value !== 'string' ? JSON.stringify(value) : value);
0100
0101 if(this.saveCallback) {
0102 this.saveCallback();
0103 }
0104
0105 this.subject.next(value);
0106 }
0107
0108 /**
0109 * Gets the current value of the property.
0110 *
0111 * @returns {T} The current value of the property.
0112 */
0113 get value(): T {
0114 return this.subject.value;
0115 }
0116
0117
0118 /**
0119 * Resets value to its default given at Config construction
0120 */
0121 public setDefault() {
0122 this.subject.next(this.defaultValue);
0123 }
0124 }