coer-elements 2.0.21 → 2.0.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/components/lib/coer-card/coer-card.component.d.ts +13 -0
  2. package/components/lib/coer-grid/coer-grid.component.d.ts +3 -1
  3. package/components/lib/coer-grid/coer-grid.extension.d.ts +2 -2
  4. package/components/lib/components.module.d.ts +41 -40
  5. package/components/public-api.d.ts +1 -0
  6. package/fesm2022/coer-elements-components.mjs +59 -29
  7. package/fesm2022/coer-elements-components.mjs.map +1 -1
  8. package/fesm2022/coer-elements-extensions.mjs +9 -9
  9. package/fesm2022/coer-elements-extensions.mjs.map +1 -1
  10. package/fesm2022/coer-elements-guards.mjs +8 -8
  11. package/fesm2022/coer-elements-guards.mjs.map +1 -1
  12. package/fesm2022/coer-elements-interceptors.mjs +2 -2
  13. package/fesm2022/coer-elements-interceptors.mjs.map +1 -1
  14. package/fesm2022/coer-elements-pages.mjs +18 -18
  15. package/fesm2022/coer-elements-pages.mjs.map +1 -1
  16. package/fesm2022/coer-elements-pipes.mjs +2 -2
  17. package/fesm2022/coer-elements-pipes.mjs.map +1 -1
  18. package/fesm2022/coer-elements-services.mjs +2 -2
  19. package/fesm2022/coer-elements-services.mjs.map +1 -1
  20. package/fesm2022/coer-elements-tools.mjs +362 -407
  21. package/fesm2022/coer-elements-tools.mjs.map +1 -1
  22. package/fesm2022/coer-elements.mjs +2 -1
  23. package/fesm2022/coer-elements.mjs.map +1 -1
  24. package/fonts/consolas.ttf +0 -0
  25. package/fonts/montserrat.ttf +0 -0
  26. package/fonts/roboto-monospace.ttf +0 -0
  27. package/fonts/roboto.ttf +0 -0
  28. package/index.d.ts +1 -1
  29. package/package.json +4 -2
  30. package/styles/border.scss +30 -0
  31. package/styles/coer-elements.css +17434 -3587
  32. package/styles/colors.scss +28 -8
  33. package/styles/containers.scss +1 -1
  34. package/styles/font.scss +55 -5
  35. package/styles/icons.scss +41 -1
  36. package/styles/index.scss +4 -1
  37. package/styles/layout-flex-wrap.scss +32 -32
  38. package/styles/layout-grid.scss +12 -5
  39. package/styles/margin.scss +1 -1
  40. package/styles/padding.scss +1 -1
  41. package/styles/paragraph.scss +3 -0
  42. package/styles/position.scss +20 -4
  43. package/styles/width-height.scss +145 -0
  44. package/svg/array.svg +3 -0
  45. package/svg/bulb-light-idea-fill.svg +3 -0
  46. package/svg/css.svg +3 -0
  47. package/svg/developer.svg +3 -0
  48. package/svg/envelope.svg +3 -0
  49. package/svg/html.svg +3 -0
  50. package/svg/javascript.svg +3 -0
  51. package/svg/whatsapp.svg +3 -0
  52. package/tools/lib/breadcrumbs.tools.d.ts +11 -10
  53. package/tools/lib/coer-alert/coer-alert.component.d.ts +8 -10
  54. package/tools/lib/coer-grid.templates.d.ts +4 -4
  55. package/tools/lib/collections.tools.d.ts +13 -0
  56. package/tools/lib/colors.tools.d.ts +7 -2
  57. package/tools/lib/control-value.tools.d.ts +13 -12
  58. package/tools/lib/date-time.tools.d.ts +8 -7
  59. package/tools/lib/files.tools.d.ts +1 -1
  60. package/tools/lib/{elements-html.tools.d.ts → html-elements.tools.d.ts} +6 -6
  61. package/tools/lib/numbers.tools.d.ts +9 -0
  62. package/tools/lib/page.tools.d.ts +12 -14
  63. package/tools/lib/screen.tools.d.ts +7 -2
  64. package/tools/lib/section.tools.d.ts +19 -10
  65. package/tools/lib/service.tools.d.ts +11 -10
  66. package/tools/lib/source.tools.d.ts +9 -8
  67. package/tools/lib/{string.tools.d.ts → strings.tools.d.ts} +2 -1
  68. package/tools/lib/tools.d.ts +8 -23
  69. package/tools/lib/user.class.d.ts +6 -5
  70. package/tools/public-api.d.ts +4 -2
  71. /package/styles/{cursores.scss → cursors.scss} +0 -0
  72. /package/svg/{house.svg → house-fill.svg} +0 -0
@@ -12,8 +12,9 @@ import { HttpClient, HttpRequest } from '@angular/common/http';
12
12
  import { saveAs } from 'file-saver';
13
13
 
14
14
  const reference_signal = signal({});
15
+ /** Generic Methods */
15
16
  const Tools = {
16
- /** Generate a Guid */
17
+ /** Generates a guid */
17
18
  GetGuid: (seed = 'coer-system') => {
18
19
  let time = new Date().getTime();
19
20
  seed = seed.toString().trim();
@@ -31,18 +32,18 @@ const Tools = {
31
32
  IsNotNull: (value) => {
32
33
  return !Tools.IsNull(value);
33
34
  },
34
- /** Returns true if the value is null or undefined or contains only whitespace, false otherwise */
35
+ /** Returns true if the value is null or undefined or is an empty string or contains only whitespace, false otherwise */
35
36
  IsOnlyWhiteSpace: (value) => {
36
37
  return Tools.IsNull(value) || (typeof value === 'string' && value.trim() === '');
37
38
  },
38
- /** Returns true if has string value and is not only whitespace, false otherwise */
39
+ /** Returns true if it has a string value and is not all whitespace, false otherwise */
39
40
  IsNotOnlyWhiteSpace: (value) => {
40
41
  return Tools.IsNotNull(value) && !Tools.IsOnlyWhiteSpace(value);
41
42
  },
42
- /** Avoid Null value */
43
- AvoidNull: (value, type = null) => {
43
+ /** Avoids null value and responds with the specified type */
44
+ AvoidNull: (value, type = 'string') => {
44
45
  if (typeof value === 'string') {
45
- if (type === null || type === 'string') {
46
+ if (type === 'string') {
46
47
  return (Tools.IsNotNull(value) ? value : '');
47
48
  }
48
49
  else if (type === 'number') {
@@ -53,146 +54,44 @@ const Tools = {
53
54
  }
54
55
  }
55
56
  if (typeof value === 'number') {
56
- if (type === null || type === 'number') {
57
- return (Tools.IsNotNull(value) ? value : 0);
58
- }
59
- else if (type === 'string') {
57
+ if (type === 'string') {
60
58
  return (Tools.IsNotNull(value) ? String(value) : '0');
61
59
  }
60
+ else if (type === 'number') {
61
+ return (Tools.IsNotNull(value) ? value : 0);
62
+ }
62
63
  else if (type === 'boolean') {
63
64
  return (Tools.IsNotNull(value) ? (value >= 1) : false);
64
65
  }
65
66
  }
66
67
  if (typeof value === "boolean") {
67
- if (type === null || type === 'boolean') {
68
- return (Tools.IsNotNull(value) ? value : false);
69
- }
70
- else if (type === 'string') {
68
+ if (type === 'string') {
71
69
  return (Tools.IsNotNull(value) ? (value ? 'true' : 'false') : 'false');
72
70
  }
73
71
  else if (type === 'number') {
74
72
  return (Tools.IsNotNull(value) ? (value ? 1 : 0) : 0);
75
73
  }
74
+ else if (type === 'boolean') {
75
+ return (Tools.IsNotNull(value) ? value : false);
76
+ }
76
77
  }
77
78
  switch (type) {
78
79
  case 'string': return '';
79
80
  case 'number': return 0;
80
81
  case 'boolean': return false;
81
- default: return '';
82
82
  }
83
83
  },
84
84
  /** Break reference of a object or array */
85
85
  BreakReference: (object) => {
86
- if (object === null)
87
- return object;
88
- if (typeof object === 'undefined')
86
+ if (Tools.IsNull(object) || ['string', 'number', 'boolean'].includes(typeof object))
89
87
  return object;
90
- if (typeof object === 'string')
91
- return object;
92
- if (typeof object === 'number')
93
- return object;
94
- if (typeof object === 'boolean')
95
- return object;
96
- const OBJECT = JSON.parse(JSON.stringify(object));
97
- return (Array.isArray(OBJECT) ? [...OBJECT] : { ...OBJECT });
88
+ return JSON.parse(JSON.stringify(object));
98
89
  },
99
90
  /** Get properties of an object */
100
91
  GetPropertyList: (object) => {
101
- const properties = [];
102
- if (object === null)
103
- return properties;
104
- if (typeof object === 'undefined')
105
- return properties;
106
- if (typeof object === 'string')
107
- return properties;
108
- if (typeof object === 'number')
109
- return properties;
110
- if (typeof object === 'boolean')
111
- return properties;
112
- for (const property in object)
113
- properties.push(String(property));
114
- return properties;
115
- },
116
- /**
117
- * Set an index and merge more arrays of the same type
118
- * */
119
- SetIndex: (array, ...args) => {
120
- let index = 0;
121
- for (const arg of args) {
122
- array = Tools.BreakReference(array).concat(Tools.BreakReference(arg));
123
- }
124
- return Tools.BreakReference(array).map(item => Object.assign({ index: index++ }, item));
125
- },
126
- /** Sort an array in ascending order by property */
127
- SortBy: (array, property, propertyType = 'string') => {
128
- switch (propertyType) {
129
- case 'string': {
130
- return array.sort((x, y) => {
131
- if (String(x[property]).toUpperCase().trim() < String(y[property]).toUpperCase().trim())
132
- return -1;
133
- else if (String(x[property]).toUpperCase().trim() > String(y[property]).toUpperCase().trim())
134
- return 1;
135
- else
136
- return 0;
137
- });
138
- }
139
- case 'number': {
140
- return array.sort((x, y) => Number(x[property] - Number(y[property])));
141
- }
142
- }
143
- },
144
- /** Sort an array in descending order by property */
145
- SortByDesc: (array, property, propertyType = 'string') => {
146
- switch (propertyType) {
147
- case 'string': {
148
- return array.sort((x, y) => {
149
- if (String(x[property]).toUpperCase().trim() < String(y[property]).toUpperCase().trim())
150
- return 1;
151
- else if (String(x[property]).toUpperCase().trim() > String(y[property]).toUpperCase().trim())
152
- return -1;
153
- else
154
- return 0;
155
- });
156
- }
157
- case 'number': {
158
- return array.sort((x, y) => Number(Number(y[property])) - x[property]);
159
- }
160
- }
161
- },
162
- /** Return a string with forman numeric */
163
- GetNumericFormat: (value, decimals = 0) => {
164
- if (Tools.IsOnlyWhiteSpace(value) || isNaN(Number(value))) {
165
- return '0';
166
- }
167
- let valueInteger = '';
168
- let valueDecimal = '';
169
- value = value.toString().replaceAll(' ', '');
170
- if (value.includes('.') || (decimals > 0)) {
171
- valueInteger = value.includes('.') ? value.split('.')[0] : value;
172
- if (decimals > 0) {
173
- const PADDING = decimals - valueDecimal.length;
174
- valueDecimal = value.includes('.') ? value.split('.')[1] : '';
175
- for (let i = 0; i < PADDING; i++)
176
- valueDecimal += '0';
177
- valueDecimal = valueDecimal.substring(0, decimals);
178
- valueDecimal = `.${valueDecimal}`;
179
- }
180
- }
181
- else {
182
- valueInteger = value;
183
- }
184
- let counter = 0;
185
- const VALUE_INTEGER_ARRAY = [];
186
- for (const char of valueInteger.split('').reverse()) {
187
- if (counter == 3) {
188
- VALUE_INTEGER_ARRAY.push(',');
189
- counter = 0;
190
- }
191
- VALUE_INTEGER_ARRAY.push(char);
192
- ++counter;
193
- }
194
- valueInteger = VALUE_INTEGER_ARRAY.reverse().join('');
195
- return `${valueInteger}${valueDecimal}`;
92
+ return Tools.IsNotNull(object) && typeof object === 'object'
93
+ ? Object.keys(object)
94
+ : [];
196
95
  },
197
96
  /** Wait the time indicated */
198
97
  Sleep: (milliseconds = 0, reference = null) => {
@@ -216,31 +115,7 @@ const Tools = {
216
115
  }));
217
116
  });
218
117
  },
219
- /** */
220
- Distinct: (array, ...args) => {
221
- for (const arg of args) {
222
- array = Tools.BreakReference(array).concat(Tools.BreakReference(arg));
223
- }
224
- return Array.from(new Set(array));
225
- },
226
- /** */
227
- Except: (array, filter, ...properties) => {
228
- const result = [];
229
- for (const item of array) {
230
- if (typeof item === 'object' && Tools.IsNotNull(properties) && properties.length > 0) {
231
- if (!filter.some(x => x[properties[0]] === item[properties[0]])) {
232
- result.push(item);
233
- }
234
- }
235
- }
236
- return [...result];
237
- },
238
- /** */
239
- IsNumber: (value) => {
240
- return typeof value === 'number'
241
- && !Number.isNaN(Number(value));
242
- },
243
- /** */
118
+ /** Send text to the computer's clipboard */
244
119
  Clipboard: (text, message = '', title = 'Copied') => {
245
120
  try {
246
121
  navigator.clipboard.writeText(text).then(() => {
@@ -250,10 +125,12 @@ const Tools = {
250
125
  catch {
251
126
  new CoerAlert().Warning('Unable to copy to clipboard', 'Quick Implement', 'bi bi-clipboard-fill');
252
127
  }
253
- },
128
+ }
254
129
  };
255
130
 
131
+ /** class to work with colors */
256
132
  class Colors {
133
+ /** Provides the fixed colors set by the coer-elements library */
257
134
  static get fixedColors() {
258
135
  return {
259
136
  blue: colorsSIGNAL().fixedColors.blue,
@@ -268,6 +145,7 @@ class Colors {
268
145
  purple: colorsSIGNAL().fixedColors.purple
269
146
  };
270
147
  }
148
+ /** Provides the action colors set in the application */
271
149
  static get actionColors() {
272
150
  return {
273
151
  primary: colorsSIGNAL().actionColors.primary,
@@ -279,6 +157,7 @@ class Colors {
279
157
  information: colorsSIGNAL().actionColors.information
280
158
  };
281
159
  }
160
+ /** Provides the colors of the application */
282
161
  static get appColors() {
283
162
  return {
284
163
  breadcrumbs: colorsSIGNAL().appColors.breadcrumbs,
@@ -291,17 +170,18 @@ class Colors {
291
170
  toolbarText: colorsSIGNAL().appColors.toolbarText
292
171
  };
293
172
  }
294
- static ToHexadecimal(r, g, b, a) {
295
- const red = `${Number(r).toString(16).padStart(2, '0')}`;
296
- const green = `${Number(g).toString(16).padStart(2, '0')}`;
297
- const blue = `${Number(b).toString(16).padStart(2, '0')}`;
298
- const alpha = (Tools.IsNotNull(a)) ? Math.round(Number(a) * 255).toString(16).padStart(2, '0') : '';
299
- return `#${red}${green}${blue}${alpha}`.toLowerCase();
173
+ /** Get Hexadecimal color */
174
+ static ToHexadecimal(red, green, blue, alpha) {
175
+ const _red = `${Number(red).toString(16).padStart(2, '0')}`;
176
+ const _green = `${Number(green).toString(16).padStart(2, '0')}`;
177
+ const _blue = `${Number(blue).toString(16).padStart(2, '0')}`;
178
+ const _alpha = (Tools.IsNotNull(alpha)) ? Math.round(Number(alpha) * 255).toString(16).padStart(2, '0') : '';
179
+ return `#${_red}${_green}${_blue}${_alpha}`.toLowerCase();
300
180
  }
301
181
  /** Returns a random color in hexadecimal
302
182
  public static GetRandomColorHex = (): string => "#xxxxxx".replace(/x/g, () => (Math.random() * 16 | 0).toString(16)); */
303
183
  /** Returns the number of colors requested */
304
- static GetColorHexList(quantity) {
184
+ static GetColorList(quantity) {
305
185
  const colors = [];
306
186
  let counter = 0;
307
187
  while (counter < quantity) {
@@ -316,7 +196,7 @@ class Colors {
316
196
  }
317
197
 
318
198
  class CoerAlert {
319
- /** */
199
+ /** Use this alert to issue a success message */
320
200
  Success(message = null, title = null, icon = null, autohide = 3000) {
321
201
  //Title
322
202
  if (Tools.IsOnlyWhiteSpace(title))
@@ -324,9 +204,9 @@ class CoerAlert {
324
204
  const alertSuccessTitle = document.getElementById('alert-success-title');
325
205
  alertSuccessTitle.textContent = title;
326
206
  //Icon
327
- icon = this.GetIcon(title, icon, 'bi-check-circle fa-beat');
207
+ icon = Tools.IsOnlyWhiteSpace(icon) ? 'bi-check-circle fa-beat' : icon;
328
208
  const alertSuccessIcon = document.getElementById('alert-success-icon');
329
- this.SetIcon(alertSuccessIcon, icon);
209
+ this._SetIcon(alertSuccessIcon, icon);
330
210
  //Message
331
211
  if (Tools.IsNull(message))
332
212
  message = '';
@@ -334,21 +214,21 @@ class CoerAlert {
334
214
  alertSuccessMessage.innerHTML = message;
335
215
  //Toast
336
216
  const alertSuccess = document.getElementById('alert-success');
337
- this.SetAutoHide(alertSuccess, autohide);
217
+ this._SetAutoHide(alertSuccess, autohide);
338
218
  const toast = bootstrap.Toast.getOrCreateInstance(alertSuccess);
339
219
  toast.show();
340
220
  }
341
- /** */
221
+ /** Use this alert to issue a error or danger */
342
222
  Error(message = null, title = null, icon = null, autohide = 3000) {
343
223
  //Title
344
224
  if (Tools.IsOnlyWhiteSpace(title))
345
225
  title = 'Error';
346
226
  const alertErrorTitle = document.getElementById('alert-error-title');
347
227
  alertErrorTitle.textContent = title;
348
- //Icon
349
- icon = this.GetIcon(title, icon, 'bi-exclamation-octagon fa-beat');
228
+ //Icon
229
+ icon = Tools.IsOnlyWhiteSpace(icon) ? 'bi-exclamation-octagon fa-beat' : icon;
350
230
  const alertErrorIcon = document.getElementById('alert-error-icon');
351
- this.SetIcon(alertErrorIcon, icon);
231
+ this._SetIcon(alertErrorIcon, icon);
352
232
  //Message
353
233
  if (Tools.IsNull(message))
354
234
  message = '';
@@ -356,21 +236,21 @@ class CoerAlert {
356
236
  alertErrorBody.innerHTML = message;
357
237
  //Toast
358
238
  const alertError = document.getElementById('alert-error');
359
- this.SetAutoHide(alertError, autohide);
239
+ this._SetAutoHide(alertError, autohide);
360
240
  const toast = bootstrap.Toast.getOrCreateInstance(alertError);
361
241
  toast.show();
362
242
  }
363
- /** */
243
+ /** Use this alert to broadcast an informational message */
364
244
  Info(message = null, title = null, icon = null, autohide = 3000) {
365
245
  //Title
366
246
  if (Tools.IsOnlyWhiteSpace(title))
367
247
  title = 'Info';
368
248
  const alertInfoTitle = document.getElementById('alert-info-title');
369
249
  alertInfoTitle.textContent = title;
370
- //Icon
371
- icon = this.GetIcon(title, icon, 'bi-info-circle fa-beat');
250
+ //Icon
251
+ icon = Tools.IsOnlyWhiteSpace(icon) ? 'bi-info-circle fa-beat' : icon;
372
252
  const alertInfoIcon = document.getElementById('alert-info-icon');
373
- this.SetIcon(alertInfoIcon, icon);
253
+ this._SetIcon(alertInfoIcon, icon);
374
254
  //Message
375
255
  if (Tools.IsNull(message))
376
256
  message = '';
@@ -378,21 +258,21 @@ class CoerAlert {
378
258
  alertInfoBody.innerHTML = message;
379
259
  //Toast
380
260
  const alertInfo = document.getElementById('alert-info');
381
- this.SetAutoHide(alertInfo, autohide);
261
+ this._SetAutoHide(alertInfo, autohide);
382
262
  const toast = bootstrap.Toast.getOrCreateInstance(alertInfo);
383
263
  toast.show();
384
264
  }
385
- /** */
265
+ /** Use this alert to issue a warning message */
386
266
  Warning(message = null, title = null, icon = null, autohide = 3000) {
387
267
  //Title
388
268
  if (Tools.IsOnlyWhiteSpace(title))
389
269
  title = 'Warning';
390
270
  const alertWarningTitle = document.getElementById('alert-warning-title');
391
271
  alertWarningTitle.textContent = title;
392
- //Icon
393
- icon = this.GetIcon(title, icon, 'bi-exclamation-triangle-fill fa-beat');
272
+ //Icon
273
+ icon = Tools.IsOnlyWhiteSpace(icon) ? 'bi-exclamation-triangle-fill fa-beat' : icon;
394
274
  const alertWarningIcon = document.getElementById('alert-warning-icon');
395
- this.SetIcon(alertWarningIcon, icon);
275
+ this._SetIcon(alertWarningIcon, icon);
396
276
  //Message
397
277
  if (Tools.IsNull(message))
398
278
  message = '';
@@ -400,20 +280,11 @@ class CoerAlert {
400
280
  alertWarningBody.innerHTML = message;
401
281
  //Toast
402
282
  const alertWarning = document.getElementById('alert-warning');
403
- this.SetAutoHide(alertWarning, autohide);
283
+ this._SetAutoHide(alertWarning, autohide);
404
284
  const toast = bootstrap.Toast.getOrCreateInstance(alertWarning);
405
285
  toast.show();
406
286
  }
407
- /** */
408
- Close(alert) {
409
- return new Promise(Resolve => {
410
- const element = document.getElementById(alert);
411
- const toast = bootstrap.Toast.getOrCreateInstance(element);
412
- toast.hide();
413
- setTimeout(() => { Resolve(); }, 200);
414
- });
415
- }
416
- /** */
287
+ /** Use this alert to confirm a user action */
417
288
  Confirm(message = 'Proceed?', alertType = 'warning', icon = null) {
418
289
  return new Promise(Resolve => {
419
290
  let color;
@@ -483,7 +354,16 @@ class CoerAlert {
483
354
  });
484
355
  }
485
356
  /** */
486
- SetIcon(element, icon) {
357
+ _Close(alert) {
358
+ return new Promise(Resolve => {
359
+ const element = document.getElementById(alert);
360
+ const toast = bootstrap.Toast.getOrCreateInstance(element);
361
+ toast.hide();
362
+ setTimeout(() => { Resolve(); }, 200);
363
+ });
364
+ }
365
+ /** */
366
+ _SetIcon(element, icon) {
487
367
  if (icon.toUpperCase() != 'NONE') {
488
368
  for (const item of [...element.classList.value.split(' ')]) {
489
369
  if (item.length > 0) {
@@ -503,7 +383,7 @@ class CoerAlert {
503
383
  }
504
384
  }
505
385
  /** */
506
- SetAutoHide(element, autohide) {
386
+ _SetAutoHide(element, autohide) {
507
387
  element.removeAttribute('data-bs-autohide');
508
388
  element.removeAttribute('data-bs-delay');
509
389
  if (autohide && autohide > 0) {
@@ -515,34 +395,18 @@ class CoerAlert {
515
395
  else
516
396
  element.setAttribute('data-bs-autohide', 'false');
517
397
  }
518
- /** */
519
- GetIcon(title, icon, iconDefault) {
520
- if (icon == null || icon == '') {
521
- title = title.replaceAll(' ', '').toUpperCase();
522
- switch (title) {
523
- case 'ENABLED': return 'fa-solid fa-thumbs-up fa-flip-horizontal';
524
- case 'ACTIVE': return 'fa-solid fa-thumbs-up fa-flip-horizontal';
525
- case 'ACTIVED': return 'fa-solid fa-thumbs-up fa-flip-horizontal';
526
- case 'DISABLE': return 'fa-solid fa-thumbs-down fa-flip-horizontal';
527
- case 'DISABLED': return 'fa-solid fa-thumbs-down fa-flip-horizontal';
528
- case 'DELETE': return 'fa-regular fa-trash-can';
529
- case 'DELETED': return 'fa-regular fa-trash-can';
530
- default: return iconDefault;
531
- }
532
- }
533
- return icon;
534
- }
535
398
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: CoerAlert, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
536
- 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)}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"] }); }
399
+ 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)}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"] }); }
537
400
  }
538
401
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImport: i0, type: CoerAlert, decorators: [{
539
402
  type: Component,
540
- 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)}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"] }]
403
+ 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)}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"] }]
541
404
  }] });
542
405
 
406
+ /** Controls the breadcrumbs in sessionStorage */
543
407
  class Breadcrumbs {
544
408
  static { this.storage = 'COER-System'; }
545
- /** */
409
+ /** Add a breadcrumb */
546
410
  static Add(page, path) {
547
411
  const breadcrumbs = this.Get();
548
412
  const paths = breadcrumbs.map(item => item.path);
@@ -551,7 +415,7 @@ class Breadcrumbs {
551
415
  this.Save(breadcrumbs);
552
416
  }
553
417
  }
554
- /** */
418
+ /** Get the breadcrumbs */
555
419
  static Get() {
556
420
  let storage = sessionStorage.getItem(this.storage);
557
421
  if (storage) {
@@ -562,12 +426,12 @@ class Breadcrumbs {
562
426
  }
563
427
  return [];
564
428
  }
565
- /** */
429
+ /** Get the first breadcrumb */
566
430
  static GetFirst() {
567
431
  const breadcrumbs = this.Get();
568
432
  return (breadcrumbs.length > 0) ? breadcrumbs.shift() : null;
569
433
  }
570
- /** */
434
+ /** Get the last breadcrumb */
571
435
  static GetLast() {
572
436
  const breadcrumbs = this.Get();
573
437
  return (breadcrumbs.length > 0) ? breadcrumbs.pop() : null;
@@ -580,8 +444,8 @@ class Breadcrumbs {
580
444
  storage = Object.assign({}, storage, { breadcrumbs });
581
445
  sessionStorage.setItem(this.storage, JSON.stringify(storage));
582
446
  }
583
- /** */
584
- static Remove(path) {
447
+ /** Removes one breadcrumb by route */
448
+ static RemoveByPath(path) {
585
449
  let breadcrumbs = this.Get();
586
450
  const index = breadcrumbs.findIndex(x => x.path.toLowerCase().trim() === path.toLowerCase().trim());
587
451
  if (index >= 0) {
@@ -589,15 +453,15 @@ class Breadcrumbs {
589
453
  this.Save(breadcrumbs);
590
454
  }
591
455
  }
592
- /** */
593
- static SetLast(page, path) {
456
+ /** Update the last breadcrumb */
457
+ static UpdateLast(page, path) {
594
458
  const breadcrumbs = this.Get();
595
459
  if (breadcrumbs.length > 0) {
596
460
  breadcrumbs[breadcrumbs.length - 1] = { page, path };
597
461
  this.Save(breadcrumbs);
598
462
  }
599
463
  }
600
- /** */
464
+ /** Remove the last breadcrumb */
601
465
  static RemoveLast() {
602
466
  const breadcrumbs = this.Get();
603
467
  if (breadcrumbs.length > 0) {
@@ -608,7 +472,7 @@ class Breadcrumbs {
608
472
  }
609
473
 
610
474
  const GridTemplates = {
611
- /** Template for boolean property */
475
+ /** Set Active/Disabled values, template for boolean property */
612
476
  isActiveTemplate: (item) => {
613
477
  if (item.value) {
614
478
  return `
@@ -625,22 +489,89 @@ const GridTemplates = {
625
489
  `;
626
490
  }
627
491
  },
628
- /** Template for boolean property */
492
+ /** Enable switch by row, template for boolean property */
629
493
  coerSwitchTemplate: (item) => ({
630
494
  isInput: true,
631
495
  tooltip: `${item.value ? 'Active' : 'Disabled'}`
632
496
  }),
633
- /** Template for text property */
497
+ /** Enable textbox by row, template for text property */
634
498
  coerTextboxTemplate: (item) => ({
635
499
  isInput: true,
636
500
  isInvalid: item.value.length <= 0
637
501
  }),
638
- /** Template for text property */
502
+ /** Template for icons */
639
503
  coerIconTemplate: (icon, color = 'black') => {
640
504
  return `<i class='${icon} d-block w-100 text-center' style='color: ${color};'></i>`;
641
505
  }
642
506
  };
643
507
 
508
+ /** Provides several methods for collection manipulation */
509
+ class Collections {
510
+ /** Set an index and concat more arrays of the same type */
511
+ static SetIndex(array, ...args) {
512
+ let index = 0;
513
+ for (const arg of args) {
514
+ array = Tools.BreakReference(array).concat(Tools.BreakReference(arg));
515
+ }
516
+ return Tools.BreakReference(array).map(item => Object.assign({ index: index++ }, item));
517
+ }
518
+ /** Sort an array in ascending order by property */
519
+ static SortBy(array, property, propertyType = 'string') {
520
+ switch (propertyType) {
521
+ case 'string': {
522
+ return array.sort((x, y) => {
523
+ if (String(x[property]).toUpperCase().trim() < String(y[property]).toUpperCase().trim())
524
+ return -1;
525
+ else if (String(x[property]).toUpperCase().trim() > String(y[property]).toUpperCase().trim())
526
+ return 1;
527
+ else
528
+ return 0;
529
+ });
530
+ }
531
+ case 'number': {
532
+ return array.sort((x, y) => Number(x[property] - Number(y[property])));
533
+ }
534
+ }
535
+ }
536
+ /** Sort an array in descending order by property */
537
+ static SortByDesc(array, property, propertyType = 'string') {
538
+ switch (propertyType) {
539
+ case 'string': {
540
+ return array.sort((x, y) => {
541
+ if (String(x[property]).toUpperCase().trim() < String(y[property]).toUpperCase().trim())
542
+ return 1;
543
+ else if (String(x[property]).toUpperCase().trim() > String(y[property]).toUpperCase().trim())
544
+ return -1;
545
+ else
546
+ return 0;
547
+ });
548
+ }
549
+ case 'number': {
550
+ return array.sort((x, y) => Number(Number(y[property])) - x[property]);
551
+ }
552
+ }
553
+ }
554
+ /** */
555
+ static Distinct(array, ...args) {
556
+ for (const arg of args) {
557
+ array = Tools.BreakReference(array).concat(Tools.BreakReference(arg));
558
+ }
559
+ return Array.from(new Set(array));
560
+ }
561
+ /** */
562
+ static Except(array, filter, ...properties) {
563
+ const result = [];
564
+ for (const item of array) {
565
+ if (typeof item === 'object' && Tools.IsNotNull(properties) && properties.length > 0) {
566
+ if (!filter.some(x => x[properties[0]] === item[properties[0]])) {
567
+ result.push(item);
568
+ }
569
+ }
570
+ }
571
+ return [...result];
572
+ }
573
+ }
574
+
644
575
  const CONTROL_VALUE = (component) => {
645
576
  return {
646
577
  provide: NG_VALUE_ACCESSOR,
@@ -648,44 +579,46 @@ const CONTROL_VALUE = (component) => {
648
579
  multi: true
649
580
  };
650
581
  };
582
+ /** Implements the ControlValueAccessor interface to build a components */
651
583
  class ControlValue {
652
584
  constructor() {
585
+ //Variables
653
586
  this._isTouched = false;
654
587
  }
588
+ /** Property to validate if the component has been touched */
655
589
  get isTouched() {
656
590
  return this._isTouched;
657
591
  }
658
- /** */
592
+ /** Sets the value of the component when it is created */
593
+ writeValue(value) {
594
+ this._value = value;
595
+ }
596
+ /** Sets the value of the component when it is updated */
597
+ registerOnChange(callback) {
598
+ this._UpdateValue = callback;
599
+ }
600
+ /** Sets the component's touched status when it is updated */
601
+ registerOnTouched(callback) {
602
+ this._IsTouched = callback;
603
+ }
604
+ /** Sets the value of the component */
659
605
  SetValue(value) {
660
606
  if (typeof this._UpdateValue === 'function') {
661
607
  this._UpdateValue(value);
662
608
  }
663
609
  this._value = value;
664
610
  }
665
- /** */
611
+ /** Sets whether the component has been touched */
666
612
  SetTouched(isTouched) {
667
613
  if (typeof this._IsTouched === 'function') {
668
614
  this._IsTouched(isTouched);
669
615
  }
670
616
  this._isTouched = isTouched;
671
617
  }
672
- /** */
673
- writeValue(value) {
674
- this._value = value;
675
- }
676
- /** */
677
- registerOnChange(callback) {
678
- this._UpdateValue = callback;
679
- }
680
- /** */
681
- registerOnTouched(callback) {
682
- this._IsTouched = callback;
683
- }
684
- /** */
685
- setDisabledState(isDisabled) { }
686
618
  }
687
619
 
688
- class DateTime {
620
+ /** Provides several methods for dates manipulation */
621
+ class Dates {
689
622
  /** Get UTC Offset */
690
623
  static GetOffset() {
691
624
  return moment().utcOffset();
@@ -699,69 +632,60 @@ class DateTime {
699
632
  date = new Date(date.toString());
700
633
  return moment(date).format('YYYY-MM-DD HH:mm:ss');
701
634
  }
702
- /** Convert UTC Date to Local Zone */
635
+ /** Convert UTC Date to Local Zone. YYYY-MM-DD HH:mm:ss */
703
636
  static ToLocalZone(date) {
704
- date = DateTime.GetFormatDB(date);
705
- return moment(date).add(DateTime.GetOffset(), 'minutes').format('YYYY-MM-DD HH:mm:ss');
637
+ date = Dates.GetFormatDB(date);
638
+ return moment(date).add(Dates.GetOffset(), 'minutes').format('YYYY-MM-DD HH:mm:ss');
706
639
  }
707
- /** Convert Local Zone Date to UTC */
640
+ /** Convert Local Zone Date to UTC. YYYY-MM-DD HH:mm:ss */
708
641
  static ToUTC(date) {
709
- date = DateTime.GetFormatDB(date);
710
- return moment(date).subtract(DateTime.GetOffset(), 'minutes').format('YYYY-MM-DD HH:mm:ss');
642
+ date = Dates.GetFormatDB(date);
643
+ return moment(date).subtract(Dates.GetOffset(), 'minutes').format('YYYY-MM-DD HH:mm:ss');
711
644
  }
712
645
  /** MMM, DD YYYY */
713
646
  static GetDateFormat(date) {
714
- date = DateTime.GetFormatDB(date);
647
+ date = Dates.GetFormatDB(date);
715
648
  return moment(date).parseZone().local(true).format('MMM, DD YYYY');
716
649
  }
717
650
  /** MMM, DD YYYY at hh:mm a */
718
651
  static GetDateTimeFormat(date) {
719
- date = DateTime.GetFormatDB(date);
652
+ date = Dates.GetFormatDB(date);
720
653
  return moment(date).parseZone().local(true).format('MMM, DD YYYY - hh:mm a').replace('-', 'at');
721
654
  }
722
655
  /** */
723
656
  static IsValidDate(date) {
724
- if (Tools.IsOnlyWhiteSpace(date))
657
+ try {
658
+ if (Tools.IsOnlyWhiteSpace(date))
659
+ return false;
660
+ date = Dates.GetFormatDB(date);
661
+ return moment(date).isValid();
662
+ }
663
+ catch {
725
664
  return false;
726
- date = DateTime.GetFormatDB(date);
727
- return moment(date).isValid();
728
- }
729
- /** */
730
- static SetFirstHour(date = '', format = 'database') {
731
- if (Tools.IsOnlyWhiteSpace(date))
732
- date = moment();
733
- else {
734
- date = DateTime.GetFormatDB(date);
735
- date = moment(date);
736
665
  }
737
- date = date.set('hour', 0).set('minute', 0).set('second', 0).set('millisecond', 0);
738
- return (format === 'database')
739
- ? DateTime.GetFormatDB(date)
740
- : DateTime.GetDateFormat(date);
741
666
  }
742
- /** */
743
- static SetLastHour(date = '', format = 'database') {
744
- if (Tools.IsOnlyWhiteSpace(date))
745
- date = moment();
746
- else {
747
- date = DateTime.GetFormatDB(date);
748
- date = moment(date);
749
- }
750
- date = date.set('hour', 23).set('minute', 59).set('second', 59).set('millisecond', 59);
751
- return (format === 'database')
752
- ? DateTime.GetFormatDB(date)
753
- : DateTime.GetDateFormat(date);
667
+ /** YYYY-MM-DD HH:mm:ss */
668
+ static SetFirstHour(date) {
669
+ date = Dates.GetFormatDB(date);
670
+ date = moment(date).set('hour', 0).set('minute', 0).set('second', 0).set('millisecond', 0);
671
+ return Dates.GetFormatDB(date);
672
+ }
673
+ /** YYYY-MM-DD HH:mm:ss */
674
+ static SetLastHour(date) {
675
+ date = Dates.GetFormatDB(date);
676
+ date = moment(date).set('hour', 23).set('minute', 59).set('second', 59).set('millisecond', 59);
677
+ return Dates.GetFormatDB(date);
754
678
  }
755
679
  }
756
680
 
757
- class ElementsHTML {
681
+ class HTMLElements {
758
682
  /** */
759
683
  static { this.GetElement = (selector) => {
760
684
  return document.querySelector(selector);
761
685
  }; }
762
686
  /** */
763
- static { this.GetCssValueBy = (selector, style) => {
764
- return ElementsHTML.GetCssValue(document.querySelector(selector), style);
687
+ static { this.GetCssValueBySelector = (selector, style) => {
688
+ return HTMLElements.GetCssValue(document.querySelector(selector), style);
765
689
  }; }
766
690
  /** */
767
691
  static { this.GetCssValue = (element, style) => {
@@ -769,7 +693,7 @@ class ElementsHTML {
769
693
  ? window.getComputedStyle(element).getPropertyValue(style)
770
694
  : '';
771
695
  }; }
772
- /** Get width in px */
696
+ /** Gets the width of the element in px */
773
697
  static { this.GetElementWidth = (element, ...args) => {
774
698
  let width = 0;
775
699
  if (Tools.IsNotNull(element) && Tools.IsNotOnlyWhiteSpace(element?.offsetWidth)) {
@@ -784,7 +708,7 @@ class ElementsHTML {
784
708
  }
785
709
  return `${width}px`;
786
710
  }; }
787
- /** Get height in px */
711
+ /** Gets the height of the element in px */
788
712
  static { this.GetElementHeight = (element, ...args) => {
789
713
  let height = 0;
790
714
  if (Tools.IsNotNull(element) && Tools.IsNotOnlyWhiteSpace(element?.offsetHeight)) {
@@ -803,7 +727,7 @@ class ElementsHTML {
803
727
  static { this.IsInvalidElement = (element) => {
804
728
  let isInvalid = true;
805
729
  if (Tools.IsNotNull(element)) {
806
- if (typeof element == 'object') {
730
+ if (typeof element === 'object') {
807
731
  const properties = Tools.GetPropertyList(element);
808
732
  if (properties.includes('_isTouched') && properties.includes('_value')) {
809
733
  isInvalid = element.isTouched && Tools.IsOnlyWhiteSpace(element.value);
@@ -812,7 +736,7 @@ class ElementsHTML {
812
736
  }
813
737
  return isInvalid;
814
738
  }; }
815
- /** Get color in hexadecimal format */
739
+ /** Gets the color of the element in hexadecimal */
816
740
  static { this.GetElementColor = (element) => {
817
741
  if (Tools.IsNotNull(element)) {
818
742
  let rgb = window.getComputedStyle(element).getPropertyValue('color');
@@ -829,49 +753,36 @@ class ElementsHTML {
829
753
  }
830
754
  ;
831
755
 
832
- class StringTools {
756
+ /** Provides several methods for string manipulation */
757
+ class Strings {
833
758
  /** Sets the first character to lowercase */
834
759
  static FirstCharToLower(value) {
835
- if (Tools.IsOnlyWhiteSpace(value))
836
- return '';
837
- const array = [];
838
- for (let i = 0; i < String(value).length; i++) {
839
- if (i === 0)
840
- array.push(String(value)[i].toLowerCase());
841
- else
842
- array.push(String(value)[i]);
843
- }
844
- return array.join('');
760
+ return (Tools.IsNotOnlyWhiteSpace(value))
761
+ ? String(value).charAt(0).toLowerCase() + String(value).slice(1)
762
+ : '';
845
763
  }
846
764
  /** Sets the first character to uppercase */
847
765
  static FirstCharToUpper(value) {
848
- if (Tools.IsOnlyWhiteSpace(value))
849
- return '';
850
- const array = [];
851
- for (let i = 0; i < String(value).length; i++) {
852
- if (i === 0)
853
- array.push(String(value)[i].toUpperCase());
854
- else
855
- array.push(String(value)[i]);
856
- }
857
- return array.join('');
766
+ return (Tools.IsNotOnlyWhiteSpace(value))
767
+ ? String(value).charAt(0).toUpperCase() + String(value).slice(1)
768
+ : '';
858
769
  }
859
770
  /** Clean extra whitespaces */
860
771
  static CleanUpBlanks(value) {
861
- return (Tools.IsNotOnlyWhiteSpace(value))
862
- ? String(value).split(' ').filter(x => x.length > 0).join(' ')
772
+ return value && Tools.IsNotOnlyWhiteSpace(value)
773
+ ? String(value).replace(/\s+/g, ' ').trim()
863
774
  : '';
864
775
  }
865
776
  /** Apply title formatting */
866
777
  static ToTitle(value) {
867
778
  return (Tools.IsNotOnlyWhiteSpace(value))
868
- ? String(value).split(' ').filter(x => x.length > 0).map(x => StringTools.FirstCharToUpper(x.toLowerCase())).join(' ')
779
+ ? String(value).split(' ').filter(x => x.length > 0).map(x => Strings.FirstCharToUpper(x.toLowerCase())).join(' ')
869
780
  : '';
870
781
  }
871
782
  /** Removes the last character */
872
783
  static RemoveLastChar(value) {
873
784
  return Tools.IsNotOnlyWhiteSpace(value)
874
- ? String(value).trimEnd().substring(0, String(value).length - 1).trimEnd()
785
+ ? String(value).trimEnd().slice(0, -1)
875
786
  : '';
876
787
  }
877
788
  /** Removes accents */
@@ -941,7 +852,7 @@ class Files {
941
852
  }
942
853
  return null;
943
854
  }
944
- /** Is Excel File */
855
+ /** */
945
856
  static IsExcel(file) {
946
857
  const EXTENSION = Files.GetExtension(file);
947
858
  return Tools.IsNotNull(EXTENSION)
@@ -965,7 +876,7 @@ class Files {
965
876
  });
966
877
  //Get Headers
967
878
  for (const column in dataSheet[0]) {
968
- columns.push(StringTools.FirstCharToLower(String(dataSheet[0][column]).replaceAll(' ', '')));
879
+ columns.push(Strings.FirstCharToLower(String(dataSheet[0][column]).replaceAll(' ', '')));
969
880
  }
970
881
  //Get Rows
971
882
  rows = XLSX.utils.sheet_to_json(sheet, { header: columns });
@@ -983,8 +894,8 @@ class Files {
983
894
  }
984
895
  /** Export to excel file */
985
896
  static ExportExcel(data, fileName = 'coer_report', sheetName = 'Sheet1') {
986
- sheetName = StringTools.CleanUpBlanks(sheetName);
987
- fileName = StringTools.CleanUpBlanks(fileName);
897
+ sheetName = Strings.CleanUpBlanks(sheetName);
898
+ fileName = Strings.CleanUpBlanks(fileName);
988
899
  if (fileName.endsWith('.xls') || fileName.endsWith('.xlsx') || fileName.endsWith('.csv')) {
989
900
  if (fileName.endsWith('.xls')) {
990
901
  fileName = fileName.replaceAll('.xls', '.xlsx');
@@ -1014,9 +925,10 @@ class Files {
1014
925
  }
1015
926
  }
1016
927
 
928
+ /** Controls user information in localStorage */
1017
929
  class User {
1018
930
  static { this.storage = 'COER-System'; }
1019
- /** */
931
+ /** Save the user to localStorage */
1020
932
  static Set(user) {
1021
933
  let storage = localStorage.getItem(this.storage);
1022
934
  if (storage) {
@@ -1029,7 +941,7 @@ class User {
1029
941
  }
1030
942
  localStorage.setItem(this.storage, JSON.stringify(storage));
1031
943
  }
1032
- /** */
944
+ /** Get the user from localStorage */
1033
945
  static Get() {
1034
946
  let storage = localStorage.getItem(this.storage);
1035
947
  if (storage) {
@@ -1051,15 +963,16 @@ class User {
1051
963
  }
1052
964
  return null;
1053
965
  }
1054
- /** */
1055
- static LogIn() {
966
+ /** Validates if the user and the jwt exist in the localStorage */
967
+ static IsLogIn() {
1056
968
  let storage = localStorage.getItem(this.storage);
1057
969
  storage = JSON.parse(storage);
1058
970
  return Tools.IsNotNull(storage)
1059
971
  && Tools.IsNotNull(storage?.user)
972
+ && Tools.IsNotOnlyWhiteSpace(storage?.user?.user)
1060
973
  && Tools.IsNotOnlyWhiteSpace(storage?.user?.jwt);
1061
974
  }
1062
- /** */
975
+ /** Removes data from localStorage and sessionStorage, except for the user and navigate to root */
1063
976
  static LogOut() {
1064
977
  let storage = localStorage.getItem(this.storage);
1065
978
  sessionStorage.removeItem(this.storage);
@@ -1210,15 +1123,63 @@ class Menu {
1210
1123
  }; }
1211
1124
  }
1212
1125
 
1126
+ /** Provides several methods for string manipulation */
1127
+ class Numbers {
1128
+ /** Validates if the value is a numeric type */
1129
+ static IsNumber(value) {
1130
+ return typeof value === 'number' && !Number.isNaN(Number(value));
1131
+ }
1132
+ /** Validates if the value isn't a numeric type */
1133
+ static IsNotNumber(value) {
1134
+ return !this.IsNumber(value);
1135
+ }
1136
+ /** Return a string with numeric format */
1137
+ static GetNumericFormat(value, decimals = 0) {
1138
+ if (this.IsNotNumber(value)) {
1139
+ return '0';
1140
+ }
1141
+ let valueInteger = '';
1142
+ let valueDecimal = '';
1143
+ value = value.toString().replaceAll(' ', '');
1144
+ if (value.includes('.') || (decimals > 0)) {
1145
+ valueInteger = value.includes('.') ? value.split('.')[0] : value;
1146
+ if (decimals > 0) {
1147
+ const PADDING = decimals - valueDecimal.length;
1148
+ valueDecimal = value.includes('.') ? value.split('.')[1] : '';
1149
+ for (let i = 0; i < PADDING; i++)
1150
+ valueDecimal += '0';
1151
+ valueDecimal = valueDecimal.substring(0, decimals);
1152
+ valueDecimal = `.${valueDecimal}`;
1153
+ }
1154
+ }
1155
+ else {
1156
+ valueInteger = value;
1157
+ }
1158
+ let counter = 0;
1159
+ const VALUE_INTEGER_ARRAY = [];
1160
+ for (const char of valueInteger.split('').reverse()) {
1161
+ if (counter == 3) {
1162
+ VALUE_INTEGER_ARRAY.push(',');
1163
+ counter = 0;
1164
+ }
1165
+ VALUE_INTEGER_ARRAY.push(char);
1166
+ ++counter;
1167
+ }
1168
+ valueInteger = VALUE_INTEGER_ARRAY.reverse().join('');
1169
+ return `${valueInteger}${valueDecimal}`;
1170
+ }
1171
+ }
1172
+
1173
+ /** Controls source information in sessionStorage */
1213
1174
  class Source {
1214
1175
  static { this.storage = 'COER-System'; }
1215
- /** */
1216
- static Set(page) {
1176
+ /** Save the source to sessionStorage and add the breadcrumb */
1177
+ static Set(pageName) {
1217
1178
  const ROUTER = inject(Router);
1218
1179
  let path = ROUTER.url;
1219
1180
  if (path.includes('?'))
1220
1181
  path = path.split('?')[0];
1221
- Breadcrumbs.Add(page, path);
1182
+ Breadcrumbs.Add(pageName, path);
1222
1183
  const breadcrumbs = Breadcrumbs.Get();
1223
1184
  if (breadcrumbs.length >= 2) {
1224
1185
  breadcrumbs.pop();
@@ -1236,7 +1197,7 @@ class Source {
1236
1197
  storage = Object.assign({}, storage, { source });
1237
1198
  sessionStorage.setItem(this.storage, JSON.stringify(storage));
1238
1199
  }
1239
- /** */
1200
+ /** Get the source from sessionStorage */
1240
1201
  static Get() {
1241
1202
  let storage = sessionStorage.getItem(this.storage);
1242
1203
  if (storage) {
@@ -1247,19 +1208,18 @@ class Source {
1247
1208
  }
1248
1209
  return null;
1249
1210
  }
1250
- /** */
1211
+ /** Gets the first breadcrumb from sessionStorage */
1251
1212
  static GetRoot() {
1252
- const breadcrumbs = Breadcrumbs.Get();
1253
- return (breadcrumbs.length > 0) ? breadcrumbs.shift() : null;
1213
+ return Breadcrumbs.GetFirst();
1254
1214
  }
1255
- /** */
1215
+ /** Save the pageResponse to sessionStorage */
1256
1216
  static SetPageResponse(pageResponse) {
1257
1217
  let storage = sessionStorage.getItem(this.storage);
1258
1218
  storage = JSON.parse(storage);
1259
1219
  storage = Object.assign({}, storage, { pageResponse });
1260
1220
  sessionStorage.setItem(this.storage, JSON.stringify(storage));
1261
1221
  }
1262
- /** */
1222
+ /** Gets the pageResponse from sessionStorage */
1263
1223
  static GetPageResponse() {
1264
1224
  let storage = sessionStorage.getItem(this.storage);
1265
1225
  if (storage) {
@@ -1270,7 +1230,7 @@ class Source {
1270
1230
  }
1271
1231
  return null;
1272
1232
  }
1273
- /** */
1233
+ /** Remove the pageResponse from sessionStorage */
1274
1234
  static ClearPageResponse() {
1275
1235
  let storage = sessionStorage.getItem(this.storage);
1276
1236
  storage = JSON.parse(storage);
@@ -1282,17 +1242,9 @@ class Source {
1282
1242
  sessionStorage.setItem(this.storage, JSON.stringify(storage));
1283
1243
  }
1284
1244
  }
1285
- /** */
1245
+ /** Remove the sessionStorage */
1286
1246
  static Reset() {
1287
- let storage = localStorage.getItem(this.storage);
1288
- storage = JSON.parse(storage);
1289
- const user = storage?.user || null;
1290
- localStorage.removeItem(this.storage);
1291
1247
  sessionStorage.removeItem(this.storage);
1292
- if (Tools.IsNotNull(user)) {
1293
- storage = Object.assign({ user });
1294
- localStorage.setItem(this.storage, JSON.stringify(storage));
1295
- }
1296
1248
  }
1297
1249
  }
1298
1250
 
@@ -1301,7 +1253,7 @@ class Page {
1301
1253
  //Injection
1302
1254
  this.alert = inject(CoerAlert);
1303
1255
  this.router = inject(Router);
1304
- this.activatedRoute = inject(ActivatedRoute);
1256
+ this.__activatedRoute = inject(ActivatedRoute);
1305
1257
  /** */
1306
1258
  this.isUpdate = false;
1307
1259
  /** */
@@ -1321,30 +1273,25 @@ class Page {
1321
1273
  /** */
1322
1274
  this.goBack = { show: false };
1323
1275
  //Private Variables
1324
- this._path = '';
1325
- this._page = '';
1326
- this._source = null;
1327
- this._preventDestroy = false;
1276
+ this.__path = '';
1277
+ this.__page = '';
1278
+ this.__source = null;
1279
+ this.__preventDestroy = false;
1328
1280
  /** */
1329
1281
  this.GoBack = (path) => (() => {
1330
1282
  if (path)
1331
- Breadcrumbs.Remove(path);
1283
+ Breadcrumbs.RemoveByPath(path);
1332
1284
  else
1333
1285
  Breadcrumbs.RemoveLast();
1334
1286
  });
1335
- //Grid Templates
1336
- this.isActiveTemplate = GridTemplates.isActiveTemplate;
1337
- this.coerSwitchTemplate = GridTemplates.coerSwitchTemplate;
1338
- this.coerTextboxTemplate = GridTemplates.coerTextboxTemplate;
1339
- this.coerIconTemplate = GridTemplates.coerIconTemplate;
1340
- //Tools
1287
+ /** Returns true if the value is null or undefined, false otherwise */
1341
1288
  this.IsNull = Tools.IsNull;
1289
+ /** Returns true if the value is not null or undefined, false otherwise */
1342
1290
  this.IsNotNull = Tools.IsNotNull;
1291
+ /** Returns true if the value is null or undefined or is an empty string or contains only whitespace, false otherwise */
1343
1292
  this.IsOnlyWhiteSpace = Tools.IsOnlyWhiteSpace;
1293
+ /** Returns true if it has a string value and is not all whitespace, false otherwise */
1344
1294
  this.IsNotOnlyWhiteSpace = Tools.IsNotOnlyWhiteSpace;
1345
- this.Sleep = Tools.Sleep;
1346
- //ElementsHTML
1347
- this.IsInvalidElement = ElementsHTML.IsInvalidElement;
1348
1295
  if (page.toUpperCase().toUpperCase() === 'HOME')
1349
1296
  Source.Reset();
1350
1297
  this.SetPageName(page);
@@ -1357,8 +1304,8 @@ class Page {
1357
1304
  this.__GetPageResponse();
1358
1305
  }
1359
1306
  async ngAfterViewInit() {
1360
- this.routeParams = this.activatedRoute.snapshot.params;
1361
- this.queryParams = this.activatedRoute.snapshot.queryParams;
1307
+ this.routeParams = this.__activatedRoute.snapshot.params;
1308
+ this.queryParams = this.__activatedRoute.snapshot.queryParams;
1362
1309
  await Tools.Sleep();
1363
1310
  this.isReadyPage = true;
1364
1311
  this.RunPage();
@@ -1366,7 +1313,7 @@ class Page {
1366
1313
  this.enableAnimations = true;
1367
1314
  }
1368
1315
  ngOnDestroy() {
1369
- if (!this._preventDestroy)
1316
+ if (!this.__preventDestroy)
1370
1317
  this.ClearPageResponse();
1371
1318
  }
1372
1319
  /** Main method. Starts after ngAfterViewInit() */
@@ -1374,32 +1321,32 @@ class Page {
1374
1321
  ;
1375
1322
  /** Rename the last breadcrumb and update the url id */
1376
1323
  SetPageName(name, id = null) {
1377
- this._page = name;
1378
- this._path = this.router.url;
1379
- if (this._path.includes('?'))
1380
- this._path = this._path.split('?')[0];
1324
+ this.__page = name;
1325
+ this.__path = this.router.url;
1326
+ if (this.__path.includes('?'))
1327
+ this.__path = this.__path.split('?')[0];
1381
1328
  if (id) {
1382
- const PATH_ARRAY = this._path.split('/');
1329
+ const PATH_ARRAY = this.__path.split('/');
1383
1330
  const PATH_ID = Tools.BreakReference(PATH_ARRAY).pop();
1384
1331
  if (PATH_ID) {
1385
1332
  PATH_ARRAY[PATH_ARRAY.length - 1] = String(id);
1386
- this._path = PATH_ARRAY.join('/');
1333
+ this.__path = PATH_ARRAY.join('/');
1387
1334
  }
1388
1335
  }
1389
1336
  if (this.breadcrumbs.length > 0) {
1390
1337
  this.breadcrumbs[this.breadcrumbs.length - 1].page = name;
1391
- this.breadcrumbs[this.breadcrumbs.length - 1].path = this._path;
1392
- Breadcrumbs.SetLast(name, this._path);
1338
+ this.breadcrumbs[this.breadcrumbs.length - 1].path = this.__path;
1339
+ Breadcrumbs.UpdateLast(name, this.__path);
1393
1340
  }
1394
- this.router.navigateByUrl(this._path);
1341
+ this.router.navigateByUrl(this.__path);
1395
1342
  }
1396
1343
  /** */
1397
1344
  __SetSource() {
1398
- Source.Set(this._page);
1345
+ Source.Set(this.__page);
1399
1346
  }
1400
1347
  /** */
1401
1348
  __GetSource() {
1402
- this._source = Source.Get();
1349
+ this.__source = Source.Get();
1403
1350
  }
1404
1351
  /** */
1405
1352
  __GetPageResponse() {
@@ -1407,7 +1354,7 @@ class Page {
1407
1354
  }
1408
1355
  /** */
1409
1356
  __GetNavigation() {
1410
- if (this._source) {
1357
+ if (this.__source) {
1411
1358
  this.breadcrumbs = Breadcrumbs.Get().map(item => Object.assign({
1412
1359
  page: item.page,
1413
1360
  path: item.path,
@@ -1415,21 +1362,21 @@ class Page {
1415
1362
  }));
1416
1363
  }
1417
1364
  else
1418
- this.breadcrumbs = [{ page: this._page }];
1365
+ this.breadcrumbs = [{ page: this.__page }];
1419
1366
  }
1420
1367
  /** */
1421
1368
  __SetGoBack() {
1422
- if (this._source) {
1369
+ if (this.__source) {
1423
1370
  this.goBack = {
1424
1371
  show: true,
1425
- path: this._source.path,
1372
+ path: this.__source.path,
1426
1373
  click: this.GoBack()
1427
1374
  };
1428
1375
  }
1429
1376
  }
1430
1377
  /** */
1431
1378
  __GetPageMode() {
1432
- const subscribe$ = this.activatedRoute.data.subscribe({
1379
+ const subscribe$ = this.__activatedRoute.data.subscribe({
1433
1380
  next: ({ module, submodule, page }) => {
1434
1381
  const menuAccess = Menu.GetMenuAccess().find(x => Tools.AvoidNull(x.module, 'string') === Tools.AvoidNull(module, 'string')
1435
1382
  && Tools.AvoidNull(x.submodule, 'string') === Tools.AvoidNull(submodule, 'string')
@@ -1442,18 +1389,18 @@ class Page {
1442
1389
  }
1443
1390
  /** Navigate to previous page */
1444
1391
  GoToSource(pageResponse = null) {
1445
- if (this._source) {
1392
+ if (this.__source) {
1446
1393
  Breadcrumbs.RemoveLast();
1447
1394
  this.SetPageResponse(pageResponse);
1448
1395
  this.RemovePageFilter();
1449
- Tools.Sleep().then(_ => this.router.navigateByUrl(this._source.path));
1396
+ Tools.Sleep().then(_ => this.router.navigateByUrl(this.__source.path));
1450
1397
  }
1451
1398
  }
1452
1399
  ;
1453
1400
  /** */
1454
1401
  SetPageResponse(pageResponse = null) {
1455
1402
  if (Tools.IsNotNull(pageResponse)) {
1456
- this._preventDestroy = true;
1403
+ this.__preventDestroy = true;
1457
1404
  Source.SetPageResponse(pageResponse);
1458
1405
  }
1459
1406
  }
@@ -1471,21 +1418,21 @@ class Page {
1471
1418
  /** */
1472
1419
  SetPageFilters(filters) {
1473
1420
  this.pageFilters = Tools.BreakReference(filters);
1474
- Filters.Add(this.pageFilters, this._path);
1421
+ Filters.Add(this.pageFilters, this.__path);
1475
1422
  }
1476
1423
  /** */
1477
1424
  __GetPageFilter() {
1478
- this.pageFilters = Filters.Get(this._path);
1425
+ this.pageFilters = Filters.Get(this.__path);
1479
1426
  }
1480
1427
  /** */
1481
1428
  RemovePageFilter() {
1482
1429
  this.pageFilters = {};
1483
- Filters.Remove(this._path);
1430
+ Filters.Remove(this.__path);
1484
1431
  }
1485
- /** */
1486
- Log(value, log = null) {
1487
- if (Tools.IsNotNull(log))
1488
- console.log({ log, value });
1432
+ /** Emit a console.log() */
1433
+ Log(value, logName = null) {
1434
+ if (Tools.IsNotNull(logName))
1435
+ console.log({ log: logName, value });
1489
1436
  else
1490
1437
  console.log(value);
1491
1438
  }
@@ -1501,33 +1448,38 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImpor
1501
1448
  }] }] });
1502
1449
 
1503
1450
  class Screen {
1451
+ /** Gets the width of the browser window */
1504
1452
  static get WINDOW_WIDTH() {
1505
1453
  return window.innerWidth;
1506
1454
  }
1455
+ /** Gets the height of the screen window */
1507
1456
  static get WINDOW_HEIGHT() {
1508
1457
  return window.innerHeight;
1509
1458
  }
1459
+ /** Gets the width of the device screen */
1510
1460
  static get DEVICE_WIDTH() {
1511
1461
  return window.screen.width;
1512
1462
  }
1463
+ /** Gets the height of the device screen */
1513
1464
  static get DEVICE_HEIGHT() {
1514
1465
  return window.screen.height;
1515
1466
  }
1467
+ /** gets the breakpoint based on the width of the browsing window */
1516
1468
  static get BREAKPOINT() {
1517
- if (window.innerWidth < 576)
1469
+ if (this.WINDOW_WIDTH < 576)
1518
1470
  return 'xs';
1519
- else if (window.innerWidth >= 576 && window.innerWidth < 768)
1471
+ else if (this.WINDOW_WIDTH >= 576 && this.WINDOW_WIDTH < 768)
1520
1472
  return 'sm';
1521
- else if (window.innerWidth >= 768 && window.innerWidth < 992)
1473
+ else if (this.WINDOW_WIDTH >= 768 && this.WINDOW_WIDTH < 992)
1522
1474
  return 'md';
1523
- else if (window.innerWidth >= 992 && window.innerWidth < 1200)
1475
+ else if (this.WINDOW_WIDTH >= 992 && this.WINDOW_WIDTH < 1200)
1524
1476
  return 'lg';
1525
- else if (window.innerWidth >= 1200 && window.innerWidth < 1400)
1477
+ else if (this.WINDOW_WIDTH >= 1200 && this.WINDOW_WIDTH < 1400)
1526
1478
  return 'xl';
1527
1479
  else
1528
1480
  return 'xxl';
1529
1481
  }
1530
- /** */
1482
+ /** Provides an observable for screen resizing */
1531
1483
  static { this.Resize = new Observable(subscriber => {
1532
1484
  const handleResize = () => {
1533
1485
  subscriber.next({
@@ -1543,7 +1495,7 @@ class Screen {
1543
1495
  window.removeEventListener("load", handleResize);
1544
1496
  };
1545
1497
  }); }
1546
- /** */
1498
+ /** Provides an observable for the browser buttons */
1547
1499
  static { this.BackButtonBrowser = new Observable(subscriber => {
1548
1500
  const handlePopState = (popStateEvent) => {
1549
1501
  if (popStateEvent.state && popStateEvent.target) {
@@ -1557,35 +1509,37 @@ class Screen {
1557
1509
  }); }
1558
1510
  }
1559
1511
 
1512
+ /** Use this component to extend the functionality of a page section. */
1560
1513
  class Section {
1561
1514
  constructor() {
1562
- //Injection
1515
+ /** */
1563
1516
  this.alert = inject(CoerAlert);
1517
+ /** */
1564
1518
  this.router = inject(Router);
1565
- //Inputs
1519
+ /** */
1566
1520
  this.isLoading = input(false);
1521
+ /** */
1567
1522
  this.isUpdate = input(false);
1568
- //Outputs
1523
+ /** */
1569
1524
  this.onReady = output();
1525
+ /** */
1570
1526
  this.onDestroy = output();
1527
+ /** */
1571
1528
  this.onIsLoading = output();
1529
+ /** */
1572
1530
  this.onUpdated = output();
1573
- //Variables
1531
+ /** */
1574
1532
  this.enableAnimations = false;
1533
+ /** */
1575
1534
  this.isReadySection = false;
1576
- //Grid Templates
1577
- this.isActiveTemplate = GridTemplates.isActiveTemplate;
1578
- this.coerSwitchTemplate = GridTemplates.coerSwitchTemplate;
1579
- this.coerTextboxTemplate = GridTemplates.coerTextboxTemplate;
1580
- this.coerIconTemplate = GridTemplates.coerIconTemplate;
1581
- //Tools
1535
+ /** Returns true if the value is null or undefined, false otherwise */
1582
1536
  this.IsNull = Tools.IsNull;
1537
+ /** Returns true if the value is not null or undefined, false otherwise */
1583
1538
  this.IsNotNull = Tools.IsNotNull;
1539
+ /** Returns true if the value is null or undefined or is an empty string or contains only whitespace, false otherwise */
1584
1540
  this.IsOnlyWhiteSpace = Tools.IsOnlyWhiteSpace;
1541
+ /** Returns true if it has a string value and is not all whitespace, false otherwise */
1585
1542
  this.IsNotOnlyWhiteSpace = Tools.IsNotOnlyWhiteSpace;
1586
- this.Sleep = Tools.Sleep;
1587
- //ElementsHTML
1588
- this.IsInvalidElement = ElementsHTML.IsInvalidElement;
1589
1543
  }
1590
1544
  async ngAfterViewInit() {
1591
1545
  await Tools.Sleep();
@@ -1601,10 +1555,10 @@ class Section {
1601
1555
  /** Main method. Starts after ngAfterViewInit() */
1602
1556
  RunSection() { }
1603
1557
  ;
1604
- /** */
1605
- Log(value, log = null) {
1606
- if (Tools.IsNotNull(log))
1607
- console.log({ log, value });
1558
+ /** Emit a console.log() */
1559
+ Log(value, logName = null) {
1560
+ if (Tools.IsNotNull(logName))
1561
+ console.log({ log: logName, value });
1608
1562
  else
1609
1563
  console.log(value);
1610
1564
  }
@@ -1616,12 +1570,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.1", ngImpor
1616
1570
  args: [{ template: '' }]
1617
1571
  }] });
1618
1572
 
1573
+ /** Provides several methods for handling http requests */
1619
1574
  class Service {
1620
1575
  constructor() {
1621
1576
  //Injections
1622
1577
  this.alert = inject(CoerAlert);
1623
1578
  this.http = inject(HttpClient);
1624
- this.httpCode = {
1579
+ this.HTTP_CODE = {
1625
1580
  Ok: 200,
1626
1581
  Created: 201,
1627
1582
  NoContent: 204,
@@ -1636,12 +1591,12 @@ class Service {
1636
1591
  InnerError: 500
1637
1592
  };
1638
1593
  }
1639
- /** */
1594
+ /** Clear and release a subscription */
1640
1595
  ReleaseSubscription(subscription) {
1641
1596
  if (subscription && !subscription.closed)
1642
1597
  subscription.unsubscribe();
1643
1598
  }
1644
- /** HTTP GET */
1599
+ /** Generates a GET http request */
1645
1600
  HTTP_GET(request, cancelPrevious = true) {
1646
1601
  const responseType = request?.responseType || 'json';
1647
1602
  return new Promise(Resolve => {
@@ -1726,7 +1681,7 @@ class Service {
1726
1681
  }
1727
1682
  });
1728
1683
  }
1729
- /** HTTP POST */
1684
+ /** Generates a POST http request */
1730
1685
  HTTP_POST(request, cancelPrevious = true) {
1731
1686
  return new Promise(Resolve => {
1732
1687
  const responseType = request?.responseType || 'json';
@@ -1811,7 +1766,7 @@ class Service {
1811
1766
  }
1812
1767
  });
1813
1768
  }
1814
- /** HTTP PUT */
1769
+ /** Generates a PUT http request */
1815
1770
  HTTP_PUT(request, cancelPrevious = true) {
1816
1771
  return new Promise(Resolve => {
1817
1772
  const responseType = request?.responseType || 'json';
@@ -1896,7 +1851,7 @@ class Service {
1896
1851
  }
1897
1852
  });
1898
1853
  }
1899
- /** HTTP PATCH */
1854
+ /** Generates a PATCH http request */
1900
1855
  HTTP_PATCH(request, cancelPrevious = true) {
1901
1856
  return new Promise(Resolve => {
1902
1857
  const responseType = request?.responseType || 'json';
@@ -1981,7 +1936,7 @@ class Service {
1981
1936
  }
1982
1937
  });
1983
1938
  }
1984
- /** HTTP DELETE */
1939
+ /** Generates a DELETE http request */
1985
1940
  HTTP_DELETE(request, cancelPrevious = true) {
1986
1941
  return new Promise(Resolve => {
1987
1942
  const responseType = request?.responseType || 'json';
@@ -2066,7 +2021,7 @@ class Service {
2066
2021
  }
2067
2022
  });
2068
2023
  }
2069
- /** */
2024
+ /** Download a csv file from browser */
2070
2025
  DOWNLOAD_CSV(buffer, fileName = '') {
2071
2026
  if (Tools.IsOnlyWhiteSpace(fileName))
2072
2027
  fileName = 'COERSystem';
@@ -2076,7 +2031,7 @@ class Service {
2076
2031
  saveAs(BLOB, fileName);
2077
2032
  return BLOB;
2078
2033
  }
2079
- /** */
2034
+ /** Download a txt file from browser */
2080
2035
  DOWNLOAD_TXT(buffer, fileName = '') {
2081
2036
  if (Tools.IsOnlyWhiteSpace(fileName))
2082
2037
  fileName = 'COERSystem';
@@ -2144,5 +2099,5 @@ class Service {
2144
2099
  * Generated bundle index. Do not edit.
2145
2100
  */
2146
2101
 
2147
- export { Breadcrumbs, CONTROL_VALUE, CoerAlert, Colors, ControlValue, DateTime, ElementsHTML, Files, Filters, GridTemplates, Menu, Page, Screen, Section, Service, Source, StringTools, Tools, User };
2102
+ export { Breadcrumbs, CONTROL_VALUE, CoerAlert, Collections, Colors, ControlValue, Dates, Files, Filters, GridTemplates, HTMLElements, Menu, Numbers, Page, Screen, Section, Service, Source, Strings, Tools, User };
2148
2103
  //# sourceMappingURL=coer-elements-tools.mjs.map