UNPKG

coersystem

Version:

Library for Angular projects

1,049 lines (1,037 loc) 104 kB
import * as i0 from '@angular/core'; import { signal, Component, forwardRef, inject, Inject, input, output } from '@angular/core'; import { colorsSIGNAL, navigationSIGNAL } from 'coersystem/signals'; import * as bootstrap from 'bootstrap'; import Swal from 'sweetalert2'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import * as XLSX from 'xlsx'; import { Router, ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs'; import { HttpClient, HttpRequest } from '@angular/common/http'; import { saveAs } from 'file-saver'; /** Provides several methods for string manipulation */ class Numbers { /** Validates if the value is a numeric type */ static IsNumber(value) { return typeof value === 'number' && !Number.isNaN(Number(value)); } /** Validates if the value isn't a numeric type */ static IsNotNumber(value) { return !this.IsNumber(value); } /** */ static SetDecimals(value, decimals = 2) { if (typeof value === 'string') value = Number(value); if (this.IsNotNumber(value)) return '0'; let valueInteger = ''; let valueDecimal = ''; value = String(value); if (value.includes('.') || (decimals > 0)) { valueInteger = value.includes('.') ? value.split('.')[0] : value; if (decimals > 0) { valueDecimal = value.includes('.') ? value.split('.')[1] : ''; for (let i = 0; i < decimals; i++) valueDecimal += '0'; valueDecimal = valueDecimal.substring(0, decimals); valueDecimal = `.${valueDecimal}`; } } else { valueInteger = value; } return `${valueInteger}${valueDecimal}`; } /** Return a string with numeric format */ static GetNumericFormat(value, decimals = 0) { const [INTEGER, DECIMAL = ''] = this.SetDecimals(value).split('.'); return decimals > 0 ? `${INTEGER.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}.${DECIMAL}` : INTEGER.replace(/\B(?=(\d{3})+(?!\d))/g, ','); } /** Return a string with currency format */ static GetCurrencyFormat(value, symbol = '$', currency = '') { return `${symbol}${this.GetNumericFormat(value, 2)}${currency.length > 0 ? ` ${currency}` : ''}`; } } const reference_signal = signal({}); /** Generic Methods */ const Tools = { /** Generates a guid */ GetGuid: (seed = 'coer-system') => { let time = new Date().getTime(); seed = seed.toString().trim(); return seed + `-xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g, (c) => { const random = (time + Math.random() * 16) % 16 | 0; time = Math.floor(time / 16); return (c == 'x' ? random : (random & 0x3 | 0x8)).toString(16); }); }, /** Returns true if the value is null or undefined, false otherwise */ IsNull: (value) => { return (value === undefined || value === null); }, /** Returns true if the value is not null or undefined, false otherwise */ IsNotNull: (value) => { return !Tools.IsNull(value); }, /** Returns true if the value is null or undefined or is an empty string or contains only whitespace, false otherwise */ IsOnlyWhiteSpace: (value) => { return Tools.IsNull(value) || (typeof value === 'string' && value.trim() === ''); }, /** Returns true if it has a string value and is not all whitespace, false otherwise */ IsNotOnlyWhiteSpace: (value) => { return Tools.IsNotNull(value) && !Tools.IsOnlyWhiteSpace(value); }, /** Avoids null value and responds with the specified type */ AvoidNull: (value, type = 'string') => { if (Tools.IsNull(value)) { return (type === 'string' ? '' : type === 'number' ? 0 : false); } else if (typeof value === 'string') { if (type === 'string') return value; if (type === 'number') return (Numbers.IsNumber(Number(value)) ? Number(value) : 0); if (type === 'boolean') return (Numbers.IsNumber(Number(value)) ? Number(value) > 0 : (value.toLowerCase().trim() === 'true')); } else if (typeof value === 'number') { if (type === 'string') return String(value); if (type === 'number') return value; if (type === 'boolean') return (value > 0); } else if (typeof value === "boolean") { if (type === 'string') return (value ? 'true' : 'false'); if (type === 'number') return (value ? 1 : 0); if (type === 'boolean') return value; } return (type === 'string' ? '' : type === 'number' ? 0 : false); }, /** Break reference of a object or array */ BreakReference: (object) => { if (Tools.IsNull(object) || ['string', 'number', 'boolean'].includes(typeof object)) return object; return JSON.parse(JSON.stringify(object)); }, /** Get properties of an object */ GetPropertyList: (object) => { return Tools.IsNotNull(object) && typeof object === 'object' ? Object.keys(object) : []; }, /** */ HasProperty: (object, property) => { return typeof object === 'object' && object.hasOwnProperty(property); }, /** */ IsBoolean: (object, property = '') => { return Tools.IsOnlyWhiteSpace(property) ? typeof object === 'boolean' : Tools.IsNotNull(object) && object.hasOwnProperty(property) && (typeof object[property] === 'boolean'); }, /** */ IsBooleanTrue: (object, property = '') => { return Tools.IsOnlyWhiteSpace(property) ? typeof object === 'boolean' && object === true : Tools.IsNotNull(object) && object.hasOwnProperty(property) && (typeof object[property] === 'boolean') && object[property] === true; }, /** */ IsBooleanFalse: (object, property = '') => { return Tools.IsOnlyWhiteSpace(property) ? typeof object === 'boolean' && object === false : Tools.IsNotNull(object) && object.hasOwnProperty(property) && (typeof object[property] === 'boolean') && object[property] === false; }, /** */ IsString: (object, property = '') => { return Tools.IsOnlyWhiteSpace(property) ? typeof object === 'string' : Tools.IsNotNull(object) && object.hasOwnProperty(property) && (typeof object[property] === 'string'); }, /** */ IsFunction: (object, property = '') => { return Tools.IsOnlyWhiteSpace(property) ? typeof object === 'function' : Tools.IsNotNull(object) && object.hasOwnProperty(property) && (typeof object[property] === 'function'); }, /** Wait the time indicated */ Sleep: (milliseconds = 0, reference = null) => { if (Tools.IsNull(reference)) { return new Promise(Resolve => setTimeout(Resolve, milliseconds)); } else return new Promise(Resolve => { reference = reference.replaceAll(' ', '_').toLowerCase(); if (reference_signal().hasOwnProperty(reference)) { clearInterval(reference_signal()[reference]); } reference_signal.set(Object.assign(reference_signal(), { [reference]: setTimeout(() => { Resolve(); clearInterval(reference_signal()[reference]); const _reference = { ...reference_signal() }; delete _reference[reference]; reference_signal.set({ ..._reference }); }, milliseconds) })); }); }, /** Send text to the computer's clipboard */ Clipboard: (text, message = '', title = 'Copied') => { try { navigator.clipboard.writeText(text.trim()).then(() => { new CoerAlert().Info(message, title, 'bi bi-clipboard-fill'); }); } catch { new CoerAlert().Warning('Unable to copy to clipboard', 'Quick Implement', 'bi bi-clipboard-fill'); } } }; /** class to work with colors */ class Colors { /** Provides the fixed colors set by the coersystem library */ static get fixedColors() { return { blue: colorsSIGNAL().fixedColors.blue, gray: colorsSIGNAL().fixedColors.gray, green: colorsSIGNAL().fixedColors.green, yellow: colorsSIGNAL().fixedColors.yellow, red: colorsSIGNAL().fixedColors.red, smoke: colorsSIGNAL().fixedColors.smoke, black: colorsSIGNAL().fixedColors.black, orange: colorsSIGNAL().fixedColors.orange, white: colorsSIGNAL().fixedColors.white, purple: colorsSIGNAL().fixedColors.purple }; } /** Provides the action colors set in the application */ static get actionColors() { return { primary: colorsSIGNAL().actionColors.primary, secondary: colorsSIGNAL().actionColors.secondary, success: colorsSIGNAL().actionColors.success, warning: colorsSIGNAL().actionColors.warning, danger: colorsSIGNAL().actionColors.danger, navigation: colorsSIGNAL().actionColors.navigation, information: colorsSIGNAL().actionColors.information }; } /** Provides the colors of the application */ static get appColors() { return { breadcrumbs: colorsSIGNAL().appColors.breadcrumbs, background: colorsSIGNAL().appColors.background, containers: colorsSIGNAL().appColors.containers, sidenav: colorsSIGNAL().appColors.sidenav, sidenavText: colorsSIGNAL().appColors.sidenavText, sidenavActive: colorsSIGNAL().appColors.sidenavActive, toolbar: colorsSIGNAL().appColors.toolbar, toolbarText: colorsSIGNAL().appColors.toolbarText }; } /** Get Hexadecimal color */ static ToHexadecimal(red, green, blue, alpha) { const _red = `${Number(red).toString(16).padStart(2, '0')}`; const _green = `${Number(green).toString(16).padStart(2, '0')}`; const _blue = `${Number(blue).toString(16).padStart(2, '0')}`; const _alpha = (Tools.IsNotNull(alpha)) ? Math.round(Number(alpha) * 255).toString(16).padStart(2, '0') : ''; return `#${_red}${_green}${_blue}${_alpha}`.toLowerCase(); } /** Returns a random color in hexadecimal public static GetRandomColorHex = (): string => "#xxxxxx".replace(/x/g, () => (Math.random() * 16 | 0).toString(16)); */ /** Returns the number of colors requested */ static GetColorList(quantity) { const colors = []; let counter = 0; while (counter < quantity) { for (const color in this.fixedColors) { colors.push(color); if (++counter === quantity) break; } } return colors; } } class CoerAlert { /** Use this alert to issue a success message */ Success(message = null, title = null, icon = null, autohide = 3000) { //Title if (Tools.IsOnlyWhiteSpace(title)) title = 'Success'; const alertSuccessTitle = document.getElementById('alert-success-title'); alertSuccessTitle.textContent = title; //Icon icon = Tools.IsOnlyWhiteSpace(icon) ? 'bi-check-circle fa-beat' : icon; const alertSuccessIcon = document.getElementById('alert-success-icon'); this._SetIcon(alertSuccessIcon, icon); //Message if (Tools.IsNull(message)) message = ''; const alertSuccessMessage = document.getElementById('alert-success-message'); alertSuccessMessage.innerHTML = message; //Toast const alertSuccess = document.getElementById('alert-success'); this._SetAutoHide(alertSuccess, autohide); const toast = bootstrap.Toast.getOrCreateInstance(alertSuccess); toast.show(); } /** Use this alert to issue a error or danger */ Error(message = null, title = null, icon = null, autohide = 3000) { //Title if (Tools.IsOnlyWhiteSpace(title)) title = 'Error'; const alertErrorTitle = document.getElementById('alert-error-title'); alertErrorTitle.textContent = title; //Icon icon = Tools.IsOnlyWhiteSpace(icon) ? 'bi-exclamation-octagon fa-beat' : icon; const alertErrorIcon = document.getElementById('alert-error-icon'); this._SetIcon(alertErrorIcon, icon); //Message if (Tools.IsNull(message)) message = ''; const alertErrorBody = document.getElementById('alert-error-message'); alertErrorBody.innerHTML = message; //Toast const alertError = document.getElementById('alert-error'); this._SetAutoHide(alertError, autohide); const toast = bootstrap.Toast.getOrCreateInstance(alertError); toast.show(); } /** Use this alert to broadcast an informational message */ Info(message = null, title = null, icon = null, autohide = 3000) { //Title if (Tools.IsOnlyWhiteSpace(title)) title = 'Info'; const alertInfoTitle = document.getElementById('alert-info-title'); alertInfoTitle.textContent = title; //Icon icon = Tools.IsOnlyWhiteSpace(icon) ? 'circle-info fa-beat' : icon; const alertInfoIcon = document.getElementById('alert-info-icon'); this._SetIcon(alertInfoIcon, icon); //Message if (Tools.IsNull(message)) message = ''; const alertInfoBody = document.getElementById('alert-info-message'); alertInfoBody.innerHTML = message; //Toast const alertInfo = document.getElementById('alert-info'); this._SetAutoHide(alertInfo, autohide); const toast = bootstrap.Toast.getOrCreateInstance(alertInfo); toast.show(); } /** Use this alert to issue a warning message */ Warning(message = null, title = null, icon = null, autohide = 3000) { //Title if (Tools.IsOnlyWhiteSpace(title)) title = 'Warning'; const alertWarningTitle = document.getElementById('alert-warning-title'); alertWarningTitle.textContent = title; //Icon icon = Tools.IsOnlyWhiteSpace(icon) ? 'bi-exclamation-triangle-fill fa-beat' : icon; const alertWarningIcon = document.getElementById('alert-warning-icon'); this._SetIcon(alertWarningIcon, icon); //Message if (Tools.IsNull(message)) message = ''; const alertWarningBody = document.getElementById('alert-warning-message'); alertWarningBody.innerHTML = message; //Toast const alertWarning = document.getElementById('alert-warning'); this._SetAutoHide(alertWarning, autohide); const toast = bootstrap.Toast.getOrCreateInstance(alertWarning); toast.show(); } /** Use this alert to confirm a user action */ Confirm(message = 'Proceed?', alertType = 'warning', icon = null) { return new Promise(Resolve => { let color; let iconType; switch (alertType) { case 'danger': { if (Tools.IsNull(icon)) icon = 'bi-exclamation-octagon'; iconType = 'error'; color = Colors.actionColors.danger; break; } ; case 'success': { if (Tools.IsNull(icon)) icon = 'bi-check-circle'; iconType = 'info'; color = Colors.actionColors.success; break; } ; case 'info': { if (Tools.IsNull(icon)) icon = 'icon-circle-info'; iconType = 'error'; color = Colors.actionColors.information; break; } ; default: { if (Tools.IsNull(icon)) icon = 'bi-exclamation-triangle-fill'; iconType = 'warning'; color = Colors.actionColors.warning; break; } } switch (icon) { case 'delete': icon = 'fa-regular fa-trash-can'; break; } Swal.fire({ icon: iconType, iconColor: 'transparent', iconHtml: `<i class="${icon}" style="color: ${color};"></i>`, html: message, showConfirmButton: true, confirmButtonText: 'Yes', confirmButtonColor: color, focusConfirm: true, showDenyButton: true, denyButtonColor: color, focusDeny: false, reverseButtons: true, allowOutsideClick: false, allowEscapeKey: false, allowEnterKey: true, customClass: { denyButton: 'sweet-alert-button', confirmButton: 'sweet-alert-button' } }).then(({ value }) => setTimeout(() => Resolve(value))); }); } /** */ _Close(alert) { return new Promise(Resolve => { const element = document.getElementById(alert); const toast = bootstrap.Toast.getOrCreateInstance(element); toast.hide(); setTimeout(() => { Resolve(); }, 200); }); } /** */ _SetIcon(element, icon) { if (icon.toUpperCase() != 'NONE') { for (const item of [...element.classList.value.split(' ')]) { if (item.length > 0) { element.classList.remove(item); element.classList.remove('q'); } } icon = icon.trim(); const hasWhiteSpaces = / /; if (hasWhiteSpaces.test(icon)) { const classes = icon.split(' '); for (const icon of classes) element.classList.add(icon); } else element.classList.add(icon); } } /** */ _SetAutoHide(element, autohide) { element.removeAttribute('data-bs-autohide'); element.removeAttribute('data-bs-delay'); if (autohide && autohide > 0) { if (autohide < 1000) autohide = 1000; element.setAttribute('data-bs-autohide', 'true'); element.setAttribute('data-bs-delay', String(autohide)); } else element.setAttribute('data-bs-autohide', 'false'); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: CoerAlert, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.1", type: CoerAlert, isStandalone: true, selector: "coer-alert", ngImport: i0, template: "<aside class=\"toast-container coer-alert\">\r\n <!-- Success -->\r\n <div id=\"alert-success\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"toast\">\r\n <div class=\"toast-header\">\r\n <i id=\"alert-success-icon\"></i>\r\n <strong id=\"alert-success-title\"></strong>\r\n <button type=\"button\" (click)=\"_Close('alert-success')\" class=\"btn-close btn-close-white\"></button>\r\n </div>\r\n\r\n <div class=\"toast-body\">\r\n <pre id=\"alert-success-message\"></pre>\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Error -->\r\n <div id=\"alert-error\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"toast\">\r\n <div class=\"toast-header\">\r\n <i id=\"alert-error-icon\"></i>\r\n <strong id=\"alert-error-title\"></strong>\r\n <button type=\"button\" (click)=\"_Close('alert-error')\" class=\"btn-close btn-close-white\"></button>\r\n </div>\r\n\r\n <div class=\"toast-body\">\r\n <pre id=\"alert-error-message\"></pre>\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Info -->\r\n <div id=\"alert-info\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"toast\">\r\n <div class=\"toast-header\">\r\n <i id=\"alert-info-icon\"></i>\r\n <strong id=\"alert-info-title\"></strong>\r\n <button type=\"button\" (click)=\"_Close('alert-info')\" class=\"btn-close btn-close-white\"></button>\r\n </div>\r\n\r\n <div class=\"toast-body\">\r\n <pre id=\"alert-info-message\"></pre>\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Warning -->\r\n <div id=\"alert-warning\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"toast\">\r\n <div class=\"toast-header\">\r\n <i id=\"alert-warning-icon\"></i>\r\n <strong id=\"alert-warning-title\"></strong>\r\n <button type=\"button\" (click)=\"_Close('alert-warning')\" class=\"btn-close\"></button>\r\n </div>\r\n\r\n <div class=\"toast-body\">\r\n <pre id=\"alert-warning-message\"></pre>\r\n </div>\r\n </div>\r\n</aside>", styles: ["aside.toast-container{position:fixed;bottom:0;right:0;padding:15px!important;z-index:2000!important}aside.toast-container i,aside.toast-container svg{display:flex;align-items:center}aside.toast-container strong{margin:0 auto 0 5px}aside.toast-container div.toast,aside.toast-container div.toast-header{border-top-left-radius:10px;border-top-right-radius:10px;color:var(--smoke)}aside.toast-container div.toast,aside.toast-container div.toast-body{border-bottom-left-radius:10px;border-bottom-right-radius:10px;width:auto!important;min-width:350px!important;max-width:470px!important;color:var(--smoke)}@media (min-width: 0) and (max-width: 499px){aside.toast-container div.toast,aside.toast-container div.toast-body{min-width:calc(100vw - 30px)!important}}aside.toast-container div.toast-body{min-height:36px}aside.toast-container pre{font-family:Roboto,RobotoFallback,Noto Kufi Arabic,Helvetica,Arial,sans-serif;white-space:pre-wrap;font-size:medium}aside.toast-container button{margin:0 2px!important;width:10px!important;height:10px!important;box-shadow:none!important;outline:none!important;border:none!important}aside.toast-container div#alert-success div.toast-header,aside.toast-container div#alert-success div.toast-body{background-color:var(--success-inner)}aside.toast-container div#alert-info div.toast-header,aside.toast-container div#alert-info div.toast-body{background-color:var(--information-inner)}aside.toast-container div#alert-error div.toast-header,aside.toast-container div#alert-error div.toast-body{background-color:var(--danger-inner)}aside.toast-container div#alert-warning div.toast-header,aside.toast-container div#alert-warning div.toast-body{background-color:var(--warning-inner);border-color:var(--black);color:var(--black)}aside.toast-container div#alert-success:hover,aside.toast-container div#alert-info:hover,aside.toast-container div#alert-error:hover,aside.toast-container div#alert-warning:hover{transform:scale(1.01);box-shadow:2px 2px 10px #789;cursor:default}button.sweet-alert-button{width:100px!important;height:40px!important;display:flex!important;align-items:center!important;justify-content:center!important;margin:0 5px!important;outline:none!important;border:none!important;box-shadow:none!important}aside.toast-container>*{border:none!important;z-index:2000!important;margin:15px 0 0!important}\n"] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: CoerAlert, decorators: [{ type: Component, args: [{ selector: 'coer-alert', standalone: true, template: "<aside class=\"toast-container coer-alert\">\r\n <!-- Success -->\r\n <div id=\"alert-success\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"toast\">\r\n <div class=\"toast-header\">\r\n <i id=\"alert-success-icon\"></i>\r\n <strong id=\"alert-success-title\"></strong>\r\n <button type=\"button\" (click)=\"_Close('alert-success')\" class=\"btn-close btn-close-white\"></button>\r\n </div>\r\n\r\n <div class=\"toast-body\">\r\n <pre id=\"alert-success-message\"></pre>\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Error -->\r\n <div id=\"alert-error\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"toast\">\r\n <div class=\"toast-header\">\r\n <i id=\"alert-error-icon\"></i>\r\n <strong id=\"alert-error-title\"></strong>\r\n <button type=\"button\" (click)=\"_Close('alert-error')\" class=\"btn-close btn-close-white\"></button>\r\n </div>\r\n\r\n <div class=\"toast-body\">\r\n <pre id=\"alert-error-message\"></pre>\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Info -->\r\n <div id=\"alert-info\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"toast\">\r\n <div class=\"toast-header\">\r\n <i id=\"alert-info-icon\"></i>\r\n <strong id=\"alert-info-title\"></strong>\r\n <button type=\"button\" (click)=\"_Close('alert-info')\" class=\"btn-close btn-close-white\"></button>\r\n </div>\r\n\r\n <div class=\"toast-body\">\r\n <pre id=\"alert-info-message\"></pre>\r\n </div>\r\n </div>\r\n\r\n\r\n <!-- Warning -->\r\n <div id=\"alert-warning\" role=\"alert\" aria-live=\"assertive\" aria-atomic=\"true\" class=\"toast\">\r\n <div class=\"toast-header\">\r\n <i id=\"alert-warning-icon\"></i>\r\n <strong id=\"alert-warning-title\"></strong>\r\n <button type=\"button\" (click)=\"_Close('alert-warning')\" class=\"btn-close\"></button>\r\n </div>\r\n\r\n <div class=\"toast-body\">\r\n <pre id=\"alert-warning-message\"></pre>\r\n </div>\r\n </div>\r\n</aside>", styles: ["aside.toast-container{position:fixed;bottom:0;right:0;padding:15px!important;z-index:2000!important}aside.toast-container i,aside.toast-container svg{display:flex;align-items:center}aside.toast-container strong{margin:0 auto 0 5px}aside.toast-container div.toast,aside.toast-container div.toast-header{border-top-left-radius:10px;border-top-right-radius:10px;color:var(--smoke)}aside.toast-container div.toast,aside.toast-container div.toast-body{border-bottom-left-radius:10px;border-bottom-right-radius:10px;width:auto!important;min-width:350px!important;max-width:470px!important;color:var(--smoke)}@media (min-width: 0) and (max-width: 499px){aside.toast-container div.toast,aside.toast-container div.toast-body{min-width:calc(100vw - 30px)!important}}aside.toast-container div.toast-body{min-height:36px}aside.toast-container pre{font-family:Roboto,RobotoFallback,Noto Kufi Arabic,Helvetica,Arial,sans-serif;white-space:pre-wrap;font-size:medium}aside.toast-container button{margin:0 2px!important;width:10px!important;height:10px!important;box-shadow:none!important;outline:none!important;border:none!important}aside.toast-container div#alert-success div.toast-header,aside.toast-container div#alert-success div.toast-body{background-color:var(--success-inner)}aside.toast-container div#alert-info div.toast-header,aside.toast-container div#alert-info div.toast-body{background-color:var(--information-inner)}aside.toast-container div#alert-error div.toast-header,aside.toast-container div#alert-error div.toast-body{background-color:var(--danger-inner)}aside.toast-container div#alert-warning div.toast-header,aside.toast-container div#alert-warning div.toast-body{background-color:var(--warning-inner);border-color:var(--black);color:var(--black)}aside.toast-container div#alert-success:hover,aside.toast-container div#alert-info:hover,aside.toast-container div#alert-error:hover,aside.toast-container div#alert-warning:hover{transform:scale(1.01);box-shadow:2px 2px 10px #789;cursor:default}button.sweet-alert-button{width:100px!important;height:40px!important;display:flex!important;align-items:center!important;justify-content:center!important;margin:0 5px!important;outline:none!important;border:none!important;box-shadow:none!important}aside.toast-container>*{border:none!important;z-index:2000!important;margin:15px 0 0!important}\n"] }] }] }); /** Controls the breadcrumbs in sessionStorage */ class Breadcrumbs { static { this.storage = 'COER-System'; } /** Add a breadcrumb */ static Add(page, path) { const breadcrumbs = this.Get(); const paths = breadcrumbs.map(item => item.path); if (!paths.includes(path)) { breadcrumbs.push({ page, path }); this.Save(breadcrumbs); } } /** Get the breadcrumbs */ static Get() { let storage = sessionStorage.getItem(this.storage); if (storage) { storage = JSON.parse(storage); if (storage.hasOwnProperty('breadcrumbs')) { return Tools.BreakReference(storage.breadcrumbs); } } return []; } /** Get the first breadcrumb */ static GetFirst() { const breadcrumbs = this.Get(); return (breadcrumbs.length > 0) ? breadcrumbs.shift() : null; } /** Get the last breadcrumb */ static GetLast() { const breadcrumbs = this.Get(); return (breadcrumbs.length > 0) ? breadcrumbs.pop() : null; } /** */ static Save(breadcrumbs) { let storage = sessionStorage.getItem(this.storage); if (storage) storage = JSON.parse(storage); storage = Object.assign({}, storage, { breadcrumbs }); sessionStorage.setItem(this.storage, JSON.stringify(storage)); } /** Removes one breadcrumb by route */ static RemoveByPath(path) { let breadcrumbs = this.Get(); const index = breadcrumbs.findIndex(x => x.path.toLowerCase().trim() === path.toLowerCase().trim()); if (index >= 0) { breadcrumbs = Tools.BreakReference(breadcrumbs).splice(0, index + 1); this.Save(breadcrumbs); } } /** Update the last breadcrumb */ static UpdateLast(page, path) { const breadcrumbs = this.Get(); if (breadcrumbs.length > 0) { breadcrumbs[breadcrumbs.length - 1] = { page, path }; this.Save(breadcrumbs); } } /** Remove the last breadcrumb */ static RemoveLast() { const breadcrumbs = this.Get(); if (breadcrumbs.length > 0) { breadcrumbs.pop(); this.Save(breadcrumbs); } } } const GridTemplates = { /** Set Active/Disabled values, template for boolean property */ isActiveTemplate: (item) => { if (item.value) { return ` <span class='text-green font-weight-bold'> <i class="icon-circle-check icon-fill"></i> Active </span> `; } else { return ` <span class='text-gray font-weight-bold'> <i class="fa-solid fa-circle-minus"></i> Disabled </span> `; } }, /** Enable switch by row, template for boolean property */ coerSwitchTemplate: (item) => ({ showInput: true, tooltip: `${item.value ? 'Active' : 'Disabled'}` }), /** Enable textbox by row, template for text property */ coerTextboxTemplate: (item) => ({ showInput: true, isInvalid: item.value.length <= 0 }), /** Template for icons */ coerIconTemplate: (icon, color = 'black') => { return `<i class='${icon} display-block width-100 text-center' style='color: ${color};'></i>`; } }; /** Provides several methods for collection manipulation */ class Collections { /** Set an index and concat more arrays of the same type */ static SetIndex(array, ...args) { for (const arg of args) { array = [...array].concat([...arg]); } return [...array].map((item, index) => Object.assign({}, item, { index })); } /** Sort an array in ascending order by property */ static SortBy(array, property, propertyType = 'string') { switch (propertyType) { case 'string': { return array.sort((x, y) => { if (String(x[property]).toUpperCase().trim() < String(y[property]).toUpperCase().trim()) return -1; else if (String(x[property]).toUpperCase().trim() > String(y[property]).toUpperCase().trim()) return 1; else return 0; }); } case 'number': { return array.sort((x, y) => Number(x[property] - Number(y[property]))); } } } /** Sort an array in descending order by property */ static SortByDesc(array, property, propertyType = 'string') { switch (propertyType) { case 'string': { return array.sort((x, y) => { if (String(x[property]).toUpperCase().trim() < String(y[property]).toUpperCase().trim()) return 1; else if (String(x[property]).toUpperCase().trim() > String(y[property]).toUpperCase().trim()) return -1; else return 0; }); } case 'number': { return array.sort((x, y) => Number(Number(y[property])) - x[property]); } } } /** */ static Distinct(array) { return Tools.IsNotNull(array) ? Array.from(new Set(array)) : []; } /** */ static Except(array, exceptions) { if (Tools.IsNull(array)) return []; if (Tools.IsNull(exceptions) || exceptions.length <= 0) return [...array]; exceptions = Collections.Distinct(exceptions); return [...array].filter(item => !exceptions.includes(item)); } } const CONTROL_VALUE = (component) => { return { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => component), multi: true }; }; /** Implements the ControlValueAccessor interface to build a components */ class ControlValue { constructor() { //Variables this._isTouched = false; } /** Property to validate if the component has been touched */ get isTouched() { return this._isTouched; } /** Sets the value of the component when it is created */ writeValue(value) { this.SetValue(value); } /** Sets the value of the component when it is updated */ registerOnChange(callback) { if (typeof callback === 'function') { this._UpdateValue = callback; } } /** Sets the component's touched status when it is updated */ registerOnTouched(callback) { this._IsTouched = callback; } /** Sets the value of the component */ SetValue(value) { if (typeof this._UpdateValue === 'function') { this._UpdateValue(value); } this._value = value; } /** Sets whether the component has been touched */ SetTouched(isTouched) { if (typeof this._IsTouched === 'function') { this._IsTouched(isTouched); } this._isTouched = isTouched; } } /** Provides several methods for string manipulation */ class Strings { /** Sets the first character to lowercase */ static FirstCharToLower(value) { return (Tools.IsNotOnlyWhiteSpace(value)) ? String(value).charAt(0).toLowerCase() + String(value).slice(1) : ''; } /** Sets the first character to uppercase */ static FirstCharToUpper(value) { return (Tools.IsNotOnlyWhiteSpace(value)) ? String(value).charAt(0).toUpperCase() + String(value).slice(1) : ''; } /** Clean extra whitespaces */ static CleanUpBlanks(value) { return value && Tools.IsNotOnlyWhiteSpace(value) ? String(value).replace(/\s+/g, ' ').trim() : ''; } /** Apply title formatting */ static ToTitle(value) { return (Tools.IsNotOnlyWhiteSpace(value)) ? String(value).split(' ').filter(x => x.length > 0).map(x => Strings.FirstCharToUpper(x.toLowerCase())).join(' ') : ''; } /** Remove whitespaces */ static RemoveWhiteSpaces(value) { return Tools.IsNotOnlyWhiteSpace(value) ? String(value).replaceAll(' ', '') : ''; } /** Removes the last character */ static RemoveLastChar(value) { return Tools.IsNotOnlyWhiteSpace(value) ? String(value).trimEnd().slice(0, -1) : ''; } /** Removes accents */ static RemoveAccents(value, except = []) { if (Tools.IsOnlyWhiteSpace(value)) return ''; if (except.length > 0) { let index = 0; const mapValue = new Map(); for (const char of String(value)) { mapValue.set(index++, char); } index = 0; const mapNormalize = new Map(); for (const char of String(value).normalize('NFD').replace(/[\u0300-\u036f]/g, '')) { mapNormalize.set(index++, char); } for (const char of except) { for (const [index, value] of mapValue.entries()) { if (value === char) { mapNormalize.set(index, char); } } } return Array.from(mapNormalize.values()).join(''); } else { return String(value).normalize('NFD').replace(/[\u0300-\u036f]/g, ''); } } /** Removes special characters */ static RemoveSpecialCharacters(value) { return (Tools.IsNotOnlyWhiteSpace(value)) ? String(value).replace(/[^a-zA-Z0-9áéíóúÁÉÍÓÚüÜñÑ\s]/g, '') : ''; } /** Only Alphanumeric */ static OnlyAlphanumeric(value) { return (Tools.IsNotOnlyWhiteSpace(value)) ? String(value).replace(/[^a-zA-Z0-9\s]/g, '') : ''; } /** Only Alphanumeric */ static OnlyNumbers(value) { return (Tools.IsNotOnlyWhiteSpace(value)) ? String(value).replace(/[^0-9\s]/g, '') : ''; } /** Validates if both strings are equal */ static Equals(value, value2, sensitive = false) { if (typeof value === null && typeof value2 === null) return true; if (typeof value === 'undefined' && typeof value2 === 'undefined') return true; if (typeof value === 'string' && typeof value2 === 'string') { if (!sensitive) { value = value.toUpperCase(); value2 = value2.toUpperCase(); } return value.length === value2.length && value === value2; } return false; } } /** Provides several methods for dates manipulation */ class Dates { static { this.MONTHS = new Map([ [1, 'Jan'], [2, 'Feb'], [3, 'Mar'], [4, 'Apr'], [5, 'May'], [6, 'Jun'], [7, 'Jul'], [8, 'Aug'], [9, 'Sep'], [10, 'Oct'], [11, 'Nov'], [12, 'Dec'], ]); } /** */ static GetOffset() { return -(new Date().getTimezoneOffset()); } /** */ static GetLastDay(date) { const DATE = this._CleanDate(date); return new Date(DATE.getFullYear(), DATE.getMonth() + 1, 0).getDate(); } /** */ static IsValidDate(date) { return !isNaN(new Date(date).getTime()); } /** */ static GetCurrentDate() { return new Date(); } /** */ static _CleanDate(date) { if (typeof date === 'string') { date = Strings.CleanUpBlanks(date.replace(/(?:at|AT|t|T)/g, ' ')); return /\b([01]?\d|2[0-3]):[0-5]\d(:[0-5]\d)?\b/.test(date) ? new Date(date) : new Date(`${date} 00:00:00`); } else return date; } /** */ static ToLocalZone(utcDate) { return new Date(new Date(utcDate).getTime() + this.GetOffset() * 60000); } /** */ static ToUTC(date) { return new Date(new Date(date).getTime() - this.GetOffset() * 60000); } /** YYYY-MM-DD HH:mm:ss */ static ToFormatDB(date) { const DATE = this._CleanDate(date); return `${DATE.getFullYear()}` + '-' + `${DATE.getMonth() + 1}`.padStart(2, '0') + '-' + `${DATE.getDate()}`.padStart(2, '0') + ' ' + `${DATE.getHours()}`.padStart(2, '0') + ':' + `${DATE.getMinutes()}`.padStart(2, '0') + ':' + `${DATE.getSeconds()}`.padStart(2, '0'); } /** */ static ToFormatDate(date, format) { const DATE = this._CleanDate(date); switch (format || Tools.AvoidNull(appSettings?.dateTime?.format, 'string')) { case 'DMY': { /** DD MMM YYYY - MX ES */ return `${DATE.getDate()}`.padStart(2, '0') + ' ' + `${this.MONTHS.get(DATE.getMonth() + 1)}` + ' ' + `${DATE.getFullYear()}`; } case 'YMD': { /** YYYY MMM DD - International */ return `${DATE.getFullYear()}` + ' ' + `${this.MONTHS.get(DATE.getMonth() + 1)}` + ' ' + `${DATE.getDate()}`.padStart(2, '0') + ' '; } default: { /** MMM, DD YYYY - US */ return `${this.MONTHS.get(DATE.getMonth() + 1)}` + ', ' + `${DATE.getDate()}`.padStart(2, '0') + ' ' + `${DATE.getFullYear()}`; } } } /** */ static ToFormatTime(date, ampm = false) { const DATE = this._CleanDate(date); if (ampm) { let hours = DATE.getHours(); const AM_PM = hours >= 12 ? 'pm' : 'am'; hours = hours % 12; hours = hours === 0 ? 12 : hours; return `${hours}`.padStart(2, '0') + ':' + `${DATE.getMinutes()}`.padStart(2, '0') + ' ' + `${AM_PM}`; } else { return `${DATE.getHours()}`.padStart(2, '0') + ':' + `${DATE.getMinutes()}`.padStart(2, '0'); } } /** */ static ToFormatDateTime(date, ampm = false, format) { return this.ToFormatDate(date, format) + ' at ' + this.ToFormatTime(date, ampm); } /** */ static AddMilliseconds(date, milliseconds) { return new Date(this._CleanDate(date).getTime() + milliseconds); } /** */ static AddSeconds(date, seconds = 1) { return this.AddMilliseconds(date, seconds * 1000); } /** */ static AddMinutes(date, minutes = 1) { return this.AddMilliseconds(date, minutes * 60 * 1000); } /** */ static AddHours(date, hours = 1) { return this.AddMilliseconds(date, hours * 60 * 60 * 1000); } /** Add days */ static AddDays(date, days = 1) { return this.AddMilliseconds(date, days * 24 * 60 * 60 * 1000); } /** Add weeks */ static AddWeeks(date, weeks = 1) { return this.AddMilliseconds(date, weeks * 7 * 24 * 60 * 60 * 1000); } /** Add months */ static AddMonths(date, months = 1) { const DATE = this._CleanDate(date); const DATE_UPDATED = new Date(DATE.getFullYear(), (DATE.getMonth() + months), 1); DATE_UPDATED.setDate(Math.min(DATE.getDate(), new Date(DATE_UPDATED.getFullYear(), (DATE_UPDATED.getMonth() + 1), 0).getDate())); DATE_UPDATED.setHours(DATE.getHours(), DATE.getMinutes(), DATE.getSeconds(), DATE.getMilliseconds()); return DATE_UPDATED; } /** Add years */ static AddYears(date, years = 1) { const DATE = this._CleanDate(date); const DATE_UPDATED = new Date((DATE.getFullYear() + years), DATE.getMonth(), 1); DATE_UPDATED.setDate(Math.min(DATE.getDate(), new Date(DATE_UPDATED.getFullYear(), DATE_UPDATED.getMonth() + 1, 0).getDate())); DATE_UPDATED.setHours(DATE.getHours(), DATE.getMinutes(), DATE.getSeconds(), DATE.getMilliseconds()); return DATE_UPDATED; } /** */ static SetMillisecond(date, millisecond = 0) { const DATE = this._CleanDate(date); if (millisecond < 0 || millisecond >= 1000) { millisecond = DATE.getMilliseconds(); } DATE.setMilliseconds(millisecond); return DATE; } /** */ static SetSecond(date, second = 0) { const DATE = this._CleanDate(date); if (second < 0 || second >= 60) { second = DATE.getSeconds(); } DATE.setSeconds(second); return DATE; } /** */ static SetMinute(date, minute = 0) { const DATE = this._CleanDate(date); if (minute < 0 || minute >= 60) { minute = DATE.getMinutes(); } DATE.setMinutes(minute, DATE.getSeconds()); return DATE; } /** */ static SetHour(date, hour = 0) { const DATE = this._CleanDate(date); if (hour < 0 || hour >= 24) { hour = DATE.getHours(); } DATE.setHours(hour, DATE.getMinutes(), DATE.getSeconds()); return DATE; } /** Set 00:00:00 */ static SetFirstHour(date) { const DATE = this._CleanDate(date); DATE.setHours(0, 0, 0); return DATE; } /** Set 23:59:59 */ static SetLastHour(date) { const DATE = this._CleanDate(date); DATE.setHours(23, 59, 59); return DATE; } /** */ static SetDay(date, day = 1) { const DATE = this._CleanDate(date); if (day < 1 || day > this.GetLastDay(DATE)) { day = DATE.getDate(); } DATE.setDate(day); return DATE; } /** */ static SetFirstDay(date) { return this.SetDay(date, 1); } /** */ static SetLastDay(date) { return this.SetDay(date, this.GetLastDay(date)); } /** */ static GetDiffNow(date, unit = 'minutes') { return this.GetDiff(this.GetCurrentDate(), date, unit); } /** */ static GetDiff(fromDate, toDate, unit = 'minutes') { switch (unit) { case 'milliseconds': return Number(Numbers.SetDecimals(this._CleanDate(fromDate).getTime() - this._CleanDate(toDate).getTime(), 0)); case 'seconds': return Number(Numbers.SetDecimals((this._CleanDate(fromDate).getTime() - this._CleanDate(toDate).getTime()) / 1000, 0)); case 'minutes': return Number(Numbers.SetDecimals((this._CleanDate(fromDate).getTime() - this._CleanDate(toDate).getTime()) / (1000 * 60), 0)); case 'hours': return Number(Numbers.SetDecimals((this._CleanDate(fromDate).getTime() - this._CleanDate(toDate).getTime()) / (1000 * 60 * 60), 0)); case 'days': return Number(Numbers.SetDecimals((this._CleanDate(fromDate).getTime() - this._CleanDate(toDate).getTime()) / (1000 * 60 * 60 * 24), 0)); } } } class HTMLElements { /** */ static { this.GetElement = (selector) => { return document.querySelector(selector); }; } /** */ static { this.Scroll = (element, y = 0, x = 0) => { const HTML_ELEMENT = (typeof element === 'string') ? this.GetElement(element) : element; if (HTML_ELEMENT) { Tools.Sleep().then(_ => HTML_ELEMENT.scroll({ top: y, left: x, behavior: 'smooth' })); } }; } /** */ static { this.ScrollToElement = (element, container = '') => { const HTML_ELEMENT = (typeof element === 'string') ? this.GetElement(element) : element; if (HTML_ELEMENT) { const HTML_CONTAINER = (typeof container === 'string') ? this.GetElement(container) : container; if (HTML_CONTAINER) { Tools.Sleep().then(_ => HTML_CONTAINER.scrollBy({ top: HTML_ELEMENT.offsetTop, behavior: 'smooth' })); } else { Tools.Sleep().then(_ => HTML_ELEMENT.scrollIntoView({ behavior: 'smooth', block: "start" })); } } }; } /** */ static { this.GetOffsetTop = (element) => { const HTML_ELEMENT = (typeof element === 'string') ? this.GetElement(element) : element; return (HTML_ELEMENT) ? HTML_ELEMENT.offsetTop : 0; }; } /** */ static { this.GetCssValue = (element, style) => { const HTML_ELEMENT = (typeof element === 'string') ? this.GetElement(element) : element; return (HTML_ELEMENT) ? window.getComputedStyle(HTML_ELEMENT).getPropertyValue(style) : ''; }; } /** Gets the width of the element in px */ static { this.GetElementWidth = (element, ...args) => { let width = 0; if (Tools.IsNotNull(element) && Tools.IsNotOnlyWhiteSpace(element?.offsetWidth)) {