Back to home page

EIC code displayed by LXR

 
 

    


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    * Loads the property value from localStorage or returns the default value if not found or invalid.
0062    *
0063    * @returns {T} The loaded or default value of the property.
0064    */
0065   private loadValue(): T {
0066     let storedValue: string|null = null;
0067     let parsedValue: any = undefined;
0068     try {
0069       storedValue = this.storage.getItem(this.key);
0070 
0071       if (storedValue !== null) {
0072         parsedValue = (typeof this.defaultValue) !== 'string' ? JSON.parse(storedValue) : storedValue;
0073       } else {
0074         parsedValue = this.defaultValue;
0075       }
0076       return this.validator && !this.validator(parsedValue) ? this.defaultValue : parsedValue;
0077     } catch (error) {
0078       console.error(`Error at ConfigProperty.loadValue, key='${this.key}'`);
0079       console.log('   storedValue', storedValue);
0080       console.log('   parsedValue', parsedValue);
0081       console.log('   Default value will be used: ', this.defaultValue);
0082       console.log(error);
0083 
0084       return this.defaultValue;
0085     }
0086   }
0087 
0088   /**
0089    * Sets the property value after validation. If the value is valid, it updates the property and calls the save callback.
0090    *
0091    * @param {T} value The new value to set for the property.
0092    */
0093   set value(value: T) {
0094     if (this.validator && !this.validator(value)) {
0095       console.error('Validation failed for:', value);
0096       return;
0097     }
0098     this.storage.setItem(this.key, typeof value !== 'string' ? JSON.stringify(value) : value);
0099 
0100     if(this.saveCallback) {
0101       this.saveCallback();
0102     }
0103 
0104     this.subject.next(value);
0105   }
0106 
0107   /**
0108    * Gets the current value of the property.
0109    *
0110    * @returns {T} The current value of the property.
0111    */
0112   get value(): T {
0113     return this.subject.value;
0114   }
0115 }