Files
xSaherelmWorkspace/Documents/GeneratedContext/xDashboard-xFrameworkServicesHolder-20260809_235622.txt
T
2026-08-11 22:10:12 +03:30

8257 lines
193 KiB
Plaintext

### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\crypto-js.d.ts
// Type definitions for crypto-js v4.0.0
// Project: https://github.com/brix/crypto-js
// Definitions by: Michael Zabka <https://github.com/misak113>
// Max Lysenko <https://github.com/maximlysenko>
// Brendan Early <https://github.com/mymindstorm>
// Doma <https://github.com/SevenOutman>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
type WordArray = CryptoJS.lib.WordArray;
type CipherParams = CryptoJS.lib.CipherParams;
type X64Word = CryptoJS.x64.Word;
/**
* Encoding strategy.
*/
interface Encoder {
/**
* Converts a word array to a hex string.
*
* @param wordArray The word array.
*
* @return The hex string.
*
* @example
*
* var hexString = CryptoJS.enc.Hex.stringify(wordArray);
*/
stringify(wordArray: WordArray): string;
/**
* Converts a hex string to a word array.
*
* @param hexStr The hex string.
*
* @return The word array.
*
* @example
*
* var wordArray = CryptoJS.enc.Hex.parse(hexString);
*/
parse(str: string): WordArray;
}
/**
* Abstract buffered block algorithm template.
*
* The property blockSize must be implemented in a concrete subtype.
*/
interface BufferedBlockAlgorithm {
/**
* The number of blocks that should be kept unprocessed in the buffer. Default: 0
*/
_minBufferSize: number;
/**
* Resets this block algorithm's data buffer to its initial state.
*
* @example
*
* bufferedBlockAlgorithm.reset();
*/
reset(): void;
/**
* Adds new data to this block algorithm's buffer.
*
* @param data The data to append. Strings are converted to a WordArray using UTF-8.
*
* @example
*
* bufferedBlockAlgorithm._append('data');
* bufferedBlockAlgorithm._append(wordArray);
*/
_append(data: WordArray | string): void;
/**
* Processes available data blocks.
*
* This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
*
* @param doFlush Whether all blocks and partial blocks should be processed.
*
* @return The processed data.
*
* @example
*
* var processedData = bufferedBlockAlgorithm._process();
* var processedData = bufferedBlockAlgorithm._process(!!'flush');
*/
_process(doFlush?: boolean): WordArray;
/**
* Creates a copy of this object.
*
* @return The clone.
*
* @example
*
* var clone = bufferedBlockAlgorithm.clone();
*/
clone(): BufferedBlockAlgorithm;
}
/**
* Abstract hasher template.
*/
interface Hasher {
/**
* The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
*/
blockSize: number;
/**
* Resets this hasher to its initial state.
*
* @example
*
* hasher.reset();
*/
reset(): void;
/**
* Updates this hasher with a message.
*
* @param messageUpdate The message to append.
*
* @return This hasher.
*
* @example
*
* hasher.update('message');
* hasher.update(wordArray);
*/
update(messageUpdate: WordArray | string): this;
/**
* Finalizes the hash computation.
* Note that the finalize operation is effectively a destructive, read-once operation.
*
* @param messageUpdate (Optional) A final message update.
*
* @return The hash.
*
* @example
*
* var hash = hasher.finalize();
* var hash = hasher.finalize('message');
* var hash = hasher.finalize(wordArray);
*/
finalize(messaegUpdate?: WordArray | string): WordArray;
}
interface HasherStatic {
/**
* Initializes a newly created hasher.
*
* @param cfg (Optional) The configuration options to use for this hash computation.
*
* @example
*
* var hasher = CryptoJS.algo.SHA256.create();
*/
create(cfg?: object): Hasher;
}
interface HasherHelper {
(message: WordArray | string, cfg?: object): WordArray;
}
interface HmacHasherHelper {
(message: WordArray | string, key: WordArray | string): WordArray;
}
/**
* Abstract base cipher template.
*/
interface Cipher {
/**
* This cipher's key size. Default: 4 (128 bits)
*/
keySize: number;
/**
* This cipher's IV size. Default: 4 (128 bits)
*/
ivSize: number;
/**
* A constant representing encryption mode.
*/
readonly _ENC_XFORM_MODE: number;
/**
* A constant representing decryption mode.
*/
readonly _DEV_XFORM_MODE: number;
/**
* Resets this cipher to its initial state.
*
* @example
*
* cipher.reset();
*/
reset(): void;
/**
* Adds data to be encrypted or decrypted.
*
* @param dataUpdate The data to encrypt or decrypt.
*
* @return The data after processing.
*
* @example
*
* var encrypted = cipher.process('data');
* var encrypted = cipher.process(wordArray);
*/
process(dataUpdate: WordArray | string): WordArray;
/**
* Finalizes the encryption or decryption process.
* Note that the finalize operation is effectively a destructive, read-once operation.
*
* @param dataUpdate The final data to encrypt or decrypt.
*
* @return The data after final processing.
*
* @example
*
* var encrypted = cipher.finalize();
* var encrypted = cipher.finalize('data');
* var encrypted = cipher.finalize(wordArray);
*/
finalize(dataUpdate?: WordArray | string): WordArray;
}
interface CipherStatic {
/**
* Creates this cipher in encryption mode.
*
* @param key The key.
* @param cfg (Optional) The configuration options to use for this operation.
*
* @return A cipher instance.
*
* @example
*
* var cipher = CryptoJS.algo.AES.createEncryptor(keyWordArray, { iv: ivWordArray });
*/
createEncryptor(key: WordArray, cfg?: CipherOption): Cipher;
/**
* Creates this cipher in decryption mode.
*
* @param key The key.
* @param cfg (Optional) The configuration options to use for this operation.
*
* @return A cipher instance.
*
* @example
*
* var cipher = CryptoJS.algo.AES.createDecryptor(keyWordArray, { iv: ivWordArray });
*/
createDecryptor(key: WordArray, cfg?: CipherOption): Cipher;
/**
* Initializes a newly created cipher.
*
* @param xformMode Either the encryption or decryption transormation mode constant.
* @param key The key.
* @param cfg (Optional) The configuration options to use for this operation.
*
* @example
*
* var cipher = CryptoJS.algo.AES.create(CryptoJS.algo.AES._ENC_XFORM_MODE, keyWordArray, { iv: ivWordArray });
*/
create(xformMode: number, key: WordArray, cfg?: CipherOption): Cipher;
}
interface CipherHelper {
encrypt(
message: WordArray | string,
key: WordArray | string,
cfg?: CipherOption
): CipherParams;
decrypt(
ciphertext: CipherParams | string,
key: WordArray | string,
cfg?: CipherOption
): WordArray;
}
/**
* Configuration options.
*/
interface CipherOption {
/**
* The IV to use for this operation.
*/
iv?: WordArray | undefined;
format?: Format | undefined;
[key: string]: any;
}
interface Mode {
/**
* Processes the data block at offset.
*
* @param words The data words to operate on.
* @param offset The offset where the block starts.
*
* @example
*
* mode.processBlock(data.words, offset);
*/
processBlock(words: number[], offset: number): void;
}
interface ModeStatic {
/**
* Initializes a newly created mode.
*
* @param cipher A block cipher instance.
* @param iv The IV words.
*
* @example
*
* var mode = CryptoJS.mode.CBC.Encryptor.create(cipher, iv.words);
*/
create(cipher: Cipher, iv: number[]): Mode;
}
/**
* Abstract base block cipher mode template.
*/
interface BlockCipherMode {
Encryptor: ModeStatic;
Decryptor: ModeStatic;
/**
* Creates this mode for encryption.
*
* @param cipher A block cipher instance.
* @param iv The IV words.
*
* @example
*
* var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);
*/
createEncryptor(cipher: Cipher, iv: number[]): Mode;
/**
* Creates this mode for decryption.
*
* @param cipher A block cipher instance.
* @param iv The IV words.
*
* @example
*
* var mode = CryptoJS.mode.CBC.createDecryptor(cipher, iv.words);
*/
createDecryptor(cipher: Cipher, iv: number[]): Mode;
}
/**
* Abstract base block cipher mode template.
*/
interface BlockCipherMode {
/**
* Creates this mode for encryption.
*
* @param cipher A block cipher instance.
* @param iv The IV words.
*
* @example
*
* var mode = CryptoJS.mode.CBC.createEncryptor(cipher, iv.words);
*/
createEncryptor(cipher: Cipher): Mode;
}
/**
* Padding strategy.
*/
interface Padding {
/**
* Pads data using the algorithm defined in PKCS #5/7.
*
* @param data The data to pad.
* @param blockSize The multiple that the data should be padded to.
*
* @example
*
* CryptoJS.pad.Pkcs7.pad(wordArray, 4);
*/
pad(data: WordArray, blockSize: number): void;
/**
* Unpads data that had been padded using the algorithm defined in PKCS #5/7.
*
* @param data The data to unpad.
*
* @example
*
* CryptoJS.pad.Pkcs7.unpad(wordArray);
*/
unpad(data: WordArray): void;
}
/**
* Abstract base block cipher template.
*/
interface BlockCipher {
/**
* The number of 32-bit words this cipher operates on. Default: 4 (128 bits)
*/
blockSize: number;
}
/**
* Configuration options.
*/
interface BlockCipherOption {
/**
* The block mode to use. Default: CBC
*/
mode: Mode;
/**
* The padding strategy to use. Default: Pkcs7
*/
padding: Padding;
}
/**
* Formatting strategy.
*/
interface Format {
/**
* Converts a cipher params object to an OpenSSL-compatible string.
*
* @param cipherParams The cipher params object.
*
* @return The OpenSSL-compatible string.
*
* @example
*
* var openSSLString = CryptoJS.format.OpenSSL.stringify(cipherParams);
*/
stringify(cipherParams: CipherParams): string;
/**
* Converts an OpenSSL-compatible string to a cipher params object.
*
* @param openSSLStr The OpenSSL-compatible string.
*
* @return The cipher params object.
*
* @example
*
* var cipherParams = CryptoJS.format.OpenSSL.parse(openSSLString);
*/
parse(str: string): CipherParams;
}
/**
* An array of 64-bit words.
*/
interface X64WordArray {
/**
* The array of CryptoJS.x64.Word objects.
*/
words: number[];
/**
* The number of significant bytes in this word array.
*/
sigBytes: number;
/**
* Converts this 64-bit word array to a 32-bit word array.
*
* @return This word array's data as a 32-bit word array.
*
* @example
*
* var x32WordArray = x64WordArray.toX32();
*/
toX32(): WordArray;
/**
* Creates a copy of this word array.
*
* @return The clone.
*
* @example
*
* var clone = x64WordArray.clone();
*/
clone(): X64WordArray;
}
/**
* Base object for prototypal inheritance.
*/
interface Base {
/**
* Creates a copy of this object.
*
* @return The clone.
*
* @example
*
* var clone = instance.clone();
*/
clone(): this;
}
/**
* Configuration options.
*/
interface KDFOption {
/**
* The key size in words to generate.
*/
keySize?: number | undefined;
/**
* The hasher to use.
*/
hasher?: HasherStatic | undefined;
/**
* The number of iterations to perform.
*/
iterations?: number | undefined;
}
declare namespace CryptoJS {
/**
* Library namespace.
*/
export namespace lib {
/**
* Base object for prototypal inheritance.
*/
const Base: {
/**
* Creates a new object that inherits from this object.
*
* @param overrides Properties to copy into the new object.
*
* @return The new object.
*
* @example
*
* var MyType = CryptoJS.lib.Base.extend({
* field: 'value',
*
* method: function () {
* }
* });
*/
extend(overrides: object): any;
/**
* Extends this object and runs the init method.
* Arguments to create() will be passed to init().
*
* @return The new object.
*
* @example
*
* var instance = MyType.create();
*/
create(...args: any[]): any;
/**
* Copies properties into this object.
*
* @param properties The properties to mix in.
*
* @example
*
* MyType.mixIn({
* field: 'value'
* });
*/
mixIn(properties: object): any;
};
/**
* An array of 32-bit words.
*/
interface WordArray {
/**
* The array of 32-bit words.
*/
words: number[];
/**
* The number of significant bytes in this word array.
*/
sigBytes: number;
/**
* Converts this word array to a string.
*
* @param encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
*
* @return The stringified word array.
*
* @example
*
* var string = wordArray + '';
* var string = wordArray.toString();
* var string = wordArray.toString(CryptoJS.enc.Utf8);
*/
toString(encoder?: Encoder): string;
/**
* Concatenates a word array to this word array.
*
* @param wordArray The word array to append.
*
* @return This word array.
*
* @example
*
* wordArray1.concat(wordArray2);
*/
concat(wordArray: WordArray): this;
/**
* Removes insignificant bits.
*
* @example
*
* wordArray.clamp();
*/
clamp(): void;
/**
* Creates a copy of this word array.
*
* @return The clone.
*
* @example
*
* var clone = wordArray.clone();
*/
clone(): WordArray;
}
const WordArray: {
/**
* Initializes a newly created word array.
*
* @param words (Optional) An array of 32-bit words.
* @param sigBytes (Optional) The number of significant bytes in the words.
*
* @example
*
* var wordArray = CryptoJS.lib.WordArray.create();
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
* var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
*/
create(words?: number[], sigBytes?: number): WordArray;
/**
* Creates a word array filled with random bytes.
*
* @param nBytes The number of random bytes to generate.
*
* @return The random word array.
*
* @example
*
* var wordArray = CryptoJS.lib.WordArray.random(16);
*/
random(nBytes: number): WordArray;
};
const BufferedBlockAlgorithm: any;
const Hasher: {
/**
* Creates a shortcut function to a hasher's object interface.
*
* @param hasher The hasher to create a helper for.
*
* @return The shortcut function.
*
* @example
*
* var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
*/
_createHelper(hasher: HasherStatic): HasherHelper;
/**
* Creates a shortcut function to the HMAC's object interface.
*
* @param hasher The hasher to use in this HMAC helper.
*
* @return The shortcut function.
*
* @example
*
* var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
*/
_createHmacHelper(hasher: HasherStatic): HmacHasherHelper;
};
const Cipher: {
/**
* Creates shortcut functions to a cipher's object interface.
*
* @param cipher The cipher to create a helper for.
*
* @return An object with encrypt and decrypt shortcut functions.
*
* @example
*
* var AES = CryptoJS.lib.Cipher._createHelper(CryptoJS.algo.AES);
*/
_createHelper(cipher: Cipher): CipherHelper;
};
interface CipherOption {
/**
* The IV to use for this operation.
*/
iv?: WordArray | undefined;
format?: Format | undefined;
[key: string]: any;
}
/**
* A collection of cipher parameters.
*/
interface CipherParams {
/**
* The raw ciphertext.
*/
ciphertext: WordArray;
/**
* The key to this ciphertext.
*/
key: WordArray;
/**
* The IV used in the ciphering operation.
*/
iv: WordArray;
/**
* The salt used with a key derivation function.
*/
salt: WordArray;
/**
* The cipher algorithm.
*/
algorithm: CipherStatic;
/**
* The block mode used in the ciphering operation.
*/
mode: Mode;
/**
* The padding scheme used in the ciphering operation.
*/
padding: Padding;
/**
* The block size of the cipher.
*/
blockSize: number;
/**
* The default formatting strategy to convert this cipher params object to a string.
*/
formatter: Format;
/**
* Converts this cipher params object to a string.
*
* @param formatter (Optional) The formatting strategy to use.
*
* @return The stringified cipher params.
*
* @throws Error If neither the formatter nor the default formatter is set.
*
* @example
*
* var string = cipherParams + '';
* var string = cipherParams.toString();
* var string = cipherParams.toString(CryptoJS.format.OpenSSL);
*/
toString(formatter?: Format): string;
}
const CipherParams: {
/**
* Initializes a newly created cipher params object.
*
* @param cipherParams An object with any of the possible cipher parameters.
*
* @example
*
* var cipherParams = CryptoJS.lib.CipherParams.create({
* ciphertext: ciphertextWordArray,
* key: keyWordArray,
* iv: ivWordArray,
* salt: saltWordArray,
* algorithm: CryptoJS.algo.AES,
* mode: CryptoJS.mode.CBC,
* padding: CryptoJS.pad.PKCS7,
* blockSize: 4,
* formatter: CryptoJS.format.OpenSSL
* });
*/
create(cipherParams: Partial<CipherParams>): CipherParams;
};
/**
* Abstract base stream cipher template.
*/
interface StreamCipher extends Cipher {
/**
* The number of 32-bit words this cipher operates on. Default: 1 (32 bits)
*/
blockSize: number;
}
/**
* Abstract base block cipher mode template.
*/
const BlockCipherMode: any;
/**
* A cipher wrapper that returns ciphertext as a serializable cipher params object.
*/
const SerializableCipher: {
/**
* Encrypts a message.
*
* @param cipher The cipher algorithm to use.
* @param message The message to encrypt.
* @param key The key.
* @param cfg (Optional) The configuration options to use for this operation.
*
* @return A cipher params object.
*
* @example
*
* var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key);
* var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv });
* var ciphertextParams = CryptoJS.lib.SerializableCipher.encrypt(CryptoJS.algo.AES, message, key, { iv: iv, format: CryptoJS.format.OpenSSL });
*/
encrypt(
cipher: CipherStatic,
message: WordArray | string,
key: WordArray,
cfg?: CipherOption
): CipherParams;
/**
* Decrypts serialized ciphertext.
*
* @param cipher The cipher algorithm to use.
* @param ciphertext The ciphertext to decrypt.
* @param key The key.
* @param cfg (Optional) The configuration options to use for this operation.
*
* @return The plaintext.
*
* @example
*
* var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, key, { iv: iv, format: CryptoJS.format.OpenSSL });
* var plaintext = CryptoJS.lib.SerializableCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, key, { iv: iv, format: CryptoJS.format.OpenSSL });
*/
decrypt(
cipher: CipherStatic,
ciphertext: WordArray | string,
key: WordArray,
cfg?: CipherOption
): CipherParams;
/**
* Converts serialized ciphertext to CipherParams,
* else assumed CipherParams already and returns ciphertext unchanged.
*
* @param ciphertext The ciphertext.
* @param format The formatting strategy to use to parse serialized ciphertext.
*
* @return The unserialized ciphertext.
*
* @example
*
* var ciphertextParams = CryptoJS.lib.SerializableCipher._parse(ciphertextStringOrParams, format);
*/
_parse(ciphertext: CipherParams | string, format: Format): CipherParams;
};
/**
* A serializable cipher wrapper that derives the key from a password,
* and returns ciphertext as a serializable cipher params object.
*/
const PasswordBasedCipher: {
/**
* Encrypts a message using a password.
*
* @param cipher The cipher algorithm to use.
* @param message The message to encrypt.
* @param password The password.
* @param cfg (Optional) The configuration options to use for this operation.
*
* @return A cipher params object.
*
* @example
*
* var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password');
* var ciphertextParams = CryptoJS.lib.PasswordBasedCipher.encrypt(CryptoJS.algo.AES, message, 'password', { format: CryptoJS.format.OpenSSL });
*/
encrypt(
cipher: CipherStatic,
message: WordArray | string,
password: string,
cfg?: CipherOption
): CipherParams;
/**
* Decrypts serialized ciphertext using a password.
*
* @param cipher The cipher algorithm to use.
* @param ciphertext The ciphertext to decrypt.
* @param password The password.
* @param cfg (Optional) The configuration options to use for this operation.
*
* @return The plaintext.
*
* @example
*
* var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, formattedCiphertext, 'password', { format: CryptoJS.format.OpenSSL });
* var plaintext = CryptoJS.lib.PasswordBasedCipher.decrypt(CryptoJS.algo.AES, ciphertextParams, 'password', { format: CryptoJS.format.OpenSSL });
*/
decrypt(
cipher: CipherStatic,
ciphertext: CipherParams | string,
password: string,
cfg?: CipherOption
): WordArray;
};
}
/**
* Padding namespace.
*/
export namespace pad {
/**
* PKCS #5/7 padding strategy.
*/
const Pkcs7: Padding;
/**
* ANSI X.923 padding strategy.
*/
const AnsiX923: Padding;
/**
* ISO 10126 padding strategy.
*/
const Iso10126: Padding;
/**
* ISO/IEC 9797-1 Padding Method 2.
*/
const Iso97971: Padding;
/**
* Zero padding strategy.
*/
const ZeroPadding: Padding;
/**
* A noop padding strategy.
*/
const NoPadding: Padding;
}
/**
* Key derivation function namespace.
*/
export namespace kdf {
/**
* OpenSSL key derivation function.
*/
const OpenSSL: {
/**
* Derives a key and IV from a password.
*
* @param password The password to derive from.
* @param keySize The size in words of the key to generate.
* @param ivSize The size in words of the IV to generate.
* @param salt (Optional) A 64-bit salt to use. If omitted, a salt will be generated randomly.
*
* @return A cipher params object with the key, IV, and salt.
*
* @example
*
* var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32);
* var derivedParams = CryptoJS.kdf.OpenSSL.execute('Password', 256/32, 128/32, 'saltsalt');
*/
execute(
password: string,
keySize: number,
ivSize: number,
salt?: WordArray | string
): CipherParams;
};
}
/**
* Mode namespace.
*/
export namespace mode {
/**
* Cipher Block Chaining mode.
*/
const CBC: BlockCipherMode;
/**
* Cipher Feedback block mode.
*/
const CFB: BlockCipherMode;
/**
* Counter block mode.
*/
const CTR: BlockCipherMode;
/**
* @preserve
* Counter block mode compatible with Dr Brian Gladman fileenc.c
* derived from CryptoJS.mode.CTR
* Jan Hruby jhruby.web@gmail.com
*/
const CTRGladman: BlockCipherMode;
/**
* Output Feedback block mode.
*/
const OFB: BlockCipherMode;
/**
* Electronic Codebook block mode.
*/
const ECB: BlockCipherMode;
}
/**
* Format namespace.
*/
export namespace format {
/**
* OpenSSL formatting strategy.
*/
const OpenSSL: Format;
const Hex: Format;
}
/**
* Encoder namespace.
*/
export namespace enc {
/**
* Hex encoding strategy.
*/
const Hex: Encoder;
/**
* Latin1 encoding strategy.
*/
const Latin1: Encoder;
/**
* UTF-8 encoding strategy.
*/
const Utf8: Encoder;
/**
* UTF-16 BE encoding strategy.
*/
const Utf16: Encoder;
const Utf16BE: Encoder;
/**
* UTF-16 LE encoding strategy.
*/
const Utf16LE: Encoder;
/**
* Base64 encoding strategy.
*/
const Base64: Encoder;
}
/**
* Algorithm namespace.
*/
export namespace algo {
/**
* MD5 hash algorithm.
*/
const MD5: HasherStatic;
/**
* SHA-1 hash algorithm.
*/
const SHA1: HasherStatic;
/**
* SHA-256 hash algorithm.
*/
const SHA256: HasherStatic;
/**
* SHA-224 hash algorithm.
*/
const SHA224: HasherStatic;
/**
* SHA-512 hash algorithm.
*/
const SHA512: HasherStatic;
/**
* SHA-384 hash algorithm.
*/
const SHA384: HasherStatic;
/**
* SHA-3 hash algorithm.
*/
const SHA3: HasherStatic;
/**
* RIPEMD160 hash algorithm.
*/
const RIPEMD160: HasherStatic;
/**
* HMAC algorithm.
*/
abstract class HMAC {
/**
* Initializes a newly created HMAC.
*
* @param hasher The hash algorithm to use.
* @param key The secret key.
*
* @example
*
* var hmacHasher = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
*/
static create(hasher: HasherStatic, key: WordArray | string): HMAC;
/**
* Resets this HMAC to its initial state.
*
* @example
*
* hmacHasher.reset();
*/
reset(): void;
/**
* Updates this HMAC with a message.
*
* @param messageUpdate The message to append.
*
* @return This HMAC instance.
*
* @example
*
* hmacHasher.update('message');
* hmacHasher.update(wordArray);
*/
update(messageUpdate: WordArray | string): this;
/**
* Finalizes the HMAC computation.
* Note that the finalize operation is effectively a destructive, read-once operation.
*
* @param messageUpdate (Optional) A final message update.
*
* @return The HMAC.
*
* @example
*
* var hmac = hmacHasher.finalize();
* var hmac = hmacHasher.finalize('message');
* var hmac = hmacHasher.finalize(wordArray);
*/
finalize(messageUpdate?: WordArray | string): WordArray;
}
/**
* Password-Based Key Derivation Function 2 algorithm.
*/
abstract class PBKDF2 {
/**
* Initializes a newly created key derivation function.
*
* @param cfg (Optional) The configuration options to use for the derivation.
*
* @example
*
* var kdf = CryptoJS.algo.PBKDF2.create();
* var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8 });
* var kdf = CryptoJS.algo.PBKDF2.create({ keySize: 8, iterations: 1000 });
*/
static create(cfg?: KDFOption): PBKDF2;
/**
* Computes the Password-Based Key Derivation Function 2.
*
* @param password The password.
* @param salt A salt.
*
* @return The derived key.
*
* @example
*
* var key = kdf.compute(password, salt);
*/
compute(password: WordArray | string, salt: WordArray): WordArray;
}
/**
* This key derivation function is meant to conform with EVP_BytesToKey.
* www.openssl.org/docs/crypto/EVP_BytesToKey.html
*/
abstract class EvpKDF {
/**
* Initializes a newly created key derivation function.
*
* @param cfg (Optional) The configuration options to use for the derivation.
*
* @example
*
* var kdf = CryptoJS.algo.EvpKDF.create();
* var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8 });
* var kdf = CryptoJS.algo.EvpKDF.create({ keySize: 8, iterations: 1000 });
*/
static create(cfg?: {
keySize: number;
hasher?: HasherStatic | undefined;
iterations: number;
}): EvpKDF;
/**
* Derives a key from a password.
*
* @param password The password.
* @param salt A salt.
*
* @return The derived key.
*
* @example
*
* var key = kdf.compute(password, salt);
*/
compute(password: WordArray | string, salt: WordArray): WordArray;
}
/**
* AES block cipher algorithm.
*/
const AES: CipherStatic;
/**
* DES block cipher algorithm.
*/
const DES: CipherStatic;
/**
* Triple-DES block cipher algorithm.
*/
const TripleDES: CipherStatic;
/**
* RC4 stream cipher algorithm.
*/
const RC4: CipherStatic;
/**
* Modified RC4 stream cipher algorithm.
*/
const RC4Drop: CipherStatic;
/**
* Rabbit stream cipher algorithm
*/
const Rabbit: CipherStatic;
/**
* Rabbit stream cipher algorithm.
*
* This is a legacy version that neglected to convert the key to little-endian.
* This error doesn't affect the cipher's security,
* but it does affect its compatibility with other implementations.
*/
const RabbitLegacy: CipherStatic;
}
/**
* x64 namespace.
*/
export namespace x64 {
/**
* A 64-bit word.
*/
interface Word {
/**
* Bitwise NOTs this word.
*
* @return A new x64-Word object after negating.
*
* @example
*
* var negated = x64Word.not();
*/
not(): X64Word;
/**
* Bitwise ANDs this word with the passed word.
*
* @param word The x64-Word to AND with this word.
*
* @return A new x64-Word object after ANDing.
*
* @example
*
* var anded = x64Word.and(anotherX64Word);
*/
and(word: X64Word): X64Word;
/**
* Bitwise ORs this word with the passed word.
*
* @param word The x64-Word to OR with this word.
*
* @return A new x64-Word object after ORing.
*
* @example
*
* var ored = x64Word.or(anotherX64Word);
*/
or(word: X64Word): X64Word;
/**
* Bitwise XORs this word with the passed word.
*
* @param word The x64-Word to XOR with this word.
*
* @return A new x64-Word object after XORing.
*
* @example
*
* var xored = x64Word.xor(anotherX64Word);
*/
xor(word: X64Word): X64Word;
/**
* Shifts this word n bits to the left.
*
* @param n The number of bits to shift.
*
* @return A new x64-Word object after shifting.
*
* @example
*
* var shifted = x64Word.shiftL(25);
*/
shiftL(n: number): X64Word;
/**
* Shifts this word n bits to the right.
*
* @param n The number of bits to shift.
*
* @return A new x64-Word object after shifting.
*
* @example
*
* var shifted = x64Word.shiftR(7);
*/
shiftR(n: number): X64Word;
/**
* Rotates this word n bits to the left.
*
* @param n The number of bits to rotate.
*
* @return A new x64-Word object after rotating.
*
* @example
*
* var rotated = x64Word.rotL(25);
*/
rotL(n: number): X64Word;
/**
* Rotates this word n bits to the right.
*
* @param n The number of bits to rotate.
*
* @return A new x64-Word object after rotating.
*
* @example
*
* var rotated = x64Word.rotR(7);
*/
rotR(n: number): X64Word;
/**
* Adds this word with the passed word.
*
* @param word The x64-Word to add with this word.
*
* @return A new x64-Word object after adding.
*
* @example
*
* var added = x64Word.add(anotherX64Word);
*/
add(word: X64Word): X64Word;
}
const Word: {
/**
* Initializes a newly created 64-bit word.
*
* @param high The high 32 bits.
* @param low The low 32 bits.
*
* @example
*
* var x64Word = CryptoJS.x64.Word.create(0x00010203, 0x04050607);
*/
create(high: number, low: number): X64Word;
};
/**
* Initializes a newly created word array.
*
* @param words (Optional) An array of CryptoJS.x64.Word objects.
* @param sigBytes (Optional) The number of significant bytes in the words.
*
* @example
*
* var wordArray = CryptoJS.x64.WordArray.create();
*
* var wordArray = CryptoJS.x64.WordArray.create([
* CryptoJS.x64.Word.create(0x00010203, 0x04050607),
* CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f)
* ]);
*
* var wordArray = CryptoJS.x64.WordArray.create([
* CryptoJS.x64.Word.create(0x00010203, 0x04050607),
* CryptoJS.x64.Word.create(0x18191a1b, 0x1c1d1e1f)
* ], 10);
*/
const WordArray: {
create(words?: X64WordArray[], sigBytes?: number): X64WordArray;
};
}
/**
* Shortcut function to the hasher's object interface.
*
* @param message The message to hash.
*
* @return The hash.
*
* @example
*
* var hash = CryptoJS.MD5('message');
* var hash = CryptoJS.MD5(wordArray);
*/
export const MD5: HasherHelper;
/**
* Shortcut function to the HMAC's object interface.
*
* @param message The message to hash.
* @param key The secret key.
*
* @return The HMA'C.
*
* @example
*
* var hmac = CryptoJS.HmacMD5(message, key);
*/
export const HmacMD5: HmacHasherHelper;
/**
* Shortcut function to the hasher's object interface.
*
* @param message The message to hash.
*
* @return The hash.
*
* @example
*
* var hash = CryptoJS.SHA1('message');
* var hash = CryptoJS.SHA1(wordArray);
*/
export const SHA1: HasherHelper;
/**
* Shortcut function to the HMAC's object interface.
*
* @param message The message to hash.
* @param key The secret key.
*
* @return The HMAC.
*
* @example
*
* var hmac = CryptoJS.HmacSHA1(message, key);
*/
export const HmacSHA1: HmacHasherHelper;
/**
* Shortcut function to the hasher's object interface.
*
* @param message The message to hash.
*
* @return The hash.
*
* @example
*
* var hash = CryptoJS.SHA256('message');
* var hash = CryptoJS.SHA256(wordArray);
*/
export const SHA256: HasherHelper;
/**
* Shortcut function to the HMAC's object interface.
*
* @param message The message to hash.
* @param key The secret key.
*
* @return The HMAC.
*
* @example
*
* var hmac = CryptoJS.HmacSHA256(message, key);
*/
export const HmacSHA256: HmacHasherHelper;
/**
* Shortcut function to the hasher's object interface.
*
* @param message The message to hash.
*
* @return The hash.
*
* @example
*
* var hash = CryptoJS.SHA224('message');
* var hash = CryptoJS.SHA224(wordArray);
*/
export const SHA224: HasherHelper;
/**
* Shortcut function to the HMAC's object interface.
*
* @param message The message to hash.
* @param key The secret key.
*
* @return The HMAC.
*
* @example
*
* var hmac = CryptoJS.HmacSHA224(message, key);
*/
export const HmacSHA224: HmacHasherHelper;
/**
* Shortcut function to the hasher's object interface.
*
* @param message The message to hash.
*
* @return The hash.
*
* @example
*
* var hash = CryptoJS.SHA512('message');
* var hash = CryptoJS.SHA512(wordArray);
*/
export const SHA512: HasherHelper;
/**
* Shortcut function to the HMAC's object interface.
*
* @param message The message to hash.
* @param key The secret key.
*
* @return The HMAC.
*
* @example
*
* var hmac = CryptoJS.HmacSHA512(message, key);
*/
export const HmacSHA512: HmacHasherHelper;
/**
* Shortcut function to the hasher's object interface.
*
* @param message The message to hash.
*
* @return The hash.
*
* @example
*
* var hash = CryptoJS.SHA384('message');
* var hash = CryptoJS.SHA384(wordArray);
*/
export const SHA384: HasherHelper;
/**
* Shortcut function to the HMAC's object interface.
*
* @param message The message to hash.
* @param key The secret key.
*
* @return The HMAC.
*
* @example
*
* var hmac = CryptoJS.HmacSHA384(message, key);
*/
export const HmacSHA384: HmacHasherHelper;
/**
* Shortcut function to the hasher's object interface.
*
* @param message The message to hash.
*
* @return The hash.
*
* @example
*
* var hash = CryptoJS.SHA3('message');
* var hash = CryptoJS.SHA3(wordArray);
*/
export const SHA3: HasherHelper;
/**
* Shortcut function to the HMAC's object interface.
*
* @param message The message to hash.
* @param key The secret key.
*
* @return The HMAC.
*
* @example
*
* var hmac = CryptoJS.HmacSHA3(message, key);
*/
export const HmacSHA3: HmacHasherHelper;
/**
* Shortcut function to the hasher's object interface.
*
* @param message The message to hash.
*
* @return The hash.
*
* @example
*
* var hash = CryptoJS.RIPEMD160('message');
* var hash = CryptoJS.RIPEMD160(wordArray);
*/
export const RIPEMD160: HasherHelper;
/**
* Shortcut function to the HMAC's object interface.
*
* @param message The message to hash.
* @param key The secret key.
*
* @return The HMAC.
*
* @example
*
* var hmac = CryptoJS.HmacRIPEMD160(message, key);
*/
export const HmacRIPEMD160: HmacHasherHelper;
/**
* Computes the Password-Based Key Derivation Function 2.
*
* @param password The password.
* @param salt A salt.
* @param cfg (Optional) The configuration options to use for this computation.
*
* @return The derived key.
*
* @example
*
* var key = CryptoJS.PBKDF2(password, salt);
* var key = CryptoJS.PBKDF2(password, salt, { keySize: 8 });
* var key = CryptoJS.PBKDF2(password, salt, { keySize: 8, iterations: 1000 });
*/
export function PBKDF2(
password: WordArray | string,
salt: WordArray | string,
cfg?: KDFOption
): WordArray;
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.AES.encrypt(message, key, cfg);
* var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg);
*/
export const AES: CipherHelper;
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.DES.encrypt(message, key, cfg);
* var plaintext = CryptoJS.DES.decrypt(ciphertext, key, cfg);
*/
export const DES: CipherHelper;
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.TripleDES.encrypt(message, key, cfg);
* var plaintext = CryptoJS.TripleDES.decrypt(ciphertext, key, cfg);
*/
export const TripleDES: CipherHelper;
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.RC4.encrypt(message, key, cfg);
* var plaintext = CryptoJS.RC4.decrypt(ciphertext, key, cfg);
*/
export const RC4: CipherHelper;
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.RC4Drop.encrypt(message, key, cfg);
* var plaintext = CryptoJS.RC4Drop.decrypt(ciphertext, key, cfg);
*/
export const RC4Drop: CipherHelper;
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.Rabbit.encrypt(message, key, cfg);
* var plaintext = CryptoJS.Rabbit.decrypt(ciphertext, key, cfg);
*/
export const Rabbit: CipherHelper;
/**
* Shortcut functions to the cipher's object interface.
*
* @example
*
* var ciphertext = CryptoJS.RabbitLegacy.encrypt(message, key, cfg);
* var plaintext = CryptoJS.RabbitLegacy.decrypt(ciphertext, key, cfg);
*/
export const RabbitLegacy: CipherHelper;
/**
* Derives a key from a password.
*
* @param password The password.
* @param salt A salt.
* @param cfg (Optional) The configuration options to use for this computation.
*
* @return The derived key.
*
* @example
*
* var key = CryptoJS.EvpKDF(password, salt);
* var key = CryptoJS.EvpKDF(password, salt, { keySize: 8 });
* var key = CryptoJS.EvpKDF(password, salt, { keySize: 8, iterations: 1000 });
*/
export function EvpKDF(
password: WordArray | string,
salt: WordArray | string,
cfg?: {
keySize: number;
hasher?: HasherStatic | undefined;
iterations: number;
}
): WordArray;
}
export = CryptoJS;
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\public-api.ts
/*
* Public API Surface of x-framework-services
*/
//
//#region Export Services ...
export * from './lib/x-dialog.service';
export * from './lib/x-manager.service';
export * from './lib/x-storage.service';
export * from './lib/x-security.service';
export * from './lib/x-settings.service';
export * from './lib/x-identifier.service';
export * from './lib/x-geolocation.service';
export * from './lib/x-localization.service';
export * from './lib/x-notification.service';
export * from './lib/x-task-manager.service';
export * from './lib/x-theme-manager.service';
export * from './lib/x-secure-storage.service';
export * from './lib/x-http-interceptor.service';
//#endregion
//
//#region Export Directives ...
export * from './lib/directives/x-swipable.directive';
export * from './lib/directives/x-date-presenter.directive';
export * from './lib/directives/x-currency-formatter.directive';
export * from './lib/directives/x-from-input-formatter.directive';
export * from './lib/directives/x-locale-input-formatter.directive';
//#endregion
//
//#region Export Pipes ...
export * from './lib/pipes/x-translate.pipe';
//#endregion
//
//#region Tokens ...
export * from './lib/tokens/x-injectable-tokens';
//#endregion
//
//#region Export Config ...
export * from './lib/config/x-framework-services.config';
//#endregion
//
//#region Export Modules ...
export * from './lib/modules/x-directives.module';
export * from './lib/x-framework-services.module';
//#endregion
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\test.ts
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js';
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
declare const require: {
context(path: string, deep?: boolean, filter?: RegExp): {
keys(): string[];
<T>(id: string): T;
};
};
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-dialog.service.ts
import {
NavController,
AlertController,
ModalController,
PickerController,
PopoverController,
LoadingController,
ActionSheetController,
} from '@ionic/angular';
import {
toArray,
hasChild,
XActionType,
XModalInput,
XBaseService,
XResourceIDs,
XModalButton,
XPickerColumn,
XAlertOptions,
XModalOptions,
XPickerOptions,
XPopoverOptions,
XLoadingOptions,
XModalButtonRole,
XActionModalOptions,
XPickerColumnOption,
XModalButtonRoleIdentifier,
} from 'x-framework-core';
import { Observable, of } from 'rxjs';
import { Injectable, Inject } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { XLocalizationService } from './x-localization.service';
import { XNotificationService } from './x-notification.service';
import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens';
import { XFrameworkServicesConfig } from './config/x-framework-services.config';
@Injectable({
providedIn: 'root',
})
export class XDialogService extends XBaseService {
//
constructor(
@Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig,
public matDialogService: MatDialog,
public modalController: ModalController,
public alertController: AlertController,
public pickerController: PickerController,
public navigationController: NavController,
public popoverController: PopoverController,
public loadingController: LoadingController,
private notificationService: XNotificationService,
private localizationService: XLocalizationService,
public actionSheetController: ActionSheetController
) {
super(config);
}
//
//#region Service Actions ...
nativeAlert(message?: string | XResourceIDs): Observable<void> {
//
message = !message ? XResourceIDs.are_you_sure : message;
//
const mMessage = this.localizationService.getValue(message);
const confirmation = window.alert(mMessage);
//
return of(confirmation);
}
nativeConfirm(message?: string | XResourceIDs): Observable<boolean> {
//
message = !message ? XResourceIDs.are_you_sure : message;
//
const mMessage = this.localizationService.getValue(message);
const confirmation = window.confirm(mMessage);
//
return of(confirmation);
}
async presentActionModal(props: XActionModalOptions) {
//
const options = await this.toActionSheetOptions(props);
const actionModal = await this.actionSheetController.create(options);
//
if (props.playSound) {
this.notificationService.playSound(props.type || XActionType.System);
}
//
await actionModal.present();
return actionModal;
}
async presentModal(props: XModalOptions) {
//
if (props.fullScreen) {
//
const mFullscreen = 'fullscreen';
if (hasChild(props.cssClass)) {
props.cssClass = [...toArray(props.cssClass), mFullscreen];
} else {
props.cssClass = [mFullscreen];
}
} else if (props.autoHeight) {
//
const mAutoHeight = 'autoHeight';
if (hasChild(props.cssClass)) {
props.cssClass = [...toArray(props.cssClass), mAutoHeight];
} else {
props.cssClass = [mAutoHeight];
}
}
//
const modal = await this.modalController.create(props);
await modal.present();
return modal;
}
async presentPopover(props: XPopoverOptions) {
//
const popover = await this.popoverController.create(props);
await popover.present();
return popover;
}
async presentLoading(props: XLoadingOptions) {
//
const loading = await this.loadingController.create(props);
await loading.present();
return loading;
}
async presentAlert(props: XAlertOptions) {
//
const options = await this.prepareAlertOptions(props);
const alert = await this.alertController.create(options);
//
await alert.present();
return alert;
}
async presentPicker(props: XPickerOptions) {
//
const options = await this.preparePickerOptions(props);
const picker = await this.pickerController.create(options);
//
await picker.present();
return picker;
}
//#endregion
//
//#region Commonly Used dialogs ...
async presentAreYouSureOkCancleDialog(
okHandler: () => void,
okRole?: XModalButtonRoleIdentifier,
cancelHandler?: () => void,
cancelRole?: XModalButtonRoleIdentifier
) {
await this.presentActionModal({
header: XResourceIDs.are_you_sure,
buttons: [],
keyboardClose: true,
backdropDismiss: true,
hasOk: true,
okRole,
okHandler,
hasCancel: true,
cancelRole,
cancelHandler,
});
}
async presentAreYouSureYesNoDialog(
yesHandler: () => void,
yesRole?: XModalButtonRoleIdentifier,
noHandler?: () => void,
noRole?: XModalButtonRoleIdentifier
) {
await this.presentActionModal({
header: XResourceIDs.are_you_sure,
buttons: [],
keyboardClose: true,
backdropDismiss: true,
hasNo: true,
noRole,
noHandler,
hasYes: true,
yesRole,
yesHandler,
});
}
//#endregion
//
//#region Private ...
//
//#region Button Preparer ...
getButton(
text?: XResourceIDs | string,
icon?: string,
role?: XModalButtonRoleIdentifier,
handler?: () => boolean | void | Promise<boolean>
) {
//
if (!role) {
role = XModalButtonRole.Selected;
}
//
const mText = this.getPreparedMessage(text);
return {
text: mText,
icon,
role,
handler,
};
}
getYesButton(
role?: XModalButtonRoleIdentifier,
handler?: () => boolean | void | Promise<boolean>
) {
//
if (!role) {
role = XModalButtonRole.Selected;
}
//
const mText = this.getPreparedMessage(XResourceIDs.yes);
const mIcon = 'checkmark';
return {
text: mText,
icon: mIcon,
role,
handler,
};
}
getNoButton(
role?: XModalButtonRoleIdentifier,
handler?: () => boolean | void | Promise<boolean>
) {
//
if (!role) {
role = XModalButtonRole.Selected;
}
//
const mText = this.getPreparedMessage(XResourceIDs.no);
const mIcon = 'close';
return {
text: mText,
icon: mIcon,
role,
handler,
};
}
getOkButton(
role?: XModalButtonRoleIdentifier,
handler?: () => boolean | void | Promise<boolean>
) {
//
if (!role) {
role = XModalButtonRole.Selected;
}
//
const mText = this.getPreparedMessage(XResourceIDs.ok);
const mIcon = 'checkmark';
return {
text: mText,
icon: mIcon,
role,
handler,
};
}
getCancelButton(
role?: XModalButtonRoleIdentifier,
handler?: () => boolean | void | Promise<boolean>
) {
//
if (!role) {
role = XModalButtonRole.Selected;
}
//
const mText = this.getPreparedMessage(XResourceIDs.cancel);
const mIcon = 'close';
return {
text: mText,
icon: mIcon,
role,
handler,
};
}
getAcceptButton(
role?: XModalButtonRoleIdentifier,
handler?: () => boolean | void | Promise<boolean>
) {
//
if (!role) {
role = XModalButtonRole.Selected;
}
//
const mText = this.getPreparedMessage(XResourceIDs.accept);
const mIcon = 'checkmark';
return {
text: mText,
icon: mIcon,
role,
handler,
};
}
getRetryButton(
role?: XModalButtonRoleIdentifier,
handler?: () => boolean | void | Promise<boolean>
) {
//
if (!role) {
role = XModalButtonRole.Selected;
}
//
const mText = this.getPreparedMessage(XResourceIDs.retry);
const mIcon = 'refresh';
return {
text: mText,
icon: mIcon,
role,
handler,
};
}
getDismissButton(
role?: XModalButtonRoleIdentifier,
handler?: () => boolean | void | Promise<boolean>
) {
//
if (!role) {
role = XModalButtonRole.Destructive;
}
//
const mText = this.getPreparedMessage(XResourceIDs.dismiss);
const mIcon = 'remove-circle-outline';
return {
text: mText,
icon: mIcon,
role,
handler,
};
}
//#endregion
private prepareModalButton(button?: XModalButton) {
//
const alertButton = {
...button,
text: button.text ? this.getPreparedMessage(button.text) : '',
};
//
return alertButton;
}
private async prepareModalButtons(buttons?: XModalButton[]) {
//
if (!hasChild(buttons)) {
return [];
}
//
return buttons.map((b) => this.prepareModalButton(b));
}
private prepareModalInput(input?: XModalInput) {
//
const alertInput = {
...input,
label: input.label ? this.getPreparedMessage(input.label) : '',
placeholder: input.placeholder
? this.getPreparedMessage(input.placeholder)
: '',
};
//
return alertInput;
}
private async prepareModalInputs(inputs?: XModalInput[]) {
//
if (!hasChild(inputs)) {
return [];
}
//
return inputs.map((i) => this.prepareModalInput(i));
}
private async prepareAlertOptions(options?: XAlertOptions) {
//
const alertOptions = {
...options,
header: options.header ? this.getPreparedMessage(options.header) : '',
subHeader: options.subHeader
? this.getPreparedMessage(options.subHeader)
: '',
message: options.message ? this.getPreparedMessage(options.message) : '',
inputs: hasChild(options.inputs)
? await this.prepareModalInputs(options.inputs)
: [],
buttons: hasChild(options.buttons)
? await this.prepareModalButtons(options.buttons)
: [],
};
//
return alertOptions;
}
private preparePickerColumnOption(columnOption?: XPickerColumnOption) {
//
const pickerColumnOption = {
...columnOption,
text: this.getPreparedMessage(columnOption.text),
};
//
return pickerColumnOption;
}
private async preparePickerColumnOptions(
columnOptions?: XPickerColumnOption[]
) {
//
if (!hasChild(columnOptions)) {
return [];
}
//
return columnOptions.map((co) => this.preparePickerColumnOption(co));
}
private async preparePickerColumn(column?: XPickerColumn) {
//
const pickerColumn = {
...column,
options: await this.preparePickerColumnOptions(column.options),
};
//
return pickerColumn;
}
private async preparePickerColumns(columns: XPickerColumn[]) {
//
if (!hasChild(columns)) {
return [];
}
//
return columns.map((c) => this.preparePickerColumn(c));
}
private async preparePickerOptions(options?: XPickerOptions) {
//
const pickerOptions = {
...options,
buttons: (await this.prepareModalButtons(options.buttons)) || [],
columns:
(await Promise.all(await this.preparePickerColumns(options.columns))) ||
[],
};
//
return pickerOptions;
}
private async toActionSheetOptions(options?: XActionModalOptions) {
//
let buttons: any[] = [];
//
const optButtons = (await this.prepareModalButtons(options.buttons)) || [];
buttons = [...buttons, ...optButtons];
//
//#region Handle Preserved Buttons ...
if (options.hasRetry) {
buttons.push(
this.getRetryButton(options.retryRole, options.retryHandler)
);
}
//
if (options.hasAccept) {
buttons.push(
this.getAcceptButton(options.acceptRole, options.acceptHandler)
);
}
//
if (options.hasOk) {
buttons.push(this.getOkButton(options.okRole, options.okHandler));
}
//
if (options.hasCancel) {
buttons.push(
this.getCancelButton(options.cancelRole, options.cancelHandler)
);
}
//
if (options.hasYes) {
buttons.push(this.getYesButton(options.yesRole, options.yesHandler));
}
//
if (options.hasNo) {
buttons.push(this.getNoButton(options.noRole, options.noHandler));
}
//
if (options.hasDismiss) {
buttons.push(
this.getDismissButton(options.dismissRole, options.dismissHandler)
);
}
//#endregion
//
const actionModalOptions = {
...options,
header: options.header ? this.getPreparedMessage(options.header) : '',
subHeader: options.subHeader
? this.getPreparedMessage(options.subHeader)
: '',
backdropDismiss: options.backdropDismiss || true,
buttons,
};
//
return actionModalOptions;
}
private getPreparedMessage(key: string | number) {
return this.localizationService.isExistsId(key)
? this.localizationService.getValue(key)
: key
? key.toString()
: '';
}
//#endregion
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-framework-services.module.ts
import { NgModule } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { XDialogService } from './x-dialog.service';
import { XHistoryService } from './x-history.service';
import { XManagerService } from './x-manager.service';
import { XStorageService } from './x-storage.service';
import { HttpClientModule } from '@angular/common/http';
import { XSecurityService } from './x-security.service';
import { XSettingsService } from './x-settings.service';
import { XGeolocationService } from './x-geolocation.service';
import { XTaskManagerService } from './x-task-manager.service';
import { XLocalizationService } from './x-localization.service';
import { XNotificationService } from './x-notification.service';
import { XThemeManagerService } from './x-theme-manager.service';
import { XDirectivesModule } from './modules/x-directives.module';
import { XSecureStorageService } from './x-secure-storage.service';
@NgModule({
declarations: [],
imports: [
IonicModule,
CommonModule,
RouterModule,
HttpClientModule,
XDirectivesModule,
],
exports: [
CommonModule,
HttpClientModule,
XDirectivesModule,
],
providers: [
//
XDialogService,
XStorageService,
XManagerService,
XHistoryService,
XSettingsService,
XSecurityService,
XGeolocationService,
XTaskManagerService,
XLocalizationService,
XNotificationService,
XThemeManagerService,
XSecureStorageService,
]
})
export class XFrameworkServicesModule {}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-geolocation.service.ts
import {
getError,
Exceptions,
XException,
XBaseService,
} from 'x-framework-core';
import { Observable } from 'rxjs';
import { Injectable, Output, EventEmitter, Inject } from '@angular/core';
import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens';
import { XFrameworkServicesConfig } from './config/x-framework-services.config';
@Injectable({
providedIn: 'root',
})
export class XGeolocationService extends XBaseService {
//
private IS_SUPPORT = false;
private NAVIGATION_WATCHER: any;
//
options: PositionOptions;
//
@Output()
changeLoading: EventEmitter<boolean> = new EventEmitter<boolean>();
//
isLoading = false;
//
constructor(
@Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig
) {
super(config);
//
// Check Service is Supported or not ...
if (navigator.geolocation) {
this.IS_SUPPORT = true;
}
//
this.options = {
...config.geoLocationConfig,
};
}
/**
* determines service is Supported or not
*/
get isSupport() {
return this.IS_SUPPORT;
}
/**
* get given position link for open on Google Maps ...
*/
getGoogleMapLink(position: GeolocationPosition) {
return `https://maps.google.com/?q=${position.coords.latitude},${position.coords.longitude}`;
}
/**
* get given position Lat,Long string ...
*/
getLatLong(position: GeolocationPosition) {
return `${position.coords.latitude},${position.coords.longitude}`;
}
/**
* get current location ...
*/
getCurrentLocation(): Observable<GeolocationPosition> {
//
this.startLoading();
return new Observable((observer) => {
//
if (!this.IS_SUPPORT) {
//
this.stopLoading();
observer.error(getError(Exceptions.UnsupportedBrowser));
}
//
navigator.geolocation.getCurrentPosition(
(position) => {
//
this.stopLoading();
//
observer.next(position);
observer.complete();
},
(error) => {
//
this.stopLoading();
//
let exception: XException;
switch (error.code) {
case 1:
exception = Exceptions.PermissionDenied;
break;
case 2:
exception = Exceptions.PositionUnavailable;
break;
case 3:
default:
exception = Exceptions.Timeout;
break;
}
//
observer.error(getError(exception));
},
{
...this.options,
}
);
});
}
/**
* start Watching Location Changes ...
*/
watchLocation(): Observable<GeolocationPosition> {
//
this.startLoading();
//
return new Observable((observer) => {
this.NAVIGATION_WATCHER = navigator.geolocation.watchPosition(
(position) => {
//
if (!this.IS_SUPPORT) {
//
this.stopLoading();
observer.error(getError(Exceptions.UnsupportedBrowser));
observer.complete();
}
//
observer.next(position);
},
(error) => {
//
this.stopLoading();
let exception: XException;
switch (error.code) {
case 1:
exception = Exceptions.PermissionDenied;
break;
case 2:
exception = Exceptions.PositionUnavailable;
break;
case 3:
default:
exception = Exceptions.Timeout;
break;
}
//
observer.error(getError(exception));
}
);
});
}
/**
* Stop Watching Location Changes ...
*/
stopWatchingLocation() {
//
this.stopLoading();
navigator.geolocation.clearWatch(this.NAVIGATION_WATCHER);
}
private startLoading() {
//
this.isLoading = true;
this.changeLoading.emit(true);
}
private stopLoading() {
//
this.isLoading = false;
this.changeLoading.emit(false);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-history.service.ts
import { Subject } from 'rxjs';
import { Injectable } from '@angular/core';
import { Location, PlatformLocation } from '@angular/common';
@Injectable({
providedIn: 'root',
})
export class XHistoryService {
//
//#region Props ...
//
public readonly backHandler = new Subject();
//
//#region Getters ...
//
get href() {
return this.platformLocation.href;
}
get protocol() {
return this.platformLocation.protocol;
}
get hostname() {
return this.platformLocation.hostname;
}
get port() {
return this.platformLocation.port;
}
get pathname() {
return this.platformLocation.pathname;
}
get search() {
return this.platformLocation.search;
}
get hash() {
return this.platformLocation.hash;
}
//#endregion
//#endregion
//
//#region Constructor ...
constructor(
public location: Location,
public platformLocation: PlatformLocation
) {
//
// Prevent from Back Button ...
this.platformLocation.onPopState(() => {
this.backHandler.next();
});
}
//#endregion
//
//#region Actions ...
pushEmptyState() {
this.pushState(null, null, this.platformLocation.href);
}
replaceEmptyState() {
this.replaceState(null, null, this.platformLocation.href);
}
getBaseHrefFromDOM() {
return this.platformLocation.getBaseHrefFromDOM();
}
getState() {
return this.platformLocation.getState();
}
replaceState(state: any, title: string, url: string) {
this.platformLocation.replaceState(state, title, url);
}
pushState(state: any, title: string, url: string) {
this.platformLocation.pushState(state, title, url);
}
forward() {
this.location.forward();
}
back() {
this.location.back();
}
//#endregion
//
//#region Private ...
//#endregion
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-http-interceptor.service.ts
import {
HttpEvent,
HttpRequest,
HttpHandler,
HttpInterceptor,
HttpErrorResponse,
} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { Injectable, Inject } from '@angular/core';
import { finalize, catchError } from 'rxjs/operators';
import { XManagerService } from './x-manager.service';
import { XBaseService, getErrorException } from 'x-framework-core';
import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens';
import { XFrameworkServicesConfig } from './config/x-framework-services.config';
@Injectable({
providedIn: 'root',
})
export class XHttpInterceptorService
extends XBaseService
implements HttpInterceptor {
//
constructor(
@Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig,
private managerService: XManagerService
) {
super(config);
}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return this.handleInterceptRequest(req, next);
}
handleInterceptRequest(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
//
// Apply Error Handler ...
const handledErrors = this.applyErrorHandler(next.handle(req));
//
// Apply Finally Handler ...
const handledFinally = this.applyFinally(handledErrors);
//
// Final Level ...
const result = handledFinally;
//
return result;
}
//
//#region Actions / Handlers ...
applyFinally(current: Observable<HttpEvent<any>>) {
//
return current.pipe(
finalize(() => {
//
// Collection of instructions after finish or error ...
this.managerService.loading = false;
})
);
}
applyErrorHandler(current: Observable<HttpEvent<any>>) {
return current.pipe(
catchError((error: HttpErrorResponse) => {
//
this.managerService.loading = true;
const mException = getErrorException(error.error);
//
this.managerService.error = mException;
//
return throwError(error);
})
);
}
//#endregion
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-identifier.service.ts
import { Injectable } from '@angular/core';
import { XBaseService } from 'x-framework-core';
@Injectable({
providedIn: 'root',
})
export class XIdentifierService extends XBaseService {
//
//#region Props ...
private readonly idStartKey = '_[';
private readonly idEndKey = ']';
//#endregion
/**
* check if task name contains id ...
*
* @param key the task name ...
*/
hasIdentifier(key: string | any, forceAppName = false) {
//
if (!key) {
return false;
}
//
const mKey = key.toString() as string;
const result =
mKey.includes(this.idStartKey) && mKey.includes(this.idEndKey);
//
return forceAppName
? result && mKey.includes(this.config.appInstanceName)
: result;
}
/**
* retrieve and extract the raw task name from a task name ...
*
* @param key the task name ...
*/
getName(key: string | any) {
//
if (!key) {
return '';
}
//
const mKey = key.toString() as string;
//
if (!this.hasIdentifier(mKey)) {
return mKey;
}
//
const startIndex = mKey.indexOf(this.idStartKey);
let result = mKey.substr(0, startIndex);
result = result.replace(this.idStartKey, '');
//
return result;
}
/**
* retrieve and extract the id inside a task name ...
*
* @param key the task name ...
*/
getIdentifier(key: string | any, cleanAppName = true) {
//
// Validate Args ...
if (!key || !this.hasIdentifier(key)) {
return '';
}
//
// Task Id ...
let result = key.toString() as string;
//
// Validating Info ...
let index = result.indexOf(this.idStartKey);
//
result = result.substr(index, result.length);
result = result.replace(this.idStartKey, '');
//
index = result.indexOf(this.idEndKey);
result = result.substring(0, index);
//
if (cleanAppName) {
result = result.replace(this.config.appInstanceName, '');
}
//
// Return Result ...
return result;
}
/**
* prepare a Task With ID and return ...
*
* @param key the Task Name ...
* @param id th ID ...
*/
setIdentifier(key: string | any, id: string | any, containsAppName = false) {
return `${key.toString()}${this.idStartKey}${
containsAppName ? this.config.appInstanceName : ''
}${id.toString()}${this.idEndKey}`;
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-localization.service.ts
import {
XParam,
getVal,
XLocale,
isNumber,
formatDate,
XException,
Exceptions,
fromUtcDate,
XBaseService,
XResourceIDs,
GetDateProps,
XExceptionIDs,
throwException,
isValidException,
XTranslationItem,
isNullOrUndefined,
getErrorException,
XLanguageDirection,
XResourceIdentifier,
XLanguageDescriptor,
getErrorDateFormatString,
getDateOfBirthDateFormatString,
} from 'x-framework-core';
import { Injectable, Inject } from '@angular/core';
import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens';
import { XFrameworkServicesConfig } from './config/x-framework-services.config';
@Injectable({
providedIn: 'root',
})
export class XLocalizationService extends XBaseService {
//
private LANGUAGEDESCRIPTOR: XLanguageDescriptor;
private AVAILABLELANGUAGES: XLanguageDescriptor[];
//
constructor(
@Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig
) {
super(config);
//
// Inject Loacle and set Application Locale and Direction based on it ...
this.AVAILABLELANGUAGES = config.availableLanguages;
this.LANGUAGEDESCRIPTOR = config.availableLanguages.find(
(al) => al.locale === config.defaultLanguage
);
window[XParam.Language] = this.LANGUAGEDESCRIPTOR.locale;
}
//
//#region Properties ...
/**
* Current System Locale ...
*/
get locale() {
return this.languageDescriptor.locale;
}
/**
* Current Locale UI Direction ...
*/
get direction(): XLanguageDirection {
return this.languageDescriptor.direction;
}
/**
* current available language
*/
get language() {
return this.languageDescriptor.language;
}
/**
* get Current Locale Name ...
*/
get name() {
return this.languageDescriptor.name;
}
/**
* get Current Locale Language Descriptor Object ...
*/
get languageDescriptor() {
return this.LANGUAGEDESCRIPTOR;
}
/**
* get Available Languages ...
*/
get availableLanguages() {
return this.AVAILABLELANGUAGES;
}
//#endregion
/**
* change current language ...
*
* @param locale name of available language
*/
changeLocale(locale: XLocale) {
//
const languageDescriptor = this.languageDescriptorOfLocale(locale);
if (!languageDescriptor) {
throwException(XExceptionIDs.InvalidConfiguration);
}
//
window[XParam.Language] = locale;
this.LANGUAGEDESCRIPTOR = languageDescriptor;
}
/**
* Find specific Language Descriptor ...
*/
languageDescriptorOfLocale(locale: XLocale) {
//
return this.availableLanguages.find((al) => al.locale === locale);
}
/**
* check an id exists in resources or not
*/
isExistsId(id: XResourceIdentifier) {
//
const key = getVal(XResourceIDs, id) || id;
//
return (
this.languageDescriptor.resources.findIndex((tr) => tr.id === key) > -1
);
}
/**
* check an id exists in resources of specific locale or not
*/
isExistsIdOfLocale(locale: XLocale, id: XResourceIdentifier) {
//
const key = getVal(XResourceIDs, id) || id;
//
return (
this.languageDescriptorOfLocale(locale).resources.findIndex(
(tr) => tr.id === key
) > -1
);
}
/**
* get translation item of current language
*/
getTranslationItem(id: XResourceIdentifier): XTranslationItem {
//
const key = getVal(XResourceIDs, id) || id;
//
return this.languageDescriptor.resources.find((tr) => tr.id === key);
}
/**
* get translation item of specific language
*/
getTranslationItemOfLocale(locale: XLocale, id: XResourceIdentifier) {
//
const key = getVal(XResourceIDs, id) || id;
//
const selectedLocale = this.languageDescriptorOfLocale(locale);
//
if (!selectedLocale || !this.isExistsIdOfLocale(locale, key)) {
throwException(XExceptionIDs.NotFound);
}
//
return selectedLocale.resources.find((tr) => tr.id === key);
}
/**
* get Value of specific id in Current Locale
*/
getValue(id: XResourceIdentifier) {
//
if (!this.isExistsId(id)) {
return null;
}
//
return this.getTranslationItem(id).value;
}
/**
* get Value of specific id in specific Locale
*/
getValueOfLocale(locale: XLocale, id: XResourceIdentifier) {
//
if (!this.isExistsIdOfLocale(locale, id)) {
return null;
}
//
return this.getTranslationItemOfLocale(locale, id).value;
}
/**
* get coresponding translated value of errors
*/
getErrorMessage(err: any, locale?: XLocale) {
//
if (!locale) {
locale = this.locale;
}
//
let exception: XException;
//
if (isValidException(err)) {
exception = err as XException;
} else {
exception = getErrorException(err);
}
//
if (exception.id && isNumber(exception.id)) {
//
const exceptionID = `ex_${exception.id}`;
return this.getValueOfLocale(locale, exceptionID);
}
//
return this.getValueOfLocale(locale, 'general_error');
}
/**
* get and format date
*/
getDate(props?: GetDateProps): string {
//
if (!props) {
props = {};
}
//
if (!props.locale) {
props.locale = this.locale;
}
//
if (!props.date) {
props.date = new Date();
}
//
if (!props.dateFormat) {
props.dateFormat = getDateOfBirthDateFormatString(props.locale);
}
//
if (!props.toUtc) {
props.toUtc = false;
}
//
return formatDate(props.date, props.locale, props.dateFormat, props.toUtc);
}
/**
* combine some resources and represent single joined string ...
*
* @param locale translated dest locale ...
* @param joinString the string which used to join translated parts ...
* @param resources an array of translation resources ...
*/
combine(
locale?: XLocale,
joinString: string = ' ',
...resources: XResourceIdentifier[]
) {
//
if (isNullOrUndefined(locale)) {
locale = this.locale;
}
//
const result = resources
.map((r) => this.getValueOfLocale(locale, r))
.join(joinString);
//
return result;
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-manager.service.ts
import { Location } from '@angular/common';
import { Platform } from '@angular/cdk/platform';
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { XDialogService } from './x-dialog.service';
import { XStorageService } from './x-storage.service';
import { XHistoryService } from './x-history.service';
import { XSecurityService } from './x-security.service';
import { XSettingsService } from './x-settings.service';
import { Router, ActivatedRoute } from '@angular/router';
import { XIdentifierService } from './x-identifier.service';
import { XGeolocationService } from './x-geolocation.service';
import { XTaskManagerService } from './x-task-manager.service';
import { MenuController, NavController } from '@ionic/angular';
import { XNotificationService } from './x-notification.service';
import { XLocalizationService } from './x-localization.service';
import { XThemeManagerService } from './x-theme-manager.service';
import { XSecureStorageService } from './x-secure-storage.service';
import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens';
import { XFrameworkServicesConfig } from './config/x-framework-services.config';
import { XManagerFinalService } from './x-manager-service-partial/x-manager-final.service';
@Injectable({
providedIn: 'root',
})
export class XManagerService extends XManagerFinalService {
constructor(
@Inject(X_FRAMEWORK_SERVICES_CONFIG)
public config: XFrameworkServicesConfig,
public router: Router,
public platform: Platform,
public location: Location,
public httpClient: HttpClient,
public dialogService: XDialogService,
public menuController: MenuController,
public activatedRoute: ActivatedRoute,
public historyService: XHistoryService,
public storageService: XStorageService,
public securityService: XSecurityService,
public settingsService: XSettingsService,
public navigationController: NavController,
public identifierService: XIdentifierService,
public geoLocationService: XGeolocationService,
public taskManagerService: XTaskManagerService,
public themeManagerService: XThemeManagerService,
public notificationService: XNotificationService,
public localizationService: XLocalizationService,
public secureStorageService: XSecureStorageService
) {
super(
config,
router,
platform,
location,
httpClient,
dialogService,
menuController,
activatedRoute,
historyService,
storageService,
securityService,
settingsService,
navigationController,
geoLocationService,
taskManagerService,
themeManagerService,
notificationService,
localizationService,
secureStorageService
);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-notification.service.ts
import {
XColor,
isNumber,
XActionType,
XValidators,
XResourceIDs,
XBaseService,
XNotificationParams,
XTypedNotificationParams,
XErrorNotificationParams,
} from 'x-framework-core';
import { Howl } from 'howler';
import { ToastOptions } from '@ionic/core';
import { ToastController } from '@ionic/angular';
import { Injectable, Inject } from '@angular/core';
import { XLocalizationService } from './x-localization.service';
import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens';
import { XFrameworkServicesConfig } from './config/x-framework-services.config';
@Injectable({
providedIn: 'root',
})
export class XNotificationService extends XBaseService {
//
private NOTIFICATION_IDS: string[] = [];
//
private userNotifiCationSound: Howl;
private captureNotifiCationSound: Howl;
private systemNotifiCationSound: Howl;
//
public notificationDelay: number;
constructor(
@Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig,
private localizationService: XLocalizationService,
private toastController: ToastController
) {
//
super(config);
//
const userActionConfig = config.notificationAudioSources.find(
(as) => as.type === XActionType.User
);
const systemActionConfig = config.notificationAudioSources.find(
(as) => as.type === XActionType.System
);
const captureActionConfig = config.notificationAudioSources.find(
(as) => as.type === XActionType.Capture
);
//
this.notificationDelay = config.defaultNotificationDelay;
//
this.userNotifiCationSound = new Howl({
src: [userActionConfig.resourcePath],
});
this.captureNotifiCationSound = new Howl({
src: [captureActionConfig.resourcePath],
});
this.systemNotifiCationSound = new Howl({
src: [systemActionConfig.resourcePath],
});
}
/**
* play sound based on type
*/
playSound(type: XActionType = XActionType.System) {
//
switch (type) {
//
case XActionType.Capture:
this.playCaptureNotification();
break;
//
case XActionType.User:
this.playUserNotification();
break;
//
default:
case XActionType.System:
this.playSystemNotification();
break;
}
}
/**
* play system sound
*/
playSystemNotification() {
//
if (this.systemNotifiCationSound.playing()) {
return;
}
//
this.systemNotifiCationSound.play();
}
/**
* play user sound
*/
playUserNotification() {
//
if (this.userNotifiCationSound.playing()) {
return;
}
//
this.userNotifiCationSound.play();
}
/**
* play Capture sound
*/
playCaptureNotification() {
//
if (this.captureNotifiCationSound.playing()) {
return;
}
//
this.captureNotifiCationSound.play();
}
//
//#region Toas Related ...
/**
* create a notification object ...
*
* @param opt notification options
*/
createNotification(props?: XNotificationParams) {
const toastOpt = this.prepareToastOptions(props);
return this.toastController.create(toastOpt);
}
/**
* create and present notification ...
*
* @param opt notification options
*/
async presentNotification(props?: XNotificationParams) {
//
const mProps = props ? props : this.getDefaultNotificationOptions();
//
const notification = await this.createNotification(mProps);
this.NOTIFICATION_IDS.push(notification.id);
//
notification.onDidDismiss().then(() => {
if (mProps.onDidDismiss) {
mProps.onDidDismiss();
this.NOTIFICATION_IDS = this.NOTIFICATION_IDS.filter(
(id) => id === notification.id
);
}
});
//
notification.onWillDismiss().then(() => {
if (mProps.onWillDismiss) {
mProps.onWillDismiss();
}
});
//
notification.present();
//
if (props && props.playSound) {
this.playSound(props.type);
}
}
async presentXNotification(props: XTypedNotificationParams) {
//
// Validate Args ...
XValidators.validateNotNull(props);
//
const isResourceID = isNumber(props.message);
const mMessage = isResourceID
? this.localizationService.getValue(props.message as XResourceIDs)
: (props.message as string);
const defOpts = this.getDefaultNotificationOptions();
const mProps = {
...defOpts,
...props,
opt: {
...defOpts.opt,
...props.opt,
message: mMessage,
},
};
//
await this.presentNotification(mProps);
}
/**
* present Info notification
*
* @param props Notification Properties
*/
async presentInfoNotification(
props: XTypedNotificationParams
): Promise<void> {
await this.presentXNotification({
...props,
opt: {
...props.opt,
color: XColor.Tertiary,
},
});
}
/**
* present Success Notification
*
* @param props Notification Properties
*/
async presentSuccessNotification(
props: XTypedNotificationParams
): Promise<void> {
await this.presentXNotification({
...props,
opt: {
...props.opt,
color: XColor.Success,
},
});
}
/**
* present Default Success Notification
*/
async presentDefaultSuccessNotification(
dissmissHandler?: () => void
): Promise<void> {
//
const mProps: XTypedNotificationParams = {
message: XResourceIDs.success_msg,
dissmissable: true,
onWillDismiss: dissmissHandler,
};
await this.presentSuccessNotification(mProps);
}
/**
* present warning notifications
*
* @param props Notification Properties
*/
async presentWarningNotification(
props: XTypedNotificationParams
): Promise<void> {
await this.presentXNotification({
...props,
opt: {
...props.opt,
color: XColor.Warning,
},
});
}
/**
* present error notification
*
* @param props Notification Properties
*/
async presentDangerNotification(
props: XTypedNotificationParams
): Promise<void> {
await this.presentXNotification({
...props,
opt: {
...props.opt,
color: XColor.Danger,
},
});
}
/**
* present an Exception or Error Message ...
*
* @param props Notification Properties
*/
async presentErrorNotification(
props: XErrorNotificationParams
): Promise<void> {
//
const mMessage = this.localizationService.getErrorMessage(props.exception);
await this.presentXNotification({
...props,
message: mMessage,
dissmissable: props.dissmissable,
opt: {
...props.opt,
color: XColor.Danger,
},
});
}
async closeAllNotifications() {
this.NOTIFICATION_IDS.forEach(async (id) => {
try {
await this.toastController.dismiss(null, null, id);
} catch {}
});
}
/**
* combines default notification options by
* given notification options ...
*
* @param opt notification options
*/
private prepareToastOptions(props?: XNotificationParams): ToastOptions {
//
if (!props) {
props = this.getDefaultNotificationOptions();
}
//
// Handle Dissmissable
const mDuration = props.dissmissable ? props.opt.duration : 0;
//
const result = {
...props.opt,
duration: mDuration,
};
//
return result;
}
/**
* generate default notification options ...
*/
private getDefaultNotificationOptions(): XNotificationParams {
return {
playSound: false,
type: XActionType.System,
dissmissable: true,
opt: {
color: XColor.Tertiary,
position: 'bottom',
duration: this.notificationDelay,
// ,
// showCloseButton: true,
// closeButtonText: this.localizationService.getValue(XResourceIDs.dismiss)
},
};
}
//#endregion
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-secure-storage.service.ts
import {
fromJson,
XStorageItem,
XExceptionIDs,
throwException,
isNullOrUndefined
} from 'x-framework-core';
import { Injectable, Inject } from '@angular/core';
import { XStorageService } from './x-storage.service';
import { XSecurityService } from './x-security.service';
import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens';
import { XFrameworkServicesConfig } from './config/x-framework-services.config';
@Injectable({
providedIn: 'root'
})
export class XSecureStorageService extends XStorageService {
//
constructor(
@Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig,
private securitySerive: XSecurityService
) {
super(config);
}
/**
* writing a new item in Storage ...
*
* @param key the item key
* @param data the data object which needs to save
* @param forceRewrite overwrite item if exists, the default is false,
* means if key exists throws an error ...
*/
write(key: string, data: any, forceRewrite: boolean = false) {
//
if (!forceRewrite && this.isExists(key)) {
throwException(XExceptionIDs.Duplicate);
}
//
const theKey = this.getPreparedKey(key);
const encryptedValue = this.securitySerive.encryptWithKey(
JSON.stringify(data)
);
//
localStorage.setItem(theKey, encryptedValue);
}
/**
* read an item from Storage ...
* @param key the item key
* @param forceExists determine the given key must be exists or not, true is default,
* means if key not exists throws an error ...
*/
read(key: string, forceExists: boolean = true): any | null {
//
if (forceExists && !this.isExists(key)) {
throwException(XExceptionIDs.NotFound);
}
//
const theKey = this.getPreparedKey(key);
const item = localStorage.getItem(theKey);
if (!isNullOrUndefined(item)) {
try {
const decryptedValue = this.securitySerive.decryptWithKey(item);
return JSON.parse(decryptedValue);
} catch {}
}
//
return null;
}
readOfType<T>(key: string, forceExists: boolean = true): T | null {
//
if (!this.isExists(key)) {
//
if (forceExists) {
throwException(XExceptionIDs.NotFound);
}
//
return null;
}
//
const valStr = this.read(key, forceExists);
return fromJson<T>(valStr);
}
/**
* get a List of Stored items as an Array of StorageItem ...
* @param force true is defualt, means only return list of items
* from Storage which Stored by Service ...
*/
list(force: boolean = true, decrypt: boolean = false): XStorageItem[] | null {
//
if (localStorage.length === 0) {
return null;
}
//
const items: XStorageItem[] = [];
for (let i = 0; i < localStorage.length; i++) {
//
const mKey = localStorage.key(i);
//
const mValue = localStorage.getItem(mKey);
const mValueRes = decrypt
? this.securitySerive.decryptWithKey(mValue)
: mValue;
//
if (force) {
const theRawKey = this.getRawKey(mKey);
if (!isNullOrUndefined(theRawKey)) {
//
items.push({
key: theRawKey,
value: mValueRes
});
}
} else {
//
items.push({
key: mKey,
value: mValueRes
});
}
}
//
return items;
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-security.service.ts
import * as CryptoJS from 'crypto-js';
import { DomSanitizer } from '@angular/platform-browser';
import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens';
import { toMd5, XBaseService, isNullOrEmptyString } from 'x-framework-core';
import { Injectable, Inject, Sanitizer, SecurityContext } from '@angular/core';
import { XFrameworkServicesConfig } from './config/x-framework-services.config';
@Injectable({
providedIn: 'root',
})
export class XSecurityService extends XBaseService {
//
private readonly SECRET_KEY: string;
private readonly CIPHER_KEY: string;
private readonly CIPHER_IV: string;
private readonly CIPHER_OPTION: CryptoJS.lib.CipherOption;
//
constructor(
@Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig,
private sanitizer: Sanitizer,
private domSanitizer: DomSanitizer
) {
super(config);
//
this.SECRET_KEY = toMd5(config.secretKey);
//
const forIv = this.SECRET_KEY.substring(0, 16);
this.CIPHER_IV = CryptoJS.enc.Utf8.parse(forIv).toString();
//
const forKey = this.SECRET_KEY.substring(0, 32);
this.CIPHER_KEY = CryptoJS.enc.Utf8.parse(forKey).toString();
//
this.CIPHER_OPTION = {
iv: CryptoJS.enc.Utf8.parse(this.CIPHER_IV),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
};
}
encryptWithKey(
value: string,
key?: string,
options?: CryptoJS.lib.CipherOption
) {
//
if (isNullOrEmptyString(value)) {
return null;
}
//
if (!key) {
key = this.CIPHER_KEY;
}
//
if (!options) {
options = this.CIPHER_OPTION;
}
//
return CryptoJS.AES.encrypt(value, key, options).toString();
}
encryptWithSecret(
value: string,
secret?: string,
options?: CryptoJS.lib.CipherOption
) {
//
if (isNullOrEmptyString(value)) {
return null;
}
//
if (!secret) {
secret = this.SECRET_KEY;
}
//
if (!options) {
options = this.CIPHER_OPTION;
}
//
return CryptoJS.AES.encrypt(value, secret, options);
}
decryptWithKey(
cipherValue: string,
key?: string,
options?: CryptoJS.lib.CipherOption
) {
//
if (isNullOrEmptyString(cipherValue)) {
return null;
}
//
if (!key) {
key = this.CIPHER_KEY;
}
//
if (!options) {
options = this.CIPHER_OPTION;
}
//
const result = CryptoJS.AES.decrypt(cipherValue, key, options).toString(
CryptoJS.enc.Utf8
);
//
return result;
}
decryptWithSecret(
cipherValue: string,
secret?: string,
options?: CryptoJS.lib.CipherOption
) {
//
if (isNullOrEmptyString(cipherValue)) {
return null;
}
//
if (!secret) {
secret = this.SECRET_KEY;
}
//
if (!options) {
options = this.CIPHER_OPTION;
}
//
return CryptoJS.AES.decrypt(cipherValue, secret, options).toString();
}
toMd5(value: string) {
return toMd5(value);
}
toSafeString(value: string, context: SecurityContext = SecurityContext.NONE) {
return this.sanitizer.sanitize(context, value);
}
toSafeHTML(value: string) {
return this.domSanitizer.bypassSecurityTrustHtml(value);
}
toSafeResourceURL(value: string) {
return this.domSanitizer.bypassSecurityTrustResourceUrl(value);
}
toSafeURL(value: string) {
return this.domSanitizer.bypassSecurityTrustUrl(value);
}
toSafeScript(value: string) {
return this.domSanitizer.bypassSecurityTrustScript(value);
}
toSafeStyle(value: string) {
return this.domSanitizer.bypassSecurityTrustStyle(value);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-settings.service.ts
import {
isArray,
XLocale,
XDeviceInfo,
XValidators,
XOrientation,
XBaseService,
XDeviceTypes,
XOneOrManyType,
XCssProperties,
XLanguageDirection,
XSettingsStorageKey,
isNullOrEmptyString,
} from 'x-framework-core';
import {
Breakpoints,
BreakpointState,
BreakpointObserver,
} from '@angular/cdk/layout';
import { Observable } from 'rxjs';
import { Md5 } from 'md5-typescript';
import { map } from 'rxjs/operators';
import { Platform } from '@ionic/angular';
import { Injectable, Inject } from '@angular/core';
import { XStorageService } from './x-storage.service';
import { DeviceDetectorService } from 'ngx-device-detector';
import { XLocalizationService } from './x-localization.service';
import { Meta, Title, MetaDefinition } from '@angular/platform-browser';
import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens';
import { XFrameworkServicesConfig } from './config/x-framework-services.config';
@Injectable({
providedIn: 'root',
})
export class XSettingsService extends XBaseService {
//
private PREFIX = '--';
private DEVICE_INFO: XDeviceInfo;
private SIDE_MENU_OPENED: boolean;
//
//#region Breakpoint Observers ...
isMobile$: Observable<boolean>;
isXSmall$: Observable<boolean>;
isSmall$: Observable<boolean>;
isMedium$: Observable<boolean>;
isLarge$: Observable<boolean>;
isXLarge$: Observable<boolean>;
isTablet$: Observable<boolean>;
isWeb$: Observable<boolean>;
isPortrait$: Observable<boolean>;
isLandscape$: Observable<boolean>;
orientation$: Observable<XOrientation>;
//#endregion
//
//#region Properties ...
//
get uiDirection(): XLanguageDirection {
return this.localizationService.direction;
}
//#endregion
constructor(
public platform: Platform,
private meta: Meta,
private titleService: Title,
@Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig,
private storageService: XStorageService,
private localizationService: XLocalizationService,
private deviceService: DeviceDetectorService,
private breakPointObserver: BreakpointObserver
) {
//
super(config);
//
// Handle Ui Directions based on Current Locale ...
this.applyCurrentLocale();
//
// Generate Device Info ...
this.prepareDeviceInfo();
//
// define objservable ...
this.defineUiBreakPointObservers();
//
// Handle Metas for Theme ...
this.handleThemeMetaTags();
//
// Prepare Toolbar Height ...
}
/**
* restart application ...
*/
restart() {
//
if (!window || !window.location) {
return;
}
//
const href = window.location.href;
setTimeout(() => {
window.location.href = href;
window.location.reload();
}, 100)
}
/**
* change system locale ...
*
* @param locale available locale
*/
async changeLocale(locale: XLocale, refresh: boolean = false) {
//
XValidators.validateNotNull(locale);
if (locale === this.localizationService.locale) {
return;
}
//
this.storageService.write(XSettingsStorageKey.Locale, locale, true);
this.localizationService.changeLocale(locale);
this.applyCurrentLocale();
//
if (refresh) {
this.restart();
}
}
//
//#region Met Seo Service ...
addTag(tag: MetaDefinition, forceCreation?: boolean) {
this.meta.addTag(tag, forceCreation);
}
addTags(tags: MetaDefinition[], forceCreation?: boolean) {
this.meta.addTags(tags, forceCreation);
}
getTag(attrSelector: string) {
this.meta.getTag(attrSelector);
}
getTags(attrSelector: string) {
this.meta.getTags(attrSelector);
}
updateTag(tag: MetaDefinition, attrSelector?: string) {
this.meta.updateTag(tag, attrSelector);
}
removeTag(attrSelector: string) {
this.meta.removeTag(attrSelector);
}
removeTagElement(meta: HTMLMetaElement) {
this.meta.removeTagElement(meta);
}
//#endregion
//
//#region Title Service ...
/**
* set Page ( Current Document ) Title
* in Browser ...
*/
setTitle(title?: string) {
//
const appNameKey = this.config.appNameResource;
const appName = this.localizationService.getValue(appNameKey);
//
const pageTitle = !isNullOrEmptyString(title)
? `${appName} > ${title}`
: appName;
//
this.titleService.setTitle(pageTitle);
}
/**
* get the Current Document Title ...
*/
getTitle() {
return this.titleService.getTitle();
}
//#endregion
//
//#region Device Service ...
/**
* get Current Device Model Info
*/
get device() {
return this.DEVICE_INFO;
}
/**
* get Current Device token
*/
get deviceToken() {
return this.DEVICE_INFO.token;
}
//#endregion
//
//#region Css Property Handler ...
/**
* reading the CSS Property ...
*
* @param key the key of property
*/
readCssProperty(key: XCssProperties): string {
//
const bodyStyles = window.getComputedStyle(document.body);
return bodyStyles.getPropertyValue(this.prepareCssKey(key));
}
getCssVar(name: XCssProperties, element?: HTMLElement) {
//
const docElement = element
? getComputedStyle(element)
: getComputedStyle(document.documentElement);
return !name || !docElement || isNullOrEmptyString(name)
? ''
: docElement.getPropertyValue(this.prepareCssKey(name));
}
setCssVar(
name: XCssProperties,
value: string,
elements?: XOneOrManyType<HTMLElement>
) {
//
if (isNullOrEmptyString(name)) {
return;
}
//
if (!elements || !isArray(elements)) {
//
const docElement = elements
? (elements as HTMLElement).style
: document.documentElement.style;
//
docElement.setProperty(this.prepareCssKey(name), value);
} else {
(elements as HTMLElement[]).forEach((e) => {
e.style.setProperty(this.prepareCssKey(name), value);
});
}
}
//#endregion
//
//#region Theme Manager ...
//#endregion
//
//#region Private
private applyCurrentLocale() {
//
let storedLocale = this.localizationService.locale;
const isExistsLocale = this.storageService.isExists(
XSettingsStorageKey.Locale
);
if (isExistsLocale) {
storedLocale = this.storageService.readOfType<XLocale>(
XSettingsStorageKey.Locale
);
this.localizationService.changeLocale(storedLocale);
}
//
this.storageService.write(XSettingsStorageKey.Locale, storedLocale, true);
//
//#region Handle Ui Directions based on Current Locale ...
document.documentElement.lang = this.localizationService.language;
document.documentElement.dir = this.localizationService.direction;
//
this.setTitle();
//
// Document CSS ...
document.body.style.setProperty(
this.prepareCssKey('ui-direction'),
this.localizationService.direction
);
//
const isRtl = this.localizationService.direction === 'rtl';
document.body.style.setProperty(
this.prepareCssKey('is-rtl'),
isRtl.toString()
);
//#endregion
}
private prepareDeviceInfo() {
//
//#region Generate Device Info ...
//
// Reading Device Specifications ...
const deviceOs = this.deviceService.os;
const deviceBrowser = this.deviceService.browser;
const deviceOsVersion = this.deviceService.os_version;
const deviceUserAgent = this.deviceService.userAgent;
//
// Generating Device Type ...
let mDeviceType: XDeviceTypes;
if (this.deviceService.isDesktop()) {
mDeviceType = XDeviceTypes.Desktop;
} else if (this.deviceService.isTablet()) {
mDeviceType = XDeviceTypes.Tablet;
} else if (this.deviceService.isMobile()) {
mDeviceType = XDeviceTypes.Mobile;
} else {
mDeviceType = XDeviceTypes.Unknown;
}
//
// Generating Device Identifier and it's token ...
const deviceIdentifier = `[${deviceOs}]-[${deviceOsVersion}]-[${mDeviceType}]-[${deviceBrowser}]-[${deviceUserAgent}]`;
const deviceToken = Md5.init(deviceIdentifier);
//
this.DEVICE_INFO = {
os: deviceOs,
browser: deviceBrowser,
osVersion: deviceOsVersion,
userAgent: deviceUserAgent,
deviceType: mDeviceType,
identifier: deviceIdentifier,
token: deviceToken,
};
//#endregion
}
private defineUiBreakPointObservers() {
//
//#region define objservable ...
this.isPortrait$ = this.breakPointObserver
.observe([
Breakpoints.WebPortrait,
Breakpoints.TabletPortrait,
Breakpoints.HandsetPortrait,
])
.pipe(map((breakPointState: BreakpointState) => breakPointState.matches));
//
this.isLandscape$ = this.breakPointObserver
.observe([
Breakpoints.WebLandscape,
Breakpoints.TabletLandscape,
Breakpoints.HandsetLandscape,
])
.pipe(map((breakPointState: BreakpointState) => breakPointState.matches));
//
this.orientation$ = this.breakPointObserver
.observe([
Breakpoints.WebPortrait,
Breakpoints.TabletPortrait,
Breakpoints.HandsetPortrait,
Breakpoints.WebLandscape,
Breakpoints.TabletLandscape,
Breakpoints.HandsetLandscape,
])
.pipe(
map(() => {
if (
this.breakPointObserver.isMatched([
Breakpoints.WebPortrait,
Breakpoints.TabletPortrait,
Breakpoints.HandsetPortrait,
])
) {
return 'portrait';
} else {
return 'landscape';
}
})
);
//
this.isXSmall$ = this.breakPointObserver
.observe(Breakpoints.XSmall)
.pipe(map((breakPointState: BreakpointState) => breakPointState.matches));
//
this.isSmall$ = this.breakPointObserver
.observe(Breakpoints.Small)
.pipe(map((breakPointState: BreakpointState) => breakPointState.matches));
//
this.isMedium$ = this.breakPointObserver
.observe(Breakpoints.Medium)
.pipe(map((breakPointState: BreakpointState) => breakPointState.matches));
//
this.isLarge$ = this.breakPointObserver
.observe(Breakpoints.Large)
.pipe(map((breakPointState: BreakpointState) => breakPointState.matches));
//
this.isXLarge$ = this.breakPointObserver
.observe(Breakpoints.XLarge)
.pipe(map((breakPointState: BreakpointState) => breakPointState.matches));
//
this.isTablet$ = this.breakPointObserver
.observe(Breakpoints.Tablet)
.pipe(map((breakPointState: BreakpointState) => breakPointState.matches));
//
this.isWeb$ = this.breakPointObserver
.observe(Breakpoints.Web)
.pipe(map((breakPointState: BreakpointState) => breakPointState.matches));
//
this.isMobile$ = this.breakPointObserver
.observe('(max-width: 768px)')
.pipe(map((breakPointState: BreakpointState) => breakPointState.matches));
//#endregion
}
private handleThemeMetaTags() {
//
//#region Handle Metas for Theme ...
const darkPrimaryColor = this.readCssProperty('x-app-bar-color');
this.addTag(
{
name: 'theme-color',
content: darkPrimaryColor,
},
true
);
this.addTag(
{
name: 'msapplication-navbutton-color',
content: darkPrimaryColor,
},
true
);
this.addTag(
{
name: 'apple-mobile-web-app-capable',
content: 'yes',
},
true
);
this.addTag(
{
name: 'apple-mobile-web-app-status-bar-style',
content: darkPrimaryColor,
},
true
);
//#endregion
}
private prepareCssKey(key: XCssProperties) {
return `${this.PREFIX}${key}`;
}
//#endregion
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-storage.service.ts
import {
fromJson,
XStorageItem,
XBaseService,
XExceptionIDs,
throwException,
isNullOrUndefined
} from 'x-framework-core';
import { Injectable, Inject } from '@angular/core';
import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens';
import { XFrameworkServicesConfig } from './config/x-framework-services.config';
@Injectable({
providedIn: 'root'
})
export class XStorageService extends XBaseService {
//
private keyPrefix: string;
//
constructor(
@Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig
) {
super(config);
//
if (isNullOrUndefined(typeof Storage)) {
throwException(XExceptionIDs.StorageNotSupported);
}
//
this.keyPrefix = `${config.appInstanceName}`;
}
/**
* determine a key exists in storage or not ...
* @param key the item key
*/
isExists(key: string) {
//
const theKey = this.getPreparedKey(key);
const result = localStorage.getItem(theKey) !== null;
//
return result;
}
/**
* writing a new item in Storage ...
*
* @param key the item key
* @param data the data object which needs to save
* @param forceRewrite overwrite item if exists, the default is false,
* means if key exists throws an error ...
*/
write(key: string, data: any, forceRewrite: boolean = false) {
//
if (!forceRewrite && this.isExists(key)) {
throwException(XExceptionIDs.Duplicate);
}
//
const theKey = this.getPreparedKey(key);
localStorage.setItem(theKey, JSON.stringify(data));
}
/**
* read an item from Storage ...
* @param key the item key
* @param forceExists determine the given key must be exists or not, true is default,
* means if key not exists throws an error ...
*/
read(key: string, forceExists: boolean = true): any | null {
//
if (forceExists && !this.isExists(key)) {
throwException(XExceptionIDs.NotFound);
}
//
const theKey = this.getPreparedKey(key);
const item = localStorage.getItem(theKey);
if (!isNullOrUndefined(item)) {
try {
return JSON.parse(item);
} catch {}
}
//
return null;
}
readOfType<T>(key: string, forceExists: boolean = true): T | null {
//
if (!this.isExists(key)) {
//
if (forceExists) {
throwException(XExceptionIDs.NotFound);
}
//
return null;
}
//
const valStr = this.read(key, forceExists);
return fromJson<T>(valStr);
}
/**
* remove an stored item from Storage ...
* @param key the item key
* @param forceExists determine the given key must be exists or not, true is default,
* means if key not exists throws an error ...
*/
remove(key: string, forceExists: boolean = true) {
//
if (forceExists && !this.isExists(key)) {
throwException(XExceptionIDs.NotFound);
}
//
const theKey = this.getPreparedKey(key);
localStorage.removeItem(theKey);
}
/**
* get a List of Stored items as an Array of StorageItem ...
* @param force true is defualt, means only return list of items
* from Storage which Stored by Service ...
*/
list(force: boolean = true): XStorageItem[] | null {
//
if (localStorage.length === 0) {
return null;
}
//
const items: XStorageItem[] = [];
for (let i = 0; i < localStorage.length; i++) {
//
const mKey = localStorage.key(i);
//
if (force) {
const theRawKey = this.getRawKey(mKey);
if (!isNullOrUndefined(theRawKey)) {
//
items.push({
key: theRawKey,
value: localStorage.getItem(mKey)
});
}
} else {
//
items.push({
key: mKey,
value: localStorage.getItem(mKey)
});
}
}
//
return items;
}
/**
* get the number of items which stored in Storage ...
* @param force true is defualt, means only return number of items
* from Storage which Stored by Service ...
*/
length(force: boolean = true) {
//
if (force) {
return this.list().length;
}
//
return localStorage.length;
}
/**
* clear all items from Storage ...
* @param force true is defualt, means only clear items
* from Storage which Stored by Service ...
*/
clear(force: boolean = true) {
localStorage.clear();
}
protected getPreparedKey(key: string) {
return `${this.keyPrefix}_${key}`;
}
protected getRawKey(key: string): string | null {
//
const baseKeySubstr = `${this.keyPrefix}_`;
if (key.indexOf(baseKeySubstr) === -1) {
return null;
}
//
return key.replace(baseKeySubstr, '');
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-task-manager.service.ts
import {
XTask,
XException,
XBaseService,
XTaskPriority,
isValidException,
getErrorException,
} from 'x-framework-core';
import { Injectable, Inject } from '@angular/core';
import { concatMap, catchError, tap } from 'rxjs/operators';
import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens';
import { Subscription, Subject, BehaviorSubject, of, throwError } from 'rxjs';
import { XFrameworkServicesConfig } from './config/x-framework-services.config';
@Injectable({
providedIn: 'root',
})
export class XTaskManagerService extends XBaseService {
//
//#region Props ...
//
subscription: Subscription;
//
// Notify loading ...
public allTasksFinished = new Subject();
public loading = new BehaviorSubject<boolean>(false);
//
// notify Specific Task Start or Finished ...
public taskStart = new Subject<XTask<any>>();
public taskError = new Subject<XTask<any>>();
public taskFinished = new Subject<XTask<any>>();
//
private isPaused = false;
private isStarted = false;
private tasks = new Map<string, XTask<any>>();
private taskQueue = new Subject<XTask<any>>();
/**
* retrieve a Collection of Tasks which Pending to run ...
*/
get taskList() {
return this.getSortedTasksLists();
}
/**
* retrieve Running State of Tasks ...
*/
get paused() {
return this.isPaused;
}
//#endregion
//
//#region Constructor ...
constructor(
@Inject(X_FRAMEWORK_SERVICES_CONFIG) config: XFrameworkServicesConfig
) {
super(config);
//
// Register Task Queue Runner ...
this.taskQueue.asObservable().subscribe((t) => {
this.handleTaskRun(t);
});
//
this.allTasksFinished.asObservable().subscribe(() => {
this.loading.next(false);
});
}
//#endregion
//
//#region Actions ...
/**
* determines a Tasks is in Pending List or not ...
*/
has(taskName: string) {
return this.tasks.has(taskName);
}
/**
* delete a task from Pending List ...
*/
delete(taskName: string) {
return this.tasks.delete(taskName);
}
/**
* add a Task to Pending List ...
*/
add<T>(task: XTask<T>) {
//
// Prevent Duplicate ...
if (this.has(task.name)) {
return false;
}
//
// add Task to Pending List ...
this.tasks.set(task.name, task);
//
// Start Running if it's not Started Before ...
if (!this.isStarted) {
this.requestNext();
}
//
return true;
}
/**
* Change Specific Tasks Priority ...
*/
changePriority(taskName: string, priority: XTaskPriority) {
//
if (!this.has(taskName)) {
return;
}
//
this.tasks.get(taskName).priority = priority;
}
/**
* Count Pending List Tasks ...
*/
count() {
return this.tasks.size;
}
/**
* Remove All Pending List Task ...
*/
clear() {
this.isStarted = false;
this.tasks.clear();
}
/**
* Pause Running of Tasks ...
*/
pause() {
this.isPaused = true;
}
/**
* Continue Running Pending Tasks ...
*/
continue() {
//
if (!this.isPaused) {
return;
}
//
this.isPaused = false;
this.requestNext();
}
/**
* Toggle Pause/Continue Tasks Running ...
*/
toggle() {
//
if (this.isPaused) {
this.continue();
} else {
this.pause();
}
}
//#endregion
//
//#region Private ...
private requestNext() {
//
if (this.isPaused) {
return;
}
//
const task = this.popTask();
//
if (task) {
//
this.isStarted = true;
this.taskQueue.next(task);
} else {
//
this.isStarted = false;
if (this.tasks.size === 0) {
//
this.loading.next(false);
this.allTasksFinished.next();
}
}
}
private popTask() {
//
const result = this.getSortedTasksLists().pop() || null;
//
if (result) {
this.tasks.delete(result.name);
}
return result;
}
private getSortedTasksLists() {
//
return Array.from(this.tasks.values())
.sort((a, b) => a.priority - b.priority)
.reverse();
}
private applyWrapperToTask(task: XTask<any>) {
//
return of(task).pipe(
concatMap((res) => {
//
if (res.affectLoading) {
this.loading.next(true);
}
//
this.taskStart.next(res);
//
return res.task.pipe(
catchError((err) => {
//
this.isStarted = false;
this.loading.next(false);
//
res.error = getErrorException(err);
//
if (isValidException(err.error)) {
res.error = err.error as XException;
}
//
this.taskError.next(res);
//
this.handleUnSubscribe();
return throwError(res.error);
}),
tap((tRes) => {
//
this.isStarted = false;
this.loading.next(false);
//
res.result = tRes;
this.taskFinished.next(res);
//
this.handleUnSubscribe();
this.requestNext();
})
);
})
);
}
private handleTaskRun(task: XTask<any>) {
//
const mXTObs = this.applyWrapperToTask(task);
//
this.subscription = mXTObs.subscribe(
(_) => {},
(_) => {}
);
}
private handleUnSubscribe() {
//
if (this.subscription) {
//
this.subscription.unsubscribe();
this.subscription = null;
}
}
//#endregion
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-theme-manager.service.ts
import {
keys,
hasChild,
XThemeType,
XThemePack,
XThemeColors,
downloadFile,
XBaseService,
XExceptionIDs,
XThemeCssVars,
toNormalString,
isNullOrUndefined,
isNullOrEmptyString,
XExceptionIdentifier,
XThemeTypeIdentifier,
XThemeCssVarsIdentifier,
} from 'x-framework-core';
import { XStorageService } from './x-storage.service';
import { XSettingsService } from './x-settings.service';
import { XNotificationService } from './x-notification.service';
import { X_FRAMEWORK_SERVICES_CONFIG } from './tokens/x-injectable-tokens';
import { Injectable, Inject, EventEmitter, ElementRef } from '@angular/core';
import { XFrameworkServicesConfig } from './config/x-framework-services.config';
const XThemeManagerStorageKeys = {
CurrentTheme: 'current_theme',
CurrentThemeType: 'current_theme_type',
Themes: 'themes',
};
@Injectable({
providedIn: 'root',
})
export class XThemeManagerService extends XBaseService {
//
//#region Props ...
//
private PREFIX = '--';
readonly ColorCssVars = Object.assign({}, XThemeCssVars);
//
notifyChanges = new EventEmitter<void>();
//#endregion
//
//#region Constructor ...
constructor(
@Inject(X_FRAMEWORK_SERVICES_CONFIG)
public config: XFrameworkServicesConfig,
private storageService: XStorageService,
private settingsService: XSettingsService,
private notificationService: XNotificationService
) {
//
super(config);
//
this.initializeService();
}
//#endregion
//
//#region Actions ...
async applyCurrentTheme(element?: ElementRef) {
//
const currentTheme = await this.getCurrentTheme();
const isDefaultThemeExists = !isNullOrUndefined(currentTheme);
if (isDefaultThemeExists) {
//
const type = await this.getCurrentThemeType();
await this.setTheme(currentTheme, type, false, false, element);
//
this.notifyChanges.emit();
}
}
async getCurrentThemeName() {
//
const mKey = XThemeManagerStorageKeys.CurrentTheme;
//
const isExists = this.storageService.isExists(mKey);
if (!isExists) {
return '';
}
//
const result = this.storageService.readOfType<string>(mKey);
//
return result;
}
async setCurrentThemeName(themeName: string, notifyChanges: boolean = true) {
//
const isExists = await this.isThemeExists(themeName);
if (!isExists) {
//
if (notifyChanges) {
await this.issueFailedNotification(XExceptionIDs.NotFound);
}
//
return false;
}
//
const mKey = XThemeManagerStorageKeys.CurrentTheme;
//
this.storageService.write(mKey, themeName, true);
//
if (notifyChanges) {
//
this.notifyChanges.emit();
await this.issueSuccessNotification();
}
//
return true;
}
async getCurrentThemeType() {
//
const mKey = XThemeManagerStorageKeys.CurrentThemeType;
//
const isExists = this.storageService.isExists(mKey);
if (!isExists) {
return XThemeType.Light;
}
//
const result = this.storageService.readOfType<XThemeTypeIdentifier>(mKey);
//
return result;
}
async setCurrentThemeType(
themeType: XThemeTypeIdentifier,
notifyChanges: boolean = true
) {
//
if (isNullOrEmptyString(themeType)) {
//
if (notifyChanges) {
await this.issueFailedNotification(XExceptionIDs.InvalidArgs);
}
//
return false;
}
//
const mKey = XThemeManagerStorageKeys.CurrentThemeType;
//
this.storageService.write(mKey, themeType, true);
//
if (notifyChanges) {
//
this.notifyChanges.emit();
await this.issueSuccessNotification();
}
//
return true;
}
async setTheme(
theme: XThemePack,
whichType: XThemeTypeIdentifier = XThemeType.Light,
notifyChanges: boolean = true,
restart: boolean = true,
element?: ElementRef
) {
//
if (isNullOrUndefined(theme)) {
//
if (notifyChanges) {
await this.issueFailedNotification(XExceptionIDs.InvalidArgs);
}
//
return false;
}
//
const isExists = await this.isThemeExists(theme.name);
if (!isExists) {
//
if (notifyChanges) {
await this.issueFailedNotification(XExceptionIDs.NotFound);
}
//
return false;
}
//
let result = false;
switch (whichType) {
//
case XThemeType.Light:
result = await this.setThemeColors(theme.light.colors, element);
break;
//
case XThemeType.Dark:
result = await this.setThemeColors(theme.dark.colors, element);
break;
}
//
if (result) {
//
await this.setCurrentThemeType(whichType, false);
await this.setCurrentThemeName(theme.name, false);
}
//
if (result && notifyChanges) {
//
this.notifyChanges.emit();
await this.issueSuccessNotification();
}
//
if (result && restart) {
this.settingsService.restart();
}
//
return result;
}
async cloneTheme(
themeName: string,
clonedThemeName: string,
notifyChanges: boolean = true
) {
//
const isExists = await this.isThemeExists(themeName);
if (!isExists) {
//
if (notifyChanges) {
await this.issueFailedNotification(XExceptionIDs.NotFound);
}
//
return false;
}
//
const isClonedThemeNameReserved = await this.isThemeExists(clonedThemeName);
if (isClonedThemeNameReserved) {
//
if (notifyChanges) {
await this.issueFailedNotification(XExceptionIDs.Duplicate);
}
//
return false;
}
//
const theme = await this.getTheme(themeName);
if (!theme) {
//
if (notifyChanges) {
await this.issueFailedNotification(XExceptionIDs.NotFound);
}
//
return false;
}
//
theme.name = clonedThemeName;
const result = await this.saveTheme(theme, false);
//
if (result && notifyChanges) {
this.notifyChanges.emit();
}
//
return result;
}
async exportTheme(themeName: string) {
//
if (isNullOrEmptyString(themeName)) {
return;
}
//
const theme = await this.getTheme(themeName);
if (isNullOrUndefined(theme)) {
return;
}
//
const theJSON = JSON.stringify(theme);
//
downloadFile(theJSON, 'text/json', `x-framework-${theme.name}-theme.json`);
}
async removeTheme(themeName: string, notifyChanges: boolean = true) {
//
const isExists = await this.isThemeExists(themeName);
if (!isExists) {
//
if (notifyChanges) {
await this.issueFailedNotification(XExceptionIDs.NotFound);
}
//
return false;
}
//
const currentThemeName = await this.getCurrentThemeName();
if (!currentThemeName) {
//
if (notifyChanges) {
await this.issueFailedNotification(XExceptionIDs.NotFound);
}
//
return false;
}
//
const themes = await this.getThemes();
if (!hasChild(themes) || themes.length === 1) {
//
if (notifyChanges) {
await this.issueFailedNotification(XExceptionIDs.NotFound);
}
//
return false;
}
//
const filteredThemes = themes.filter(
(th) => toNormalString(th.name) !== toNormalString(themeName)
);
//
let result = false;
try {
//
result = true;
this.writeThemes(filteredThemes);
} catch {
result = false;
}
//
const isCurrentRemoved =
toNormalString(currentThemeName) === toNormalString(themeName);
if (isCurrentRemoved) {
//
const newCurrentTheme = filteredThemes[0];
const themeType = await this.getCurrentThemeType();
result = await this.setTheme(newCurrentTheme, themeType, false, false);
}
//
if (result && notifyChanges) {
//
this.notifyChanges.emit();
await this.issueSuccessNotification();
}
//
if (result && isCurrentRemoved) {
this.settingsService.restart();
}
//
return result;
}
async saveTheme(theme: XThemePack, notifyChanges: boolean = true) {
//
if (isNullOrUndefined(theme)) {
//
if (notifyChanges) {
await this.issueFailedNotification(XExceptionIDs.InvalidArgs);
}
//
return false;
}
//
const isExists = await this.isThemeExists(theme.name);
if (isExists) {
//
if (notifyChanges) {
await this.issueFailedNotification(XExceptionIDs.Duplicate);
}
//
return false;
}
//
const themeType = await this.getCurrentThemeType();
//
const themes = await this.getThemes();
if (!hasChild(themes)) {
//
const newThemes = [theme];
//
this.writeThemes(newThemes);
//
const result = await this.setTheme(theme, themeType, true);
return result;
} else {
//
const themeIndex = themes.findIndex((th) => th.name === theme.name);
if (themeIndex === -1) {
themes.push(theme);
} else {
themes[themeIndex] = theme;
}
//
this.writeThemes(themes);
//
if (notifyChanges) {
//
this.notifyChanges.emit();
await this.issueSuccessNotification();
}
//
return true;
}
}
async updateTheme(
themeName: string,
updatedTheme: XThemePack,
notifiChanges: boolean = true,
restartIfCurrent: boolean = true
) {
//
if (isNullOrEmptyString(themeName) || isNullOrUndefined(updatedTheme)) {
//
if (notifiChanges) {
await this.issueFailedNotification(XExceptionIDs.InvalidArgs);
}
//
return false;
}
//
const isExists = await this.isThemeExists(themeName);
if (!isExists) {
//
if (notifiChanges) {
await this.issueFailedNotification(XExceptionIDs.NotFound);
}
//
return false;
}
//
const currentThemeName = await this.getCurrentThemeName();
const isCurrent =
toNormalString(themeName) === toNormalString(currentThemeName);
//
let result = false;
const themes = this.readThemes();
const themeIndex = themes.findIndex(
(th) => toNormalString(th.name) === toNormalString(themeName)
);
if (themeIndex < 0) {
//
if (notifiChanges) {
await this.issueFailedNotification(XExceptionIDs.NotFound);
}
//
return result;
}
//
themes[themeIndex] = updatedTheme;
try {
result = true;
this.writeThemes(themes);
} catch {
//
if (notifiChanges) {
await this.issueFailedNotification(XExceptionIDs.ActionFailed);
}
//
return false;
}
//
if (result && isCurrent) {
//
const mode = await this.getCurrentThemeType();
const isSetted = await this.setTheme(updatedTheme, mode, false, false);
if (!isSetted) {
//
if (notifiChanges) {
await this.issueFailedNotification(XExceptionIDs.ActionFailed);
}
//
return false;
}
}
//
if (result && notifiChanges) {
await this.issueSuccessNotification();
}
//
if (isCurrent && restartIfCurrent) {
this.settingsService.restart();
}
//
return result;
}
async getCurrentTheme() {
//
const currentThemeName = await this.getCurrentThemeName();
const isExists = await this.isThemeExists(currentThemeName);
if (!isExists) {
return null;
}
//
const result = await this.getTheme(currentThemeName);
return result;
}
async getThemeNames() {
//
const themes = await this.getThemes();
if (!hasChild(themes)) {
return [];
}
//
return themes.map((th) => th.name);
}
async getThemes() {
//
const result = this.readThemes();
//
return result;
}
async getTheme(themeName: string) {
//
const isExists = await this.isThemeExists(themeName);
if (!isExists) {
return null;
}
//
const themes = await this.getThemes();
return themes.find(
(th) => toNormalString(th.name) === toNormalString(themeName)
);
}
async isThemeExists(themeName: string) {
//
if (isNullOrEmptyString(themeName)) {
return false;
}
//
const themes = await this.getThemeNames();
const result =
themes.findIndex(
(th) => toNormalString(th) === toNormalString(themeName)
) > -1;
//
return result;
}
async setLightMode() {
//
const currentTheme = await this.getCurrentTheme();
if (isNullOrUndefined(currentTheme)) {
return false;
}
//
return await this.setTheme(currentTheme, XThemeType.Light, false, true);
}
async setDarkMode() {
//
const currentTheme = await this.getCurrentTheme();
if (isNullOrUndefined(currentTheme)) {
return false;
}
//
return await this.setTheme(currentTheme, XThemeType.Dark, false, true);
}
async toggleMode() {
//
const currentTheme = await this.getCurrentTheme();
const currentThemeMode = await this.getCurrentThemeType();
if (isNullOrUndefined(currentTheme)) {
return false;
}
//
const mode: XThemeType =
currentThemeMode === XThemeType.Light
? XThemeType.Dark
: XThemeType.Light;
//
return await this.setTheme(currentTheme, mode, false, true);
}
//#endregion
//
//#region Private ...
private async initializeService() {
//
const currentTheme = await this.getCurrentTheme();
const isDefaultThemeExists = !isNullOrUndefined(currentTheme);
if (!isDefaultThemeExists) {
//
const defaultTheme: XThemePack = {
name: 'default',
light: {
type: XThemeType.Light,
colors: {
//
//#region Primary ...
//
XColorPrimary: this.getCssVar(XThemeCssVars.XColorPrimary),
XColorPrimaryContrast: this.getCssVar(
XThemeCssVars.XColorPrimaryContrast
),
//
XColorPrimaryShade: this.getCssVar(
XThemeCssVars.XColorPrimaryShade
),
XColorPrimaryShadeContrast: this.getCssVar(
XThemeCssVars.XColorPrimaryShadeContrast
),
//
XColorPrimaryTint: this.getCssVar(XThemeCssVars.XColorPrimaryTint),
XColorPrimaryTintContrast: this.getCssVar(
XThemeCssVars.XColorPrimaryTintContrast
),
//#endregion
//
//#region Secondary ...
//
XColorSecondary: this.getCssVar(XThemeCssVars.XColorSecondary),
XColorSecondaryContrast: this.getCssVar(
XThemeCssVars.XColorSecondaryContrast
),
//
XColorSecondaryShade: this.getCssVar(
XThemeCssVars.XColorSecondaryShade
),
XColorSecondaryShadeContrast: this.getCssVar(
XThemeCssVars.XColorSecondaryShadeContrast
),
//
XColorSecondaryTint: this.getCssVar(
XThemeCssVars.XColorSecondaryTint
),
XColorSecondaryTintContrast: this.getCssVar(
XThemeCssVars.XColorSecondaryTintContrast
),
//#endregion
//
//#region Tertiary ...
//
XColorTertiary: this.getCssVar(XThemeCssVars.XColorTertiary),
XColorTertiaryContrast: this.getCssVar(
XThemeCssVars.XColorTertiaryContrast
),
//
XColorTertiaryShade: this.getCssVar(
XThemeCssVars.XColorTertiaryShade
),
XColorTertiaryShadeContrast: this.getCssVar(
XThemeCssVars.XColorTertiaryShadeContrast
),
//
XColorTertiaryTint: this.getCssVar(
XThemeCssVars.XColorTertiaryTint
),
XColorTertiaryTintContrast: this.getCssVar(
XThemeCssVars.XColorTertiaryTintContrast
),
//#endregion
//
//#region Success ...
//
XColorSuccess: this.getCssVar(XThemeCssVars.XColorSuccess),
XColorSuccessContrast: this.getCssVar(
XThemeCssVars.XColorSuccessContrast
),
//
XColorSuccessShade: this.getCssVar(
XThemeCssVars.XColorSuccessShade
),
XColorSuccessShadeContrast: this.getCssVar(
XThemeCssVars.XColorSuccessShadeContrast
),
//
XColorSuccessTint: this.getCssVar(XThemeCssVars.XColorSuccessTint),
XColorSuccessTintContrast: this.getCssVar(
XThemeCssVars.XColorSuccessTintContrast
),
//#endregion
//
//#region Warning ...
//
XColorWarning: this.getCssVar(XThemeCssVars.XColorWarning),
XColorWarningContrast: this.getCssVar(
XThemeCssVars.XColorWarningContrast
),
//
XColorWarningShade: this.getCssVar(
XThemeCssVars.XColorWarningShade
),
XColorWarningShadeContrast: this.getCssVar(
XThemeCssVars.XColorWarningShadeContrast
),
//
XColorWarningTint: this.getCssVar(XThemeCssVars.XColorWarningTint),
XColorWarningTintContrast: this.getCssVar(
XThemeCssVars.XColorWarningTintContrast
),
//#endregion
//
//#region Danger ...
//
XColorDanger: this.getCssVar(XThemeCssVars.XColorDanger),
XColorDangerContrast: this.getCssVar(
XThemeCssVars.XColorDangerContrast
),
//
XColorDangerShade: this.getCssVar(XThemeCssVars.XColorDangerShade),
XColorDangerShadeContrast: this.getCssVar(
XThemeCssVars.XColorDangerShadeContrast
),
//
XColorDangerTint: this.getCssVar(XThemeCssVars.XColorDangerTint),
XColorDangerTintContrast: this.getCssVar(
XThemeCssVars.XColorDangerTintContrast
),
//#endregion
//
//#region Dark ...
//
XColorDark: this.getCssVar(XThemeCssVars.XColorDark),
XColorDarkContrast: this.getCssVar(
XThemeCssVars.XColorDarkContrast
),
//
XColorDarkShade: this.getCssVar(XThemeCssVars.XColorDarkShade),
XColorDarkShadeContrast: this.getCssVar(
XThemeCssVars.XColorDarkShadeContrast
),
//
XColorDarkTint: this.getCssVar(XThemeCssVars.XColorDarkTint),
XColorDarkTintContrast: this.getCssVar(
XThemeCssVars.XColorDarkTintContrast
),
//#endregion
//
//#region Medium ...
//
XColorMedium: this.getCssVar(XThemeCssVars.XColorMedium),
XColorMediumContrast: this.getCssVar(
XThemeCssVars.XColorMediumContrast
),
//
XColorMediumShade: this.getCssVar(XThemeCssVars.XColorMediumShade),
XColorMediumShadeContrast: this.getCssVar(
XThemeCssVars.XColorMediumShadeContrast
),
//
XColorMediumTint: this.getCssVar(XThemeCssVars.XColorMediumTint),
XColorMediumTintContrast: this.getCssVar(
XThemeCssVars.XColorMediumTintContrast
),
//#endregion
//
//#region Light ...
//
XColorLight: this.getCssVar(XThemeCssVars.XColorLight),
XColorLightContrast: this.getCssVar(
XThemeCssVars.XColorLightContrast
),
//
XColorLightShade: this.getCssVar(XThemeCssVars.XColorLightShade),
XColorLightShadeContrast: this.getCssVar(
XThemeCssVars.XColorLightShadeContrast
),
//
XColorLightTint: this.getCssVar(XThemeCssVars.XColorLightTint),
XColorLightTintContrast: this.getCssVar(
XThemeCssVars.XColorLightTintContrast
),
//#endregion
},
},
dark: {
type: XThemeType.Dark,
colors: {
//
//#region Primary ...
//
XColorPrimary: this.getCssVar(XThemeCssVars.XColorDark),
XColorPrimaryContrast: this.getCssVar(
XThemeCssVars.XColorDarkContrast
),
//
XColorPrimaryShade: this.getCssVar(XThemeCssVars.XColorDarkShade),
XColorPrimaryShadeContrast: this.getCssVar(
XThemeCssVars.XColorDarkShadeContrast
),
//
XColorPrimaryTint: this.getCssVar(XThemeCssVars.XColorDarkTint),
XColorPrimaryTintContrast: this.getCssVar(
XThemeCssVars.XColorDarkTintContrast
),
//#endregion
//
//#region Secondary ...
//
XColorSecondary: this.getCssVar(XThemeCssVars.XColorDarkTint),
XColorSecondaryContrast: this.getCssVar(
XThemeCssVars.XColorDarkTintContrast
),
//
XColorSecondaryShade: this.getCssVar(XThemeCssVars.XColorDarkTint),
XColorSecondaryShadeContrast: this.getCssVar(
XThemeCssVars.XColorDarkTintContrast
),
//
XColorSecondaryTint: this.getCssVar(XThemeCssVars.XColorDarkTint),
XColorSecondaryTintContrast: this.getCssVar(
XThemeCssVars.XColorDarkTintContrast
),
//#endregion
//
//#region Tertiary ...
//
XColorTertiary: this.getCssVar(XThemeCssVars.XColorTertiary),
XColorTertiaryContrast: this.getCssVar(
XThemeCssVars.XColorTertiaryContrast
),
//
XColorTertiaryShade: this.getCssVar(
XThemeCssVars.XColorTertiaryShade
),
XColorTertiaryShadeContrast: this.getCssVar(
XThemeCssVars.XColorTertiaryShadeContrast
),
//
XColorTertiaryTint: this.getCssVar(
XThemeCssVars.XColorTertiaryTint
),
XColorTertiaryTintContrast: this.getCssVar(
XThemeCssVars.XColorTertiaryTintContrast
),
//#endregion
//
//#region Success ...
//
XColorSuccess: this.getCssVar(XThemeCssVars.XColorSuccess),
XColorSuccessContrast: this.getCssVar(
XThemeCssVars.XColorSuccessContrast
),
//
XColorSuccessShade: this.getCssVar(
XThemeCssVars.XColorSuccessShade
),
XColorSuccessShadeContrast: this.getCssVar(
XThemeCssVars.XColorSuccessShadeContrast
),
//
XColorSuccessTint: this.getCssVar(XThemeCssVars.XColorSuccessTint),
XColorSuccessTintContrast: this.getCssVar(
XThemeCssVars.XColorSuccessTintContrast
),
//#endregion
//
//#region Warning ...
//
XColorWarning: this.getCssVar(XThemeCssVars.XColorWarning),
XColorWarningContrast: this.getCssVar(
XThemeCssVars.XColorWarningContrast
),
//
XColorWarningShade: this.getCssVar(
XThemeCssVars.XColorWarningShade
),
XColorWarningShadeContrast: this.getCssVar(
XThemeCssVars.XColorWarningShadeContrast
),
//
XColorWarningTint: this.getCssVar(XThemeCssVars.XColorWarningTint),
XColorWarningTintContrast: this.getCssVar(
XThemeCssVars.XColorWarningTintContrast
),
//#endregion
//
//#region Danger ...
//
XColorDanger: this.getCssVar(XThemeCssVars.XColorDanger),
XColorDangerContrast: this.getCssVar(
XThemeCssVars.XColorDangerContrast
),
//
XColorDangerShade: this.getCssVar(XThemeCssVars.XColorDangerShade),
XColorDangerShadeContrast: this.getCssVar(
XThemeCssVars.XColorDangerShadeContrast
),
//
XColorDangerTint: this.getCssVar(XThemeCssVars.XColorDangerTint),
XColorDangerTintContrast: this.getCssVar(
XThemeCssVars.XColorDangerTintContrast
),
//#endregion
//
//#region Dark ...
//
XColorDark: this.getCssVar(XThemeCssVars.XColorDark),
XColorDarkContrast: this.getCssVar(
XThemeCssVars.XColorDarkContrast
),
//
XColorDarkShade: this.getCssVar(XThemeCssVars.XColorDarkShade),
XColorDarkShadeContrast: this.getCssVar(
XThemeCssVars.XColorDarkShadeContrast
),
//
XColorDarkTint: this.getCssVar(XThemeCssVars.XColorDarkTint),
XColorDarkTintContrast: this.getCssVar(
XThemeCssVars.XColorDarkTintContrast
),
//#endregion
//
//#region Medium ...
//
XColorMedium: this.getCssVar(XThemeCssVars.XColorMedium),
XColorMediumContrast: this.getCssVar(
XThemeCssVars.XColorMediumContrast
),
//
XColorMediumShade: this.getCssVar(XThemeCssVars.XColorMediumShade),
XColorMediumShadeContrast: this.getCssVar(
XThemeCssVars.XColorMediumShadeContrast
),
//
XColorMediumTint: this.getCssVar(XThemeCssVars.XColorMediumTint),
XColorMediumTintContrast: this.getCssVar(
XThemeCssVars.XColorMediumTintContrast
),
//#endregion
//
//#region Light ...
//
XColorLight: this.getCssVar(XThemeCssVars.XColorLight),
XColorLightContrast: this.getCssVar(
XThemeCssVars.XColorLightContrast
),
//
XColorLightShade: this.getCssVar(XThemeCssVars.XColorLightShade),
XColorLightShadeContrast: this.getCssVar(
XThemeCssVars.XColorLightShadeContrast
),
//
XColorLightTint: this.getCssVar(XThemeCssVars.XColorLightTint),
XColorLightTintContrast: this.getCssVar(
XThemeCssVars.XColorLightTintContrast
),
//#endregion
},
},
};
//
await this.saveTheme(defaultTheme, false);
} else {
//
const type = await this.getCurrentThemeType();
await this.setTheme(currentTheme, type, false, false);
}
//
this.notifyChanges.emit();
}
private async issueFailedNotification(exception?: XExceptionIdentifier) {
//
if (isNullOrUndefined(exception)) {
exception = XExceptionIDs.ActionFailed;
}
//
await this.notificationService.presentErrorNotification({
exception,
dissmissable: false,
});
}
private async issueSuccessNotification() {
//
await this.notificationService.presentDefaultSuccessNotification();
}
//
//#region Read and Write Storage ...
private writeThemes(themes: XThemePack[]) {
//
const mKey = XThemeManagerStorageKeys.Themes;
//
this.storageService.write(mKey, themes, true);
}
private readThemes() {
//
const mKey = XThemeManagerStorageKeys.Themes;
//
const isExists = this.storageService.isExists(mKey);
if (!isExists) {
return [];
}
//
return this.storageService.readOfType<XThemePack[]>(mKey, false);
}
//#endregion
//
//#region CssVar Manipulators ...
/**
* prepare a css var name
*
* @param key css variable name
*/
private prepareCssKey(key: XThemeCssVarsIdentifier) {
return `${this.PREFIX}${key}`;
}
/**
* remove css key prefix ...
*
* @param key a prepared css var ...
*/
private removeCssKeyPrefix(key: XThemeCssVarsIdentifier) {
return key.replace(this.PREFIX, '');
}
/**
* read specific css var value of an element
* @param name css variable name
* @param element destination element
*/
private getCssVar(name: XThemeCssVarsIdentifier) {
//
return getComputedStyle(document.body).getPropertyValue(
this.prepareCssKey(name)
);
}
/**
* set css var into element ...
*
* @param name css var name
* @param value css var value
* @param elements destination element of array of elements
*/
private setCssVar(
name: XThemeCssVarsIdentifier,
value: string,
element?: ElementRef
) {
//
if (isNullOrEmptyString(name)) {
return;
}
//
// Setting Variable on Element if exists ...
if (element && element.nativeElement) {
(element.nativeElement as HTMLElement).style.setProperty(
this.prepareCssKey(name),
value
);
}
//
// Setting Variable on root ...
document.documentElement.style.setProperty(this.prepareCssKey(name), value);
}
private async setThemeColors(theme: XThemeColors, element?: ElementRef) {
//
if (isNullOrUndefined(theme)) {
return false;
}
//
const colorKeys = keys(theme);
colorKeys.forEach((cKey) => {
//
const cssKey = this.ColorCssVars[cKey] as string;
const ionCssKey = cssKey.replace('x-', 'ion-');
const cssValue = toNormalString(theme[cKey]);
//
this.setCssVar(cssKey, cssValue, element);
this.setCssVar(ionCssKey, cssValue, element);
});
//
return true;
}
//#endregion
//#endregion
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\config\x-framework-services.config.ts
import { XFrameworkCoreConfig } from 'x-framework-core';
// tslint:disable-next-line:no-empty-interface
export interface XFrameworkServicesConfig extends XFrameworkCoreConfig {
geoLocationConfig?: PositionOptions
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\directives\x-currency-formatter.directive.ts
import {
Input,
Inject,
Renderer2,
Directive,
ElementRef,
forwardRef,
HostListener
} from '@angular/core';
import {
XLocale,
removeAll,
applyLocale,
isNullOrEmptyString
} from 'x-framework-core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { X_FRAMEWORK_SERVICES_CONFIG } from '../tokens/x-injectable-tokens';
import { XFrameworkServicesConfig } from '../config/x-framework-services.config';
export const X_CURRENCY_FORMATTER: any = {
useExisting: forwardRef(() => XCurrencyFormatterDirective),
provide: NG_VALUE_ACCESSOR,
multi: true
};
@Directive({
// tslint:disable-next-line:directive-selector
selector: '[xCurrencyFormatter]',
providers: [X_CURRENCY_FORMATTER]
})
export class XCurrencyFormatterDirective implements ControlValueAccessor {
//
//#region Props ...
@Input()
locale: XLocale;
@Input()
applyLocaleToCurrency: boolean;
@Input()
currencySeperator: string;
@Input()
enabledCurrencyFormatter: boolean;
onChange = (_: any) => {};
onTouched = () => {};
//#endregion
//
//#region Constructor ...
constructor(
private renderer: Renderer2,
private elementRef: ElementRef,
@Inject(X_FRAMEWORK_SERVICES_CONFIG)
private config: XFrameworkServicesConfig
) {}
//#endregion
//
//#region Host Bindings ...
@HostListener('change', ['$event.target.value'])
change(value: string) {
//
const res = this.getUnformattedValue(value);
this.onChange(res);
}
@HostListener('input', ['$event.target.value'])
input(value: string) {
//
const res = this.getUnformattedValue(value);
this.onChange(res);
}
@HostListener('blur')
onBlur() {
this.onTouched();
}
@HostListener('keydown', ['$event'])
onKeyDown(event: any) {
if (this.enabledCurrencyFormatter) {
this.setOnlyNumberType(event);
}
}
//#endregion
//
//#region Implemenntation of Interface ...
writeValue(value: string): void {
this.setValue(value);
}
registerOnChange(fn: (_: string | any | null) => void): void {
this.onChange = value => {
//
fn(this.enabledCurrencyFormatter ? +value : value);
this.setValue(value);
};
}
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
this.renderer.setProperty(
this.elementRef.nativeElement,
'disabled',
isDisabled
);
}
//#endregion
//
//#region Private ...
private isElementValid() {
return this.elementRef && this.elementRef.nativeElement;
}
private getFormattedValue(value: string) {
//
if (!this.enabledCurrencyFormatter || !value) {
return value || '';
}
//
if (this.applyLocaleToCurrency) {
value = applyLocale(value, this.locale || this.config.defaultLanguage);
}
//
const result = value
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, this.currencySeperator);
//
return result;
}
private getUnformattedValue(value: string) {
//
const result = removeAll(value, this.currencySeperator, true);
return result;
}
private getNormalizedValue(value: string) {
//
if (!this.isElementValid()) {
return value;
}
//
value = isNullOrEmptyString(value) ? '' : this.getUnformattedValue(value);
//
if (this.enabledCurrencyFormatter) {
value = this.getFormattedValue(value);
} else {
value = this.getUnformattedValue(value);
}
//
return value;
}
private setValue(value: string) {
//
const normalizedValue = this.getNormalizedValue(value);
this.renderer.setProperty(
this.elementRef.nativeElement,
'value',
normalizedValue
);
}
private setOnlyNumberType(e: any) {
//
const keyCode = e.code as string;
const isValidKey =
keyCode.includes('Digit') || keyCode.includes('Backspace');
//
if (!isValidKey) {
e.preventDefault();
}
}
//#endregion
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\directives\x-date-presenter.directive.ts
import {
XLocale,
formatDate,
getDateOfBirthDateFormatString,
} from 'x-framework-core';
import { XLocalizationService } from '../x-localization.service';
import {
Directive,
ElementRef,
OnInit,
Input,
OnChanges,
SimpleChanges,
} from '@angular/core';
@Directive({
// tslint:disable-next-line:directive-selector
selector: '[xDatePresenter]',
})
export class XDatePresenterDirective implements OnInit, OnChanges {
//
@Input()
date?: Date | string;
@Input()
locale?: XLocale;
@Input()
format?: string;
@Input()
isUtc?: boolean;
@Input()
toUtc?: boolean;
constructor(
private element: ElementRef,
private localizationService: XLocalizationService
) {}
ngOnInit() {
this.presentDate();
}
ngOnChanges(changes: SimpleChanges): void {
this.presentDate();
}
private presentDate() {
//
if (!this.locale) {
this.locale = this.localizationService.locale;
}
//
if (!this.date) {
this.date = new Date();
}
//
if (!this.format) {
this.format = getDateOfBirthDateFormatString(this.locale);
}
//
if (!this.toUtc) {
this.toUtc = false;
}
//
let dateStr: string;
try {
dateStr = formatDate(
this.date,
this.locale,
this.format,
this.isUtc,
this.toUtc
);
} catch {
dateStr = '---';
}
//
this.element.nativeElement.innerHTML = dateStr;
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\directives\x-from-input-formatter.directive.ts
import {
Input,
Inject,
Directive,
Renderer2,
ElementRef,
forwardRef,
HostListener,
} from '@angular/core';
import {
XLocale,
hasChild,
removeAll,
getDigits,
toXString,
applyLocale,
getNonDigits,
removeSpaces,
isNullOrUndefined,
extractUniqueChars,
isNullOrEmptyString,
} from 'x-framework-core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
import { X_FRAMEWORK_SERVICES_CONFIG } from '../tokens/x-injectable-tokens';
import { XFrameworkServicesConfig } from '../config/x-framework-services.config';
export const X_FORM_INPUT_FORMATTER: any = {
useExisting: forwardRef(() => XFromInputFormatterDirective),
provide: NG_VALUE_ACCESSOR,
multi: true,
};
export enum XFormInputFormatter {
ApplyLocale = 'apply_locale',
FormatCurrency = 'format_currency',
StringFormatter = 'string_formatter',
StringInputFormatter = 'string_input_formatter',
FormatCurrencyAndApplyLocale = 'format_currency_apply_locale',
StringFormatterAndApplyLocale = 'string_formatter_apply_locale',
StringInputFormatterAndApplyLocale = 'string_input_formatter_apply_locale',
}
export type XFormInputFormatterIdentifier = XFormInputFormatter | string;
export enum XStringInputFormatType {
None = 'none',
LowerCase = 'lowercase',
UpperCase = 'uppercase',
NonSpace = 'non_space',
NonDigits = 'none_digits',
OnlyDigits = 'only_digits',
UniqueChars = 'unique_chars',
}
export type XStringInputFormatTypeIdentifier = XStringInputFormatType | string;
@Directive({
// tslint:disable-next-line:directive-selector
selector: '[xFromInputFormatter]',
providers: [X_FORM_INPUT_FORMATTER],
})
export class XFromInputFormatterDirective implements ControlValueAccessor {
//
//#region Props ...
@Input()
locale: XLocale;
@Input()
inputFormatterType: XFormInputFormatterIdentifier;
@Input()
stringInputFormatterType: XStringInputFormatTypeIdentifier;
@Input()
seperator: string;
@Input()
currencyLable: string;
@Input()
stringFormatter: number[];
@Input()
enabledInputFormatter: boolean;
//
onChange = (_: any) => {};
onTouched = () => {};
onFocused = () => {};
//#endregion
//
//#region Constructor ...
constructor(
private renderer: Renderer2,
private elementRef: ElementRef,
@Inject(X_FRAMEWORK_SERVICES_CONFIG)
private config: XFrameworkServicesConfig
) {}
//#endregion
//
//#region Type Detectors ...
isCurrencyType() {
return (
this.inputFormatterType === XFormInputFormatter.FormatCurrency ||
this.inputFormatterType ===
XFormInputFormatter.FormatCurrencyAndApplyLocale
);
}
isStringFormatterType() {
return (
this.inputFormatterType === XFormInputFormatter.StringFormatter ||
this.inputFormatterType ===
XFormInputFormatter.StringFormatterAndApplyLocale ||
this.inputFormatterType === XFormInputFormatter.StringInputFormatter ||
this.inputFormatterType ===
XFormInputFormatter.StringInputFormatterAndApplyLocale
);
}
isLocaleType() {
return (
this.inputFormatterType === XFormInputFormatter.ApplyLocale ||
this.inputFormatterType ===
XFormInputFormatter.FormatCurrencyAndApplyLocale ||
this.inputFormatterType ===
XFormInputFormatter.StringFormatterAndApplyLocale ||
this.inputFormatterType ===
XFormInputFormatter.StringInputFormatterAndApplyLocale
);
}
//#endregion
//
//#region Host Bindings ...
@HostListener('change', ['$event.target.value'])
change(value: string) {
//
const res = this.getUnformattedValue(value);
this.onChange(res);
}
@HostListener('input', ['$event.target.value'])
input(value: string) {
//
const res = this.getUnformattedValue(value);
this.onChange(res);
}
@HostListener('focus')
onFocus() {
this.onFocused();
if (this.isCurrencyType()) {
this.clearCurrencyLabel();
}
}
@HostListener('blur')
onBlur() {
this.onTouched();
if (this.isCurrencyType()) {
this.applyCurrencyLabel();
}
}
@HostListener('keydown', ['$event'])
onKeyDown(event: any) {
// if (this.isCurrencyType()) {
// this.setOnlyNumberType(event);
// }
}
//#endregion
//
//#region Implemenntation of Interface ...
writeValue(value: string): void {
this.setValue(value);
}
registerOnChange(fn: (_: string | any | null) => void): void {
this.onChange = (value) => {
//
fn(this.isCurrencyType() ? +value : value);
//
this.setValue(value);
};
}
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
//
if (isDisabled && this.isCurrencyType()) {
this.applyCurrencyLabel();
}
//
this.renderer.setProperty(
this.elementRef.nativeElement,
'disabled',
isDisabled
);
}
//#endregion
//
//#region Private ...
private isElementValid() {
return this.elementRef && this.elementRef.nativeElement;
}
private getFormattedValue(value: string) {
//
// Normallize Value ...
if (isNullOrEmptyString(value) || !this.enabledInputFormatter) {
return '';
}
//
// Prepared Formatted Value ...
let result = this.isCurrencyType()
? this.getCurrencyFormattedValue(value)
: this.isStringFormatterType()
? this.getStringFormattedValue(value)
: value || '';
//
// Apply Locale if Localeable Input Type ...
if (this.isLocaleType()) {
result = this.getLocaleFormattedValue(result);
}
//
return result;
}
private getUnformattedValue(value: string) {
//
let result = value.toString() || '';
//
const seperator = isNullOrEmptyString(this.seperator) ? '' : this.seperator;
//
// Remove All occurence of seperator ...
if (this.enabledInputFormatter) {
result = removeAll(value, seperator, true);
}
//
// Currency Lable ...
if (this.isCurrencyType() && !isNullOrEmptyString(this.currencyLable)) {
result = result.replace(this.currencyLable, '').trim();
}
//
// Change Locale to Default ...
if (this.isLocaleType()) {
result = !isNullOrEmptyString(result) ? applyLocale(result, 'en-US') : '';
}
//
return result;
}
private getNormalizedValue(value: string) {
//
if (!this.isElementValid()) {
return value;
}
//
// Normallize Value and prevent from null ...
let result = value ? value.toString() || '' : '';
result = isNullOrEmptyString(value) ? '' : this.getUnformattedValue(value);
if (!this.enabledInputFormatter) {
return result;
}
//
// Handle Apply Locale ...
if (this.inputFormatterType === XFormInputFormatter.ApplyLocale) {
//
result = applyLocale(value, this.locale || this.config.defaultLanguage);
return result;
}
//
// Handle Formatter ...
if (this.isCurrencyType() || this.isStringFormatterType()) {
return this.getFormattedValue(result);
}
//
return value;
}
private setValue(value: string, normalizeValue = true) {
//
const normalizedValue = normalizeValue
? this.getNormalizedValue(value)
: value || '';
this.renderer.setProperty(
this.elementRef.nativeElement,
'value',
normalizedValue
);
}
private getValue() {
return this.elementRef.nativeElement.value
? (this.elementRef.nativeElement.value as string)
: '';
}
private setOnlyNumberType(e: any) {
//
const keyCode = e.code as string;
const numPadKeys = [...new Array(10).keys()].map((c, i) => `Numpad${i}`);
const isValidKey =
keyCode.includes('Tab') ||
keyCode.includes('Digit') ||
keyCode.includes('Backspace') ||
numPadKeys.includes(keyCode);
//
if (!isValidKey) {
e.preventDefault();
}
}
//
//#region Formatter Actions ...
private getLocaleFormattedValue(value: any) {
//
const mValue = value ? (value.toString() as string) : '';
return applyLocale(mValue, this.locale || this.config.defaultLanguage);
}
private getStringFormattedValue(value: any) {
//
const mValue = !isNullOrUndefined(value) ? toXString(value) : '';
//
let mResultValue = '';
//
if (
this.inputFormatterType === XFormInputFormatter.StringFormatter ||
this.inputFormatterType ===
XFormInputFormatter.StringFormatterAndApplyLocale
) {
//
if (!hasChild(this.stringFormatter)) {
return mValue;
}
//
let mSource = mValue;
this.stringFormatter.forEach((l, i) => {
if (mSource.length >= l) {
//
const selected = mSource.substring(0, l);
//
mResultValue +=
i === this.stringFormatter.length
? selected
: `${selected}${this.seperator}`;
//
mSource = mSource.substr(l, mValue.length);
}
});
//
if (mSource.length > 0) {
mResultValue += `${mSource}`;
}
} else if (
this.inputFormatterType === XFormInputFormatter.StringInputFormatter ||
this.inputFormatterType ===
XFormInputFormatter.StringInputFormatterAndApplyLocale
) {
//
switch (this.stringInputFormatterType) {
//
case XStringInputFormatType.LowerCase:
mResultValue = mValue.toLowerCase();
break;
//
case XStringInputFormatType.UpperCase:
mResultValue = mValue.toUpperCase();
break;
//
case XStringInputFormatType.NonDigits:
//
mResultValue = getNonDigits(mValue);
break;
//
case XStringInputFormatType.UniqueChars:
//
mResultValue = extractUniqueChars(mValue);
break;
//
case XStringInputFormatType.NonSpace:
mResultValue = removeSpaces(mValue.trim());
break;
//
case XStringInputFormatType.OnlyDigits:
mResultValue = getDigits(mValue);
break;
//
default:
mResultValue = mValue;
break;
}
}
//
return mResultValue;
}
private getCurrencyFormattedValue(value: any) {
//
const mValue = value ? getDigits(value.toString() as string) : '';
const seperator = isNullOrEmptyString(this.seperator) ? '' : this.seperator;
const formattedValue = mValue.replace(/\B(?=(\d{3})+(?!\d))/g, seperator);
//
const result = !isNullOrEmptyString(formattedValue) ? formattedValue : '';
//
return result;
}
private applyCurrencyLabel() {
//
if (!this.isCurrencyType()) {
return;
}
//
let value = this.getValue();
//
if (
!isNullOrEmptyString(value) &&
!isNullOrEmptyString(this.currencyLable)
) {
value = `${value} ${this.currencyLable}`;
}
//
this.setValue(value, false);
}
private clearCurrencyLabel() {
//
if (!this.isCurrencyType()) {
return;
}
//
let value = this.getValue();
//
if (
!isNullOrEmptyString(value) &&
!isNullOrEmptyString(this.currencyLable)
) {
value = value.replace(this.currencyLable, '');
}
//
this.setValue(value);
}
//#endregion
//#endregion
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\directives\x-locale-input-formatter.directive.ts
import {
Input,
Inject,
Directive,
Renderer2,
ElementRef,
forwardRef,
HostListener,
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { X_FRAMEWORK_SERVICES_CONFIG } from '../tokens/x-injectable-tokens';
import { XLocale, applyLocale, isNullOrEmptyString } from 'x-framework-core';
import { XFrameworkServicesConfig } from '../config/x-framework-services.config';
export const X_LOCALE_FORMATTER: any = {
useExisting: forwardRef(() => XLocaleInputFormatterDirective),
provide: NG_VALUE_ACCESSOR,
multi: true,
};
@Directive({
// tslint:disable-next-line:directive-selector
selector: '[xLocaleInputFormatter]',
providers: [X_LOCALE_FORMATTER],
})
export class XLocaleInputFormatterDirective implements ControlValueAccessor {
//
//#region Props ...
@Input()
locale: XLocale;
@Input()
enabledLocaleFormatter: boolean;
onChange = (_: any) => {};
onTouched = () => {};
//#endregion
//
//#region Constructor ...
constructor(
private renderer: Renderer2,
private elementRef: ElementRef,
@Inject(X_FRAMEWORK_SERVICES_CONFIG)
private config: XFrameworkServicesConfig
) {}
//#endregion
//
//#region Host Bindings ...
@HostListener('change', ['$event.target.value'])
change(value: string) {
this.onChange(value);
}
@HostListener('input', ['$event.target.value'])
input(value: string) {
this.onChange(value);
}
@HostListener('blur')
onBlur() {
this.onTouched();
}
//#endregion
//
//#region Implemenntation of Interface ...
writeValue(value: string): void {
this.setValue(value);
}
registerOnChange(fn: (_: string | any | null) => void): void {
this.onChange = (value) => {
//
fn(value);
this.setValue(value);
};
}
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
this.renderer.setProperty(
this.elementRef.nativeElement,
'disabled',
isDisabled
);
}
//#endregion
//
//#region Private ...
private isElementValid() {
return this.elementRef && this.elementRef.nativeElement;
}
private getFormattedValue(value: string) {
//
if (!this.enabledLocaleFormatter || !value) {
return value || '';
}
//
value = applyLocale(value, this.locale || this.config.defaultLanguage);
//
return value;
}
private getNormalizedValue(value: string) {
//
if (!this.isElementValid()) {
return value;
}
//
value = isNullOrEmptyString(value) ? '' : this.getFormattedValue(value);
//
return value;
}
private setValue(value: string) {
//
const normalizedValue = this.getNormalizedValue(value);
this.renderer.setProperty(
this.elementRef.nativeElement,
'value',
normalizedValue
);
}
//#endregion
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\directives\x-swipable.directive.ts
import {
Input,
OnInit,
Output,
OnChanges,
Directive,
OnDestroy,
ElementRef,
EventEmitter,
SimpleChanges,
AfterViewInit,
} from '@angular/core';
import { Subject, Observable } from 'rxjs';
import { keys, nameof } from 'x-framework-core';
import { GestureController } from '@ionic/angular';
import { Gesture, GestureDetail } from '@ionic/core';
import { takeUntil, debounceTime } from 'rxjs/operators';
import { XSettingsService } from '../x-settings.service';
export enum XSwipeDirection {
UP = 'up',
DOWN = 'down',
LEFT = 'left',
START = 'start',
RIGHT = 'right',
END = 'end',
}
export type XSwipeDirectionIdentifier = XSwipeDirection | string;
export enum XSwipeSupportedDirections {
VERTICALL,
HORIZONTAL_LEFT_RIGHT,
HORIZONTAL_START_END,
ALL,
}
export interface XSwipeEvent {
deltaX: number;
deltaY: number;
direction: XSwipeDirectionIdentifier;
}
@Directive({
// tslint:disable-next-line:directive-selector
selector: '[xSwipable]',
})
export class XSwipableDirective
implements OnInit, AfterViewInit, OnDestroy, OnChanges {
//
//#region Props ...
private gesture: Gesture;
private unsubscriber = new Subject();
private issueSwipeEvents$ = new Subject<GestureDetail>();
private uiDirection = this.settingsService.uiDirection;
//#endregion
//
//#region Inputs ...
@Input()
threshold = 60;
@Input()
swipeDisabled = false;
@Input()
debounceTime = 300;
@Input()
supportedDirections: XSwipeSupportedDirections =
XSwipeSupportedDirections.HORIZONTAL_START_END;
//#endregion
//
//#region Event Emitters ...
@Output()
swipe = new EventEmitter<XSwipeEvent>();
@Output()
swipeUp = new EventEmitter();
@Output()
swipeDown = new EventEmitter();
@Output()
swipeLeft = new EventEmitter();
@Output()
swipeStart = new EventEmitter();
@Output()
swipeRight = new EventEmitter();
@Output()
swipeEnd = new EventEmitter();
//#endregion
//
//#region Constructor ...
constructor(
private elementRef: ElementRef,
private gestureCtrl: GestureController,
private settingsService: XSettingsService
) {}
//#endregion
//
//#region LifeCycles ...
ngOnInit() {
this.prepareGesture();
}
ngAfterViewInit() {
this.registerIssueSwipeHandler();
}
ngOnDestroy() {
this.destroyGesture();
this.issueSwipeEvents$.complete();
this.releaseUnsubscriber();
}
ngOnChanges(changes: SimpleChanges) {
//
const changeKesy = keys(changes);
//
const isThresholdChanged = changeKesy.includes(
nameof<XSwipableDirective>('threshold')
);
if (isThresholdChanged) {
this.prepareGesture();
}
//
const isDebounceTimeChanged = changeKesy.includes(
nameof<XSwipableDirective>('debounceTime')
);
if (isDebounceTimeChanged) {
this.registerIssueSwipeHandler();
}
}
//#endregion
//
//#region Private ...
private prepareGesture() {
//
this.destroyGesture();
//
this.gesture = this.gestureCtrl.create({
el: this.elementRef.nativeElement,
threshold: this.threshold,
gestureName: 'x-gesture',
onMove: (detail) => {
this.onMoveHandler(detail);
},
});
//
this.gesture.enable();
}
private destroyGesture() {
//
if (this.gesture) {
//
this.gesture.destroy();
this.gesture = null;
}
}
private releaseUnsubscriber() {
//
if (!this.unsubscriber.closed) {
this.unsubscriber.next();
this.unsubscriber.complete();
}
}
private applyTakeUntilWrapper<T>(task: Observable<T>): Observable<T> {
return task.pipe(takeUntil(this.unsubscriber));
}
private registerIssueSwipeHandler() {
//
this.applyTakeUntilWrapper(
this.issueSwipeEvents$
.asObservable()
.pipe(debounceTime(this.debounceTime))
).subscribe((gDetail) => {
//
if (this.swipeDisabled) {
return;
}
//
const mSwipeEvent: Partial<XSwipeEvent> = {
deltaX: gDetail.deltaX,
deltaY: gDetail.deltaY,
};
//
// Handle Vertical ...
if (
this.supportedDirections === XSwipeSupportedDirections.ALL ||
this.supportedDirections === XSwipeSupportedDirections.VERTICALL
) {
//
let swipeDir: XSwipeDirection;
//
if (gDetail.deltaY >= 0) {
//
swipeDir = XSwipeDirection.DOWN;
//
this.swipeDown.emit();
} else {
//
swipeDir = XSwipeDirection.UP;
//
this.swipeUp.emit();
}
//
// Handle Global Event ...
mSwipeEvent.direction = swipeDir;
this.swipe.emit(mSwipeEvent as XSwipeEvent);
}
//
// Handle Horizontal Left Right ...
if (
this.supportedDirections === XSwipeSupportedDirections.ALL ||
this.supportedDirections ===
XSwipeSupportedDirections.HORIZONTAL_LEFT_RIGHT
) {
//
let swipeDir: XSwipeDirection;
//
if (gDetail.deltaX >= 0) {
//
swipeDir = XSwipeDirection.RIGHT;
//
this.swipeRight.emit();
} else {
//
swipeDir = XSwipeDirection.LEFT;
//
this.swipeLeft.emit();
}
//
// Handle Global Event ...
mSwipeEvent.direction = swipeDir;
this.swipe.emit(mSwipeEvent as XSwipeEvent);
}
//
// Handle Horizontal Start End ...
if (
this.supportedDirections === XSwipeSupportedDirections.ALL ||
this.supportedDirections ===
XSwipeSupportedDirections.HORIZONTAL_START_END
) {
//
let swipeDir: XSwipeDirection;
//
if (gDetail.deltaX >= 0) {
//
if (this.uiDirection === 'ltr') {
//
swipeDir = XSwipeDirection.END;
//
this.swipeEnd.emit();
} else {
//
swipeDir = XSwipeDirection.START;
//
this.swipeStart.emit();
}
} else {
//
if (this.uiDirection === 'ltr') {
//
swipeDir = XSwipeDirection.START;
//
this.swipeStart.emit();
} else {
//
swipeDir = XSwipeDirection.END;
//
this.swipeEnd.emit();
}
}
//
// Handle Global Event ...
mSwipeEvent.direction = swipeDir;
this.swipe.emit(mSwipeEvent as XSwipeEvent);
}
});
}
private onMoveHandler(ev: GestureDetail) {
//
if (this.swipeDisabled) {
return;
}
//
this.issueSwipeEvents$.next(ev);
}
//#endregion
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\modules\x-directives.module.ts
import { NgModule } from '@angular/core';
import { IonicModule } from '@ionic/angular';
import { CommonModule } from '@angular/common';
import { XTranslatePipe } from '../pipes/x-translate.pipe';
import { XSwipableDirective } from '../directives/x-swipable.directive';
import { XDatePresenterDirective } from '../directives/x-date-presenter.directive';
import { XCurrencyFormatterDirective } from '../directives/x-currency-formatter.directive';
import { XFromInputFormatterDirective } from '../directives/x-from-input-formatter.directive';
import { XLocaleInputFormatterDirective } from '../directives/x-locale-input-formatter.directive';
@NgModule({
declarations: [
//
// Pipes ...
XTranslatePipe,
//
// Directives
XSwipableDirective,
XDatePresenterDirective,
XCurrencyFormatterDirective,
XFromInputFormatterDirective,
XLocaleInputFormatterDirective
],
imports: [CommonModule, IonicModule],
exports: [
//
CommonModule,
IonicModule,
//
// Pipes ...
XTranslatePipe,
//
// Directives
XSwipableDirective,
XDatePresenterDirective,
XCurrencyFormatterDirective,
XFromInputFormatterDirective,
XLocaleInputFormatterDirective
]
})
export class XDirectivesModule {}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\pipes\x-translate.pipe.ts
import {
XLocale,
toNumber,
isString,
XResourceIDs,
XTranslationItem
} from 'x-framework-core';
import { Pipe, PipeTransform } from '@angular/core';
import { XLocalizationService } from '../x-localization.service';
@Pipe({
name: 'xTranslate'
})
export class XTranslatePipe implements PipeTransform {
//
constructor(private localizationService: XLocalizationService) {}
/**
* translate a resource to specific language in a pipe
*
* @param key the resource identifier
* @param locale the selected or default locale
*/
transform(
key: XResourceIDs | XTranslationItem | string,
locale?: XLocale
): string {
//
if (!locale) {
locale = this.localizationService.locale;
}
//
const isStringKey = isString(key);
if (!isStringKey) {
key = toNumber(key) as XResourceIDs;
}
//
const isExist = isStringKey
? this.localizationService.isExistsIdOfLocale(locale, key as string)
: this.localizationService.isExistsIdOfLocale(
locale,
key as XResourceIDs
);
if (!isExist) {
return '';
}
//
return isStringKey
? this.localizationService.getValueOfLocale(locale, key as string)
: this.localizationService.getValueOfLocale(locale, key as XResourceIDs);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\tokens\x-injectable-tokens.ts
import { InjectionToken } from '@angular/core';
import { XFrameworkServicesConfig } from '../config/x-framework-services.config';
export const X_FRAMEWORK_SERVICES_CONFIG = new InjectionToken<
XFrameworkServicesConfig
>('x_config');
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-manager-service-partial\x-manager-base.service.ts
import { Location } from '@angular/common';
import { XBaseService } from 'x-framework-core';
import { Platform } from '@angular/cdk/platform';
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { XDialogService } from '../x-dialog.service';
import { XHistoryService } from '../x-history.service';
import { XStorageService } from '../x-storage.service';
import { XSecurityService } from '../x-security.service';
import { Router, ActivatedRoute } from '@angular/router';
import { XSettingsService } from '../x-settings.service';
import { MenuController, NavController } from '@ionic/angular';
import { XGeolocationService } from '../x-geolocation.service';
import { XTaskManagerService } from '../x-task-manager.service';
import { XNotificationService } from '../x-notification.service';
import { XLocalizationService } from '../x-localization.service';
import { XThemeManagerService } from '../x-theme-manager.service';
import { XSecureStorageService } from '../x-secure-storage.service';
import { X_FRAMEWORK_SERVICES_CONFIG } from '../tokens/x-injectable-tokens';
import { XFrameworkServicesConfig } from '../config/x-framework-services.config';
@Injectable()
export abstract class XManagerBaseService extends XBaseService {
constructor(
@Inject(X_FRAMEWORK_SERVICES_CONFIG)
public config: XFrameworkServicesConfig,
public router: Router,
public platform: Platform,
public location: Location,
public httpClient: HttpClient,
public dialogService: XDialogService,
public menuController: MenuController,
public activatedRoute: ActivatedRoute,
public historyService: XHistoryService,
public storageService: XStorageService,
public securityService: XSecurityService,
public settingsService: XSettingsService,
public navigationController: NavController,
public geoLocationService: XGeolocationService,
public taskManagerService: XTaskManagerService,
public themeManagerService: XThemeManagerService,
public notificationService: XNotificationService,
public localizationService: XLocalizationService,
public secureStorageService: XSecureStorageService
) {
super(config);
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-manager-service-partial\x-manager-final.service.ts
import { XManagerRouteService } from './x-manager-route.service';
export abstract class XManagerFinalService extends XManagerRouteService {}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-manager-service-partial\x-manager-route.service.ts
import {
keys,
XPage,
toArray,
fromJson,
hasChild,
XRouterTarget,
XOneOrManyType,
XParamIdentifier,
isNullOrEmptyString,
} from 'x-framework-core';
import { XManagerUIStateService } from './x-manager-ui-state.service';
import { Params, UrlTree, ParamMap, NavigationExtras } from '@angular/router';
export abstract class XManagerRouteService extends XManagerUIStateService {
//
//#region Props ...
//
public routeDataChanged$ = this.router.routerState.root.data;
public routeParmChanged$ = this.router.routerState.root.params;
public routeQueryParmChanged$ = this.router.routerState.root.queryParams;
//#endregion
//
//#region Route Related Actions ...
/**
* some times we had to force change location ...
*
* @param route the specified route
*/
changeLocation(route?: string) {
window.location.href = this.getFullUrl(route);
}
/**
* retrieve base url (Origin) address
*/
getBaseUrl() {
return window.location.origin;
}
/**
* retrieve current route
*/
getRoute() {
return this.router && this.router.url ? this.router.url : '/';
}
/**
* merge several parts of a url ...
*
* @param route an instance of url tree array ...
*/
mergeRoutes(route: XOneOrManyType<string>) {
//
if (!hasChild(route)) {
return '/';
}
//
try {
return toArray(route).join('/').replace('//', '/');
} catch {}
//
return '/';
}
/**
* retrieve page route ...
*
* @param page an instance of XPage ...
*/
getPageRoute(page: XPage) {
//
if (!page || !hasChild(page.route)) {
return null;
}
//
return this.mergeRoutes(page.route);
}
/**
* generate and retrieve the fully qualified URL address of
* specified route
*
* @param route the selected app route
*/
getFullUrl(route?: string) {
//
const mBase = this.getBaseUrl().endsWith('/')
? this.getBaseUrl()
: `${this.getBaseUrl()}/`;
const mRoute = !route
? ''
: !route.startsWith('/')
? route
: route.substring(1);
//
return `${mBase}${mRoute}`;
}
/**
* navigate to specific location ...
*
* @param commands url or url tree parts which required to navigate
* @param extras the navigation params or options
*/
navigate(commands: any[], extras?: NavigationExtras) {
return this.router.navigate(commands, extras);
}
/**
* navigate to specific location ...
*
* @param commands url or url tree parts which required to navigate
* @param extras the navigation params or options
* @param replaceUrl determines the url replaced or not
*/
navigateReplace(
commands: any[],
extras?: NavigationExtras,
replaceUrl: boolean = true
) {
return this.router.navigate(commands, { ...extras, replaceUrl });
}
/**
* navigate to specific location by it's url ...
*
* @param url specific url address for navigating
* @param extras the navigation params or options
*/
navigateByUrl(url: string | UrlTree, extras?: NavigationExtras) {
return this.router.navigate([url], extras);
}
/**
* navigate to specific location by it's url ...
*
* @param url specific url address for navigating
* @param extras the navigation params or options
* @param replaceUrl determines the url replaced or not
*/
navigateByUrlReplace(
url: string | UrlTree,
extras?: NavigationExtras,
replaceUrl: boolean = true
) {
return this.router.navigate([url], { ...extras, replaceUrl });
}
/**
* navigate to Specific Page ...
*
* @param page an instance of XPage
* @param extras the navigation params or options
*/
navigateByPage(page: XPage, extras?: NavigationExtras) {
//
const route = this.getPageRoute(page);
if (isNullOrEmptyString(route)) {
return false;
}
//
return this.navigateByUrl(route, extras);
}
/**
* navigate to Specific Page ...
*
* @param page an instance of XPage
* @param extras the navigation params or options
* @param replaceUrl determines the url replaced or not
*/
navigateByPageReplace(
page: XPage,
extras?: NavigationExtras,
replaceUrl: boolean = true
) {
//
const route = this.getPageRoute(page);
if (isNullOrEmptyString(route)) {
return false;
}
//
return this.navigateByUrl(route, { ...extras, replaceUrl });
}
/**
* Applies an array of commands to the current URL tree and creates a new URL tree.
*
* When given an activated route, applies the given commands starting from the route.
* Otherwise, applies the given command starting from the root.
*
* @param commands An array of commands to apply.
* @param navigationExtras Options that control the navigation strategy.
* @returns The new URL tree.
*/
createUrlTree(commands: any[], navigationExtras?: NavigationExtras): UrlTree {
return this.router.createUrlTree(commands, navigationExtras);
}
/** Serializes a `UrlTree` into a string */
serializeUrl(url: UrlTree): string {
return this.router.serializeUrl(url);
}
/** Parses a string into a `UrlTree` */
parseUrl(url: string): UrlTree {
return this.router.parseUrl(url);
}
/** Returns whether the url is activated */
isActive(url: string | UrlTree, exact: boolean): boolean {
return this.router.isActive(url, exact);
}
/**
* open specifc url ...
*
* @param url URL address
* @param target link taget
*/
openUrl(url: string, target: XRouterTarget = XRouterTarget.BLANK) {
//
if (isNullOrEmptyString(url)) {
return;
}
//
const link = document.createElement('a');
link.target = target;
link.href = url;
//
link.click();
link.remove();
}
//#endregion
//
//#region Handling Query Param actions ...
/**
* change page Query Params ...
* @param params Query Parameters
*/
changeQueryParams(params: Params) {
//
return this.router.navigate([], {
relativeTo: this.activatedRoute,
queryParams: params,
queryParamsHandling: 'merge',
});
}
clearQueryParams() {
//
return this.router.navigate([], {
relativeTo: this.activatedRoute,
queryParams: {},
});
}
/**
* Get CurrentPages Query Params ...
*/
getQueryParams(): Params {
return this.router.routerState.snapshot.root.queryParams;
}
getQueryParamMap(): ParamMap {
return this.router.routerState.snapshot.root.queryParamMap;
}
isContainQueryParam(param: XParamIdentifier) {
return this.getQueryParamMap().has(param);
}
getQueryParamVal(param: XParamIdentifier) {
//
if (!this.isContainQueryParam(param)) {
return null;
}
//
return this.getQueryParamMap().get(param);
}
getQueryParamValOfType<T>(param: XParamIdentifier) {
//
if (!this.isContainQueryParam(param)) {
return null;
}
//
return fromJson<T>(this.getQueryParamMap().get(param));
}
//#endregion
//
//#region Handling Param actions ...
/**
* Get CurrentPages Query Params ...
*/
getParams(): Params {
return this.router.routerState.snapshot.root.params;
}
getParamMap(): Params {
return this.router.routerState.snapshot.root.paramMap;
}
isContainParam(param: XParamIdentifier) {
return this.getParamMap().has(param);
}
changeParam(params: Params) {
//
return this.router.navigate(['', params], {
relativeTo: this.activatedRoute,
replaceUrl: true,
});
}
getParamVal(param: XParamIdentifier) {
//
if (!this.isContainParam(param)) {
return null;
}
//
return this.getParamMap().get(param);
}
getParamValOfType<T>(param: XParamIdentifier) {
//
if (!this.isContainParam(param)) {
return null;
}
//
return fromJson<T>(this.getParamMap().get(param));
}
//#endregion
//
//#region State Handling ...
/**
* change page state ...
* @param params State Parameters
*/
changeState(params: Params) {
//
return this.router.navigate([], {
relativeTo: this.activatedRoute,
replaceUrl: true,
state: params,
});
}
getStates(): Params {
return this.router.getCurrentNavigation().extras.state || {};
}
isContainState(param: XParamIdentifier) {
//
const paramKeys = keys(this.getStates());
const result = paramKeys.includes(param);
//
return result;
}
getStateVal(param: XParamIdentifier) {
//
if (!this.isContainState(param)) {
return null;
}
//
return this.getStates()[param] || null;
}
getStateValOfType<T>(param: XParamIdentifier) {
//
if (!this.isContainState(param)) {
return null;
}
//
return fromJson<T>(this.getStateVal(param)) || null;
}
//#endregion
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xFrameworkServicesHolder\projects\x-framework-services\src\lib\x-manager-service-partial\x-manager-ui-state.service.ts
import {
XLocale,
XUiEvent,
notValue,
XException,
XLanguageDirection,
isNullOrEmptyString,
} from 'x-framework-core';
import { Subject, of } from 'rxjs';
import { filter, concatMap } from 'rxjs/operators';
import { XManagerBaseService } from './x-manager-base.service';
export abstract class XManagerUIStateService extends XManagerBaseService {
//
//#region props ...
private IS_LOADING: boolean;
private UI_DISABLED: boolean;
private ERROR: XException = null;
//
public uiStateChanged = new Subject<XUiEvent>();
//
public isMobileUi$ = this.settingsService.isMobile$;
public isNotMobileUi$ = notValue(this.settingsService.isMobile$);
//
public isLoading$ = this.uiStateChanged.asObservable().pipe(
filter((uiState) =>
[XUiEvent.StartLoading, XUiEvent.StopLoading].includes(uiState)
),
concatMap((state) => {
return of(state === XUiEvent.StartLoading ? true : false);
})
);
//#endregion
//
//#region Getter(s) ...
set uiDisabled(v: boolean) {
//
if (v === this.UI_DISABLED) {
return;
}
this.UI_DISABLED = v;
this.uiStateChanged.next(v ? XUiEvent.Disabled : XUiEvent.Enabled);
}
//
get uiDisabled() {
return this.UI_DISABLED;
}
//
set loading(v: boolean) {
//
if (v === this.IS_LOADING) {
return;
}
//
this.IS_LOADING = v;
this.uiStateChanged.next(v ? XUiEvent.StartLoading : XUiEvent.StopLoading);
}
//
get isLoading() {
return this.IS_LOADING;
}
//
set error(exception: XException | null) {
//
if (exception === this.ERROR) {
return;
}
//
this.ERROR = exception;
//
if (exception) {
//
if (this.loading) {
this.loading = false;
}
//
this.uiDisabled = true;
} else {
//
this.uiDisabled = false;
}
}
//
get error() {
return this.ERROR;
}
//
get hasError() {
return !!this.ERROR;
}
//
get uiDirection(): XLanguageDirection {
return this.settingsService.uiDirection;
}
//
get currentLanguage() {
return this.localizationService.language;
}
//
get currentLocale(): XLocale {
return this.localizationService.locale;
}
//
get isRtl() {
return this.settingsService.uiDirection === 'rtl';
}
//
get isLtr() {
return this.settingsService.uiDirection === 'ltr';
}
//#endregion
//
//#region UI Actions ...
//
public dispatchResizeEvent() {
//
window.dispatchEvent(new Event('resize'));
setTimeout(() => window.dispatchEvent(new Event('resize')), 500);
}
/**
* save a text value to clipboard ...
*
* @param value the content which reuired to save to clipboard ...
*/
public saveToClipboard(value: string) {
//
if (isNullOrEmptyString(value)) {
return false;
}
//
if (
document.queryCommandSupported &&
document.queryCommandSupported('copy')
) {
//
const textarea = document.createElement('textarea');
textarea.textContent = value;
// Prevent scrolling to bottom of page in Microsoft Edge.
textarea.style.position = 'fixed';
document.body.appendChild(textarea);
textarea.select();
//
try {
// Security exception may be thrown by some browsers.
return document.execCommand('copy');
} catch (ex) {
return false;
} finally {
document.body.removeChild(textarea);
}
}
//
return false;
}
//#endregion
//
//#region Private ...
//#endregion
}