tailjng 0.0.13 → 0.0.15

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 (87) hide show
  1. package/cli/component-manager.js +45 -0
  2. package/cli/dependency-manager.js +52 -0
  3. package/cli/file-operations.js +88 -0
  4. package/cli/index.js +51 -0
  5. package/cli/settings/colors.js +17 -0
  6. package/cli/settings/components-list.js +87 -0
  7. package/cli/settings/header-generator.js +42 -0
  8. package/cli/settings/path-utils.js +50 -0
  9. package/cli/settings/prompt-utils.js +37 -0
  10. package/cli/settings/tailwind-check.js +21 -0
  11. package/fesm2022/tailjng.mjs +903 -25
  12. package/fesm2022/tailjng.mjs.map +1 -1
  13. package/lib/config/tailjng-config.token.d.ts +3 -0
  14. package/lib/interfaces/alert/dialog-alert.interface.d.ts +52 -0
  15. package/lib/interfaces/alert/toast-alert.interface.d.ts +52 -0
  16. package/lib/interfaces/config.interface.d.ts +5 -0
  17. package/lib/interfaces/crud/api-response.d.ts +29 -0
  18. package/lib/interfaces/crud/crud.interface.d.ts +103 -0
  19. package/lib/services/alert/dialog-alert.service.d.ts +24 -0
  20. package/lib/services/alert/toast-alert.service.d.ts +26 -0
  21. package/lib/services/crud/converter-crud.service.d.ts +41 -0
  22. package/lib/services/crud/generic-crud.service.d.ts +81 -0
  23. package/lib/services/http/error-handler-http.service.d.ts +26 -0
  24. package/lib/services/http/params-http.service.d.ts +13 -0
  25. package/lib/services/static/icons.service.d.ts +31 -0
  26. package/lib/services/transformer/calendar.service.d.ts +71 -0
  27. package/package.json +5 -3
  28. package/public-api.d.ts +10 -3
  29. package/src/lib/components/alert/dialog-alert/dialog-alert.component.css +0 -0
  30. package/src/lib/components/alert/dialog-alert/dialog-alert.component.html +72 -0
  31. package/src/lib/components/alert/dialog-alert/dialog-alert.component.ts +66 -0
  32. package/src/lib/components/alert/toast-alert/toast-alert.component.css +5 -0
  33. package/src/lib/components/alert/toast-alert/toast-alert.component.html +76 -0
  34. package/src/lib/components/alert/toast-alert/toast-alert.component.ts +87 -0
  35. package/src/lib/components/button/button.component.css +0 -0
  36. package/src/lib/components/button/button.component.html +36 -0
  37. package/src/lib/components/button/button.component.ts +95 -0
  38. package/src/lib/components/checkbox/input-checkbox/input-checkbox.component.css +0 -0
  39. package/src/lib/components/checkbox/input-checkbox/input-checkbox.component.html +23 -0
  40. package/src/lib/components/checkbox/input-checkbox/input-checkbox.component.ts +44 -0
  41. package/src/lib/components/checkbox/switch-checkbox/switch-checkbox.component.css +0 -0
  42. package/src/lib/components/checkbox/switch-checkbox/switch-checkbox.component.html +26 -0
  43. package/src/lib/components/checkbox/switch-checkbox/switch-checkbox.component.ts +29 -0
  44. package/src/lib/components/color/colors.service.ts +109 -0
  45. package/src/lib/components/dialog/dialog.component.css +8 -0
  46. package/src/lib/components/dialog/dialog.component.html +57 -0
  47. package/src/lib/components/dialog/dialog.component.ts +179 -0
  48. package/src/lib/components/image/viewer-image/viewer-image.component.css +4 -0
  49. package/src/lib/components/image/viewer-image/viewer-image.component.html +75 -0
  50. package/src/lib/components/image/viewer-image/viewer-image.component.ts +131 -0
  51. package/src/lib/components/input/file-input/file-input.component.css +0 -0
  52. package/src/lib/components/input/file-input/file-input.component.html +49 -0
  53. package/src/lib/components/input/file-input/file-input.component.ts +218 -0
  54. package/src/lib/components/input/input/input.component.css +0 -0
  55. package/src/lib/components/input/input/input.component.html +24 -0
  56. package/src/lib/components/input/input/input.component.ts +78 -0
  57. package/src/lib/components/input/range-input/range-input.component.css +0 -0
  58. package/src/lib/components/input/range-input/range-input.component.html +64 -0
  59. package/src/lib/components/input/range-input/range-input.component.ts +78 -0
  60. package/src/lib/components/input/textarea-input/textarea-input.component.css +0 -0
  61. package/src/lib/components/input/textarea-input/textarea-input.component.html +21 -0
  62. package/src/lib/components/input/textarea-input/textarea-input.component.ts +75 -0
  63. package/src/lib/components/label/label.component.html +1 -1
  64. package/src/lib/components/label/label.component.ts +1 -1
  65. package/src/lib/components/mode-toggle/mode-toggle.component.css +0 -0
  66. package/src/lib/components/mode-toggle/mode-toggle.component.html +8 -0
  67. package/src/lib/components/mode-toggle/mode-toggle.component.ts +61 -0
  68. package/src/lib/components/progress-bar/progress-bar.component.css +0 -0
  69. package/src/lib/components/progress-bar/progress-bar.component.html +22 -0
  70. package/src/lib/components/progress-bar/progress-bar.component.ts +20 -0
  71. package/src/lib/components/select/dropdown/dropdown.component.css +0 -0
  72. package/src/lib/components/select/dropdown/dropdown.component.html +95 -0
  73. package/src/lib/components/select/dropdown/dropdown.component.ts +562 -0
  74. package/src/lib/components/select/multi-dropdown/multi-dropdown.component.css +0 -0
  75. package/src/lib/components/select/multi-dropdown/multi-dropdown.component.html +87 -0
  76. package/src/lib/components/select/multi-dropdown/multi-dropdown.component.ts +315 -0
  77. package/src/lib/components/select/multi-table/multi-table.component.css +0 -0
  78. package/src/lib/components/select/multi-table/multi-table.component.html +83 -0
  79. package/src/lib/components/select/multi-table/multi-table.component.ts +230 -0
  80. package/src/lib/components/toggle-radio/toggle-radio.component.css +0 -0
  81. package/src/lib/components/toggle-radio/toggle-radio.component.html +51 -0
  82. package/src/lib/components/toggle-radio/toggle-radio.component.ts +203 -0
  83. package/src/styles.css +126 -0
  84. package/cli/tailjng.js +0 -105
  85. package/lib/services/icons.service.d.ts +0 -9
  86. package/lib/tailjng.component.d.ts +0 -5
  87. package/lib/tailjng.service.d.ts +0 -6
@@ -1,39 +1,647 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, Component } from '@angular/core';
3
- import { Info } from 'lucide-angular';
2
+ import { InjectionToken, Injectable, Inject, signal, computed } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { formatDistanceToNowStrict } from 'date-fns';
5
+ import { es } from 'date-fns/locale';
6
+ import { map, isObservable, firstValueFrom } from 'rxjs';
7
+ import * as i1$1 from '@angular/common/http';
8
+ import { HttpParams } from '@angular/common/http';
9
+ import { Loader2, Moon, Sun, Search, SquareDashedMousePointer, ChevronDown, Eye, Upload, ImageOff, Minimize2, Scan, RefreshCcw, RotateCcw, RotateCw, ZoomOut, ZoomIn, Check, X, CircleHelp, TriangleAlert, CircleX, CircleCheck, Info } from 'lucide-angular';
4
10
 
5
- class TailjngService {
6
- constructor() { }
7
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TailjngService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
8
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TailjngService, providedIn: 'root' });
11
+ const TAILJNG_CONFIG = new InjectionToken('TAILJNG_CONFIG');
12
+ // providers: [
13
+ // provideRouter(routes),
14
+ // {
15
+ // provide: TAILJNG_CONFIG,
16
+ // useValue: {
17
+ // urlBase: environment.urlBase,
18
+ // socketUrl: environment.socketUrl,
19
+ // }
20
+ // }
21
+ // ]
22
+
23
+ class JCalendarService {
24
+ nameDaysAb = ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb'];
25
+ nameDays = ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'];
26
+ nameMontsAb = ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'];
27
+ nameMonts = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
28
+ /**
29
+ * Get month from date
30
+ * @param date The date to extract the month from, can be a Date object or a string in 'YYYY-MM-DD' format.
31
+ * @returns The name of the month in Spanish.
32
+ */
33
+ getMonthFromDate(date) {
34
+ const parsedDate = typeof date === 'string' ? new Date(date) : date;
35
+ const monthIndex = parsedDate.getMonth();
36
+ return this.nameMonts[monthIndex];
37
+ }
38
+ /**
39
+ * Calculate the age of a person based on their birth date.
40
+ * @param birth The birth date as a Date object or a string in 'YYYY-MM-DD' format.
41
+ * @returns The age in years, or null if the birth date is invalid.
42
+ */
43
+ calculateAge(birth) {
44
+ if (!birth) {
45
+ return null;
46
+ }
47
+ const birthDate = typeof birth === 'string' ? new Date(birth) : birth;
48
+ const today = new Date();
49
+ let age = today.getFullYear() - birthDate.getFullYear();
50
+ const m = today.getMonth() - birthDate.getMonth();
51
+ if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
52
+ age--;
53
+ }
54
+ return age;
55
+ }
56
+ /**
57
+ * Calculate the complete age of a person based on their birth date.
58
+ * @param birth The birth date as a Date object or a string in 'YYYY-MM-DD' format.
59
+ * @returns An object containing years, months, and days of age.
60
+ */
61
+ calculateAgeComplete(birth) {
62
+ const birthDate = typeof birth === 'string' ? new Date(birth) : birth;
63
+ const today = new Date();
64
+ let years = today.getFullYear() - birthDate.getFullYear();
65
+ let months = today.getMonth() - birthDate.getMonth();
66
+ let days = today.getDate() - birthDate.getDate();
67
+ if (days < 0) {
68
+ months--;
69
+ const previousMonth = new Date(today.getFullYear(), today.getMonth(), 0);
70
+ days += previousMonth.getDate();
71
+ }
72
+ if (months < 0) {
73
+ years--;
74
+ months += 12;
75
+ }
76
+ return { years, months, days };
77
+ }
78
+ /**
79
+ * Format a date string to a more readable format.
80
+ * @param date The date string in 'YYYY-MM-DD' format.
81
+ * @param month Optional parameter to add to the month name.
82
+ * @returns A formatted date string in the format 'DD de MMMM del YYYY'.
83
+ */
84
+ formatearFechaString(date, month) {
85
+ const partesFecha = date.split('-');
86
+ const año = partesFecha[0];
87
+ const mes = this.nameMonts[parseInt(partesFecha[1], 10) - 1];
88
+ const día = parseInt(partesFecha[2], 10);
89
+ let mes_fin;
90
+ if (month) {
91
+ mes_fin = mes + month;
92
+ }
93
+ else {
94
+ mes_fin = mes;
95
+ }
96
+ return `${día} de ${mes_fin} del ${año}`;
97
+ }
98
+ /**
99
+ * Format a Date object to a string in the format 'DD de MMMM del YYYY'.
100
+ * @param date The Date object to format.
101
+ * @param month Optional parameter to add to the month name.
102
+ * @returns A formatted date string.
103
+ */
104
+ formatearFechaDate(date, month) {
105
+ const utc_date = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
106
+ let new_date = utc_date;
107
+ if (month !== undefined) {
108
+ new_date = new Date(new_date.setUTCMonth(new_date.getUTCMonth() + month));
109
+ }
110
+ // Get the values of the new date in UTC to avoid local time zones
111
+ const año = new_date.getUTCFullYear();
112
+ const mes = this.nameMonts[new_date.getUTCMonth()];
113
+ const día = new_date.getUTCDate();
114
+ return `${día} de ${mes} del ${año}`;
115
+ }
116
+ /**
117
+ * Parse a date string in the format "dd de MMMM del yyyy" to "yyyy-MM-dd".
118
+ * @param fechaStr The date string to parse.
119
+ * @returns The parsed date string in "yyyy-MM-dd" format or null if invalid.
120
+ */
121
+ parseFechaString(fechaStr) {
122
+ if (!fechaStr)
123
+ return null;
124
+ // Map Spanish month names to their numeric equivalents
125
+ const meses = {
126
+ 'ENERO': '01',
127
+ 'FEBRERO': '02',
128
+ 'MARZO': '03',
129
+ 'ABRIL': '04',
130
+ 'MAYO': '05',
131
+ 'JUNIO': '06',
132
+ 'JULIO': '07',
133
+ 'AGOSTO': '08',
134
+ 'SEPTIEMBRE': '09',
135
+ 'OCTUBRE': '10',
136
+ 'NOVIEMBRE': '11',
137
+ 'DICIEMBRE': '12'
138
+ };
139
+ const regex = /^(\d{1,2}) de (\w+) del (\d{4})$/i;
140
+ const match = fechaStr.trim().match(regex);
141
+ if (match) {
142
+ const day = match[1].padStart(2, '0');
143
+ const mesStr = match[2].toUpperCase();
144
+ const month = meses[mesStr] || '01';
145
+ const year = match[3];
146
+ return `${year}-${month}-${day}`;
147
+ }
148
+ return null;
149
+ }
150
+ /**
151
+ * Format a date to "MMM YY" format.
152
+ * @param date The date to format, can be a Date object.
153
+ * @returns The formatted date string.
154
+ */
155
+ formatMonthYear(date) {
156
+ const months = this.nameMontsAb.map(month => month.toUpperCase());
157
+ const month = months[date.getMonth()];
158
+ const year = date.getFullYear().toString().slice(-2);
159
+ return `${month} ${year}`;
160
+ }
161
+ /**
162
+ * Format a date to the Bogotá timezone (UTC-5).
163
+ * @param date The date to format, can be a Date object.
164
+ * @returns The formatted date string in 'yyyy-MM-ddTHH:mm:ss' format.
165
+ */
166
+ formatDateToBogota(date) {
167
+ const bogotaOffset = -5 * 60;
168
+ const localTime = date.getTime();
169
+ const localOffset = date.getTimezoneOffset() * 60000;
170
+ const utc = localTime + localOffset;
171
+ const bogotaTime = utc + (bogotaOffset * 60000);
172
+ const bogotaDate = new Date(bogotaTime);
173
+ // Format the date to 'yyyy-MM-ddTHH:mm:ss'
174
+ const year = bogotaDate.getFullYear();
175
+ const month = String(bogotaDate.getMonth() + 1).padStart(2, '0');
176
+ const day = String(bogotaDate.getDate()).padStart(2, '0');
177
+ const hours = String(bogotaDate.getHours()).padStart(2, '0');
178
+ const minutes = String(bogotaDate.getMinutes()).padStart(2, '0');
179
+ const seconds = String(bogotaDate.getSeconds()).padStart(2, '0');
180
+ return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`;
181
+ }
182
+ /**
183
+ * Format a date to a relative time string.
184
+ * This method uses date-fns to format the date relative to now.
185
+ * @param date The date to format, can be a string in 'YYYY-MM-DD' format.
186
+ * @returns A formatted relative time string.
187
+ * @example "hace 2 días", "hace 1 hora", etc
188
+ */
189
+ formatRelativeDate(date) {
190
+ return formatDistanceToNowStrict(new Date(date), {
191
+ locale: {
192
+ ...es,
193
+ formatDistance: (token, count, options) => {
194
+ const formatDistanceLocale = {
195
+ lessThanXSeconds: 'hace menos de {{count}} segundos',
196
+ xSeconds: 'hace {{count}} segundos',
197
+ halfAMinute: 'hace medio minuto',
198
+ lessThanXMinutes: 'hace menos de {{count}} minutos',
199
+ xMinutes: 'hace {{count}} minutos',
200
+ aboutXHours: 'hace aproximadamente {{count}} horas',
201
+ xHours: 'hace {{count}} horas',
202
+ xDays: 'hace {{count}} días',
203
+ aboutXWeeks: 'hace aproximadamente {{count}} semanas',
204
+ xWeeks: 'hace {{count}} semanas',
205
+ aboutXMonths: 'hace aproximadamente {{count}} meses',
206
+ xMonths: 'hace {{count}} meses',
207
+ aboutXYears: 'hace aproximadamente {{count}} años',
208
+ xYears: 'hace {{count}} años',
209
+ overXYears: 'hace más de {{count}} años',
210
+ almostXYears: 'hace casi {{count}} años'
211
+ };
212
+ let result = formatDistanceLocale[token];
213
+ if (typeof count === 'number') {
214
+ result = result.replace('{{count}}', count.toString());
215
+ // Singulars and plurals
216
+ if (token === 'xHours' && count === 1) {
217
+ result = result.replace('horas', 'hora');
218
+ }
219
+ if (token === 'xDays' && count === 1) {
220
+ result = result.replace('días', 'día');
221
+ }
222
+ if (token === 'xWeeks' && count === 1) {
223
+ result = result.replace('semanas', 'semana');
224
+ }
225
+ if (token === 'xMonths' && count === 1) {
226
+ result = result.replace('meses', 'mes');
227
+ }
228
+ if (token === 'xYears' && count === 1) {
229
+ result = result.replace('años', 'año');
230
+ }
231
+ }
232
+ return result;
233
+ }
234
+ }
235
+ });
236
+ }
237
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JCalendarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
238
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JCalendarService, providedIn: 'root' });
9
239
  }
10
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TailjngService, decorators: [{
240
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JCalendarService, decorators: [{
11
241
  type: Injectable,
12
242
  args: [{
13
243
  providedIn: 'root'
14
244
  }]
15
- }], ctorParameters: () => [] });
245
+ }] });
246
+
247
+ class JConverterCrudService {
248
+ currencyPipe;
249
+ calendarService;
250
+ constructor(currencyPipe, calendarService) {
251
+ this.currencyPipe = currencyPipe;
252
+ this.calendarService = calendarService;
253
+ }
254
+ /**
255
+ * Get the correct sort key from the sortColumn object or string.
256
+ * @param sortColumn The column to sort by, can be a string or an object with a 'col' property.
257
+ * @returns The sort key as a string.
258
+ */
259
+ getSortKey(sortColumn) {
260
+ if (typeof sortColumn === 'object' && sortColumn !== null) {
261
+ return sortColumn.col;
262
+ }
263
+ return sortColumn;
264
+ }
265
+ /**
266
+ * Converter object to an array of objects with key and value for form initialization.
267
+ * @param formGroup The FormGroup to convert.
268
+ * @returns An array of objects with key and value for form initialization.
269
+ */
270
+ initializeFormControls(formGroup) {
271
+ const formControls = {};
272
+ Object.keys(formGroup.controls).forEach(key => {
273
+ formControls[`${key}_control`] = formGroup.get(key);
274
+ });
275
+ return formControls;
276
+ }
277
+ /**
278
+ * Formats data based on the column type.
279
+ * @param value The value to format.
280
+ * @param column The column definition.
281
+ * @return Formatted value based on the column type
282
+ */
283
+ formatData(value, column) {
284
+ if (column.isdollar && value !== null) {
285
+ const transformedValue = this.currencyPipe.transform(value, 'USD', 'symbol', '1.2-2');
286
+ return transformedValue ? transformedValue.replace('US', '') : null;
287
+ }
288
+ if (column.isCurrency && value !== null) {
289
+ return this.currencyPipe.transform(value, 'USD', 'symbol', '1.2-2');
290
+ }
291
+ if (column.isDate && value !== null) {
292
+ return new Date(value).toLocaleDateString();
293
+ }
294
+ if (column.isDateText && value !== null) {
295
+ return this.calendarService.formatearFechaString(`${value}`);
296
+ }
297
+ if (column.isDateTime && value !== null) {
298
+ return new Date(value).toLocaleString();
299
+ }
300
+ if (column.isDateTimeText && value !== null) {
301
+ return new Date(value).toString();
302
+ }
303
+ if (column.isRelativeTime && value !== null) {
304
+ return this.calendarService.formatRelativeDate(value);
305
+ }
306
+ if (column.isFirstWord && value !== null) {
307
+ return value.split(' ')[0];
308
+ }
309
+ return value;
310
+ }
311
+ /**
312
+ * This method converts values to appropriate types based on the column definition.
313
+ * It handles various formats such as currency, date, and text.
314
+ * @param value The value to parse.
315
+ * @param column The column definition.
316
+ * @returns The parsed value or null if invalid.
317
+ */
318
+ parseData(value, column) {
319
+ if (value === null || value === undefined || value === 'S/N') {
320
+ return null;
321
+ }
322
+ let cleaned = value;
323
+ // If it's text, trim whitespace
324
+ if (typeof cleaned === 'string') {
325
+ cleaned = cleaned.trim();
326
+ }
327
+ // isdollar → remove symbol and parse to number
328
+ if (column.isdollar && typeof cleaned === 'string') {
329
+ cleaned = cleaned.replace(/[^\d,.-]/g, '').replace(',', '.');
330
+ return cleaned ? parseFloat(cleaned) : null;
331
+ }
332
+ // isCurrency → remove symbol and parse to number
333
+ if (column.isCurrency && typeof cleaned === 'string') {
334
+ cleaned = cleaned.replace(/[^\d,.-]/g, '').replace(',', '.');
335
+ return cleaned ? parseFloat(cleaned) : null;
336
+ }
337
+ // isDateText → parse text from date to ISO format (yyyy-MM-dd)
338
+ if (column.isDateText && typeof cleaned === 'string') {
339
+ // Use your reverse calendarService if you have one
340
+ const fecha = this.calendarService.parseFechaString(cleaned);
341
+ return fecha ?? cleaned;
342
+ }
343
+ // isDate → parse text to Date or ISO string
344
+ if (column.isDate && typeof cleaned === 'string') {
345
+ const fecha = new Date(cleaned);
346
+ return isNaN(fecha.getTime()) ? cleaned : fecha.toISOString().substring(0, 10);
347
+ }
348
+ // isDateTime → parse text to DateTime
349
+ if (column.isDateTime && typeof cleaned === 'string') {
350
+ const fecha = new Date(cleaned);
351
+ return isNaN(fecha.getTime()) ? cleaned : fecha.toISOString();
352
+ }
353
+ // isDateTimeText → parse text to DateTime
354
+ if (column.isDateTimeText && typeof cleaned === 'string') {
355
+ const fecha = new Date(cleaned);
356
+ return isNaN(fecha.getTime()) ? cleaned : fecha.toISOString();
357
+ }
358
+ // isRelativeTime → impossible to reverse automatically, return text
359
+ if (column.isRelativeTime) {
360
+ return cleaned;
361
+ }
362
+ // isFirstWord → return full text, as it's unclear which part to remove
363
+ if (column.isFirstWord) {
364
+ return cleaned;
365
+ }
366
+ return cleaned;
367
+ }
368
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JConverterCrudService, deps: [{ token: i1.CurrencyPipe }, { token: JCalendarService }], target: i0.ɵɵFactoryTarget.Injectable });
369
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JConverterCrudService, providedIn: 'root' });
370
+ }
371
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JConverterCrudService, decorators: [{
372
+ type: Injectable,
373
+ args: [{
374
+ providedIn: 'root'
375
+ }]
376
+ }], ctorParameters: () => [{ type: i1.CurrencyPipe }, { type: JCalendarService }] });
377
+
378
+ class JParamsHttpService {
379
+ /**
380
+ * Transform Params to HttpParams
381
+ * @param params
382
+ * @returns
383
+ */
384
+ resParams(params) {
385
+ // Construct HttpParams
386
+ let httpParams = new HttpParams();
387
+ if (params) {
388
+ Object.keys(params).forEach(key => {
389
+ const value = params[key];
390
+ // If the value is an object (e.g., filter: { id_status: [1, 2] })
391
+ if (typeof value === 'object' && value !== null) {
392
+ Object.keys(value).forEach(subKey => {
393
+ const subValue = value[subKey];
394
+ // If the subValue is an array (e.g., id_status: [1, 2])
395
+ if (Array.isArray(subValue)) {
396
+ subValue.forEach(v => {
397
+ httpParams = httpParams.append(`${key}[${subKey}]`, v);
398
+ });
399
+ }
400
+ else {
401
+ // If it's a unique value
402
+ httpParams = httpParams.append(`${key}[${subKey}]`, subValue);
403
+ }
404
+ });
405
+ }
406
+ else {
407
+ // If it's a flat value (e.g., id_status: 1)
408
+ httpParams = httpParams.append(key, value);
409
+ }
410
+ });
411
+ }
412
+ return httpParams;
413
+ }
414
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JParamsHttpService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
415
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JParamsHttpService, providedIn: 'root' });
416
+ }
417
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JParamsHttpService, decorators: [{
418
+ type: Injectable,
419
+ args: [{
420
+ providedIn: 'root'
421
+ }]
422
+ }] });
423
+
424
+ class JGenericCrudService {
425
+ config;
426
+ http;
427
+ paramsHttpService;
428
+ converterCrudService;
429
+ constructor(config, http, paramsHttpService, converterCrudService) {
430
+ this.config = config;
431
+ this.http = http;
432
+ this.paramsHttpService = paramsHttpService;
433
+ this.converterCrudService = converterCrudService;
434
+ }
435
+ /**
436
+ * Method to get all records from an endpoint.
437
+ * @param endpoint Distinctive of the endpoint ('role', 'status', etc.)
438
+ * @param params Parameters of the request.
439
+ * @returns Observable with the API response.
440
+ */
441
+ getAll(endpoint, params) {
442
+ const url = `${this.config.urlBase}/${endpoint}`;
443
+ let httpParams;
444
+ if (params)
445
+ httpParams = this.paramsHttpService.resParams(params);
446
+ return this.http.get(url, { params: httpParams });
447
+ }
448
+ /**
449
+ * Method to get a record from an endpoint.
450
+ * @param endpoint Distinctive of the endpoint ('role', 'status', etc.)
451
+ * @param id Identifier of the record.
452
+ * @returns Observable with the API response.
453
+ */
454
+ getId(endpoint, id) {
455
+ const url = `${this.config.urlBase}/${endpoint}`;
456
+ return this.http.get(`${url}/${id}`).pipe(map(response => response.data[endpoint]));
457
+ }
458
+ /**
459
+ * Method to create a record in an endpoint.
460
+ * @param endpoint Distinctive of the endpoint ('role', 'status', etc.)
461
+ * @param data Data of the record to add.
462
+ * @returns Observable with the API response.
463
+ */
464
+ create(endpoint, data) {
465
+ const url = `${this.config.urlBase}/${endpoint}`;
466
+ return this.http.post(url, data);
467
+ }
468
+ /**
469
+ * MMethod to update a record in an endpoint.
470
+ * @param endpoint Distinctive of the endpoint ('role', 'status', etc.)
471
+ * @param id Identifier of the record.
472
+ * @param data Data of the record to update.
473
+ * @returns Observable with the API response.
474
+ */
475
+ update(endpoint, id, data) {
476
+ const url = `${this.config.urlBase}/${endpoint}`;
477
+ return this.http.put(`${url}/${id}`, data);
478
+ }
479
+ /**
480
+ * MMethod to delete a record from an endpoint.
481
+ * @param endpoint Distinctive of the endpoint ('role', 'status', etc.)
482
+ * @param id Identifier of the record.
483
+ * @returns Observable with the API response.
484
+ */
485
+ delete(endpoint, id) {
486
+ const url = `${this.config.urlBase}/${endpoint}`;
487
+ return this.http.delete(`${url}/${id}`);
488
+ }
489
+ /**
490
+ * Method to update the status of a record in an endpoint.
491
+ * @param endpoint Distinctive of the endpoint ('role', 'status', etc.)
492
+ * @param id Identifier of the record.
493
+ * @param data Data of a boolean record to update.
494
+ * @returns Observable with the API response.
495
+ */
496
+ enable(endpoint, id, data) {
497
+ const url = `${this.config.urlBase}/${endpoint}`;
498
+ return this.http.put(`${url}/enable/${id}`, data);
499
+ }
500
+ /**
501
+ * MMethod to create multiple records in an endpoint.
502
+ * @param endpoint Distinctive of the endpoint ('role', 'status', etc.)
503
+ * @param data Data of multiple records to add.
504
+ * @returns Observable with the API response.
505
+ */
506
+ createMultiple(endpoint, data) {
507
+ const url = `${this.config.urlBase}/${endpoint}/bulk`;
508
+ return this.http.post(url, data);
509
+ }
510
+ /**
511
+ * Method to get the query parameters for a table.
512
+ * @param page Current page number.
513
+ * @param limit NNumber of records per page.
514
+ * @param sort Object containing the column and the sorting direction.
515
+ * @param filters Filters applied to the query.
516
+ * @param defaultFilters Default filters applied to the query.
517
+ * @param searchQuery Search string.
518
+ * @param columns Columns to search.
519
+ * @returns
520
+ */
521
+ params({ page, limit, sort, filters, defaultFilters, searchQuery, columns }) {
522
+ const params = {};
523
+ if (page)
524
+ params['page'] = page.toString();
525
+ if (limit)
526
+ params['limit'] = limit.toString();
527
+ // Apply default filters if provided
528
+ Object.keys(defaultFilters ?? {}).forEach((key) => {
529
+ if (!filters.hasOwnProperty(key)) {
530
+ params[`filter[${key}]`] = defaultFilters[key];
531
+ }
532
+ });
533
+ // If sort is provided, get the sort key and direction
534
+ if (sort?.column && sort?.direction !== 'none') {
535
+ const sortKey = this.converterCrudService.getSortKey(sort?.column);
536
+ params['sortBy'] = sortKey;
537
+ params['sortOrder'] = sort?.direction?.toUpperCase();
538
+ }
539
+ // Apply search if provided
540
+ if (searchQuery && searchQuery.trim() !== '') {
541
+ params['search'] = searchQuery;
542
+ params['searchFields'] = columns?.map(col => col);
543
+ }
544
+ // Apply filters if provided
545
+ if (Object.keys(filters).length > 0) {
546
+ params['filter'] = filters;
547
+ }
548
+ return params;
549
+ }
550
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JGenericCrudService, deps: [{ token: TAILJNG_CONFIG }, { token: i1$1.HttpClient }, { token: JParamsHttpService }, { token: JConverterCrudService }], target: i0.ɵɵFactoryTarget.Injectable });
551
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JGenericCrudService, providedIn: 'root' });
552
+ }
553
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JGenericCrudService, decorators: [{
554
+ type: Injectable,
555
+ args: [{
556
+ providedIn: 'root'
557
+ }]
558
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
559
+ type: Inject,
560
+ args: [TAILJNG_CONFIG]
561
+ }] }, { type: i1$1.HttpClient }, { type: JParamsHttpService }, { type: JConverterCrudService }] });
16
562
 
17
- class TailjngComponent {
18
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TailjngComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
19
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: TailjngComponent, isStandalone: true, selector: "lib-tailjng", ngImport: i0, template: `
20
- <p>
21
- tailjng works!
22
- </p>
23
- `, isInline: true, styles: [""] });
24
- }
25
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TailjngComponent, decorators: [{
26
- type: Component,
27
- args: [{ selector: 'lib-tailjng', imports: [], template: `
28
- <p>
29
- tailjng works!
30
- </p>
31
- ` }]
563
+ class ErrorHandlerHttpService {
564
+ /**
565
+ * Map HTTP status codes to user-friendly messages and alert types.
566
+ * This mapping helps in providing consistent error messages across the application.
567
+ */
568
+ errorMappings = {
569
+ 400: { type: 'info', title: 'Solicitud incorrecta', message: 'Los datos enviados no son válidos. Verifique e intente de nuevo.', persistent: false },
570
+ 401: { type: 'info', title: 'No autorizado', message: 'Debe iniciar sesión para acceder a esta función.', persistent: true },
571
+ 403: { type: 'error', title: 'Acceso denegado', message: 'No tiene permisos para realizar esta acción.', persistent: true },
572
+ 404: { type: 'info', title: 'No encontrado', message: 'El recurso solicitado no existe o fue eliminado.', persistent: false },
573
+ 409: { type: 'info', title: 'Conflicto', message: 'Conflicto en la solicitud. Verifique los datos ingresados.', persistent: false },
574
+ 422: { type: 'info', title: 'Datos no procesables', message: 'Los datos son válidos, pero no pueden ser procesados en este momento.', persistent: false },
575
+ 429: { type: 'info', title: 'Demasiadas solicitudes', message: 'Ha realizado demasiadas solicitudes. Intente más tarde.', persistent: true },
576
+ 500: { type: 'error', title: 'Error del servidor', message: 'Ocurrió un error inesperado. Intente más tarde.', persistent: true },
577
+ 503: { type: 'error', title: 'Servicio no disponible', message: 'El servidor está en mantenimiento o sobrecargado.', persistent: true }
578
+ };
579
+ /**
580
+ * Handle HTTP errors and return a structured message with alert type.
581
+ * @param error The error object returned from the HTTP request.
582
+ * @returns A structured error message.
583
+ */
584
+ handleHttpError(error) {
585
+ console.error('HTTP Error:', error);
586
+ // If no error is defined, return a generic message
587
+ if (!error) {
588
+ return {
589
+ type: 'error',
590
+ title: 'Error desconocido',
591
+ message: 'Ocurrió un error inesperado. Intente de nuevo más tarde.',
592
+ persistent: true
593
+ };
594
+ }
595
+ const status = error?.status || 0;
596
+ const backendMessage = error?.error?.msg || error?.message;
597
+ const errorInfo = this.errorMappings[status] || {
598
+ title: 'Error desconocido',
599
+ message: 'Ocurrió un error inesperado. Intente de nuevo más tarde.',
600
+ type: 'error',
601
+ persistent: true
602
+ };
603
+ return {
604
+ type: errorInfo.type,
605
+ title: errorInfo.title,
606
+ message: backendMessage || errorInfo.message,
607
+ persistent: errorInfo.persistent
608
+ };
609
+ }
610
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ErrorHandlerHttpService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
611
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ErrorHandlerHttpService, providedIn: 'root' });
612
+ }
613
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ErrorHandlerHttpService, decorators: [{
614
+ type: Injectable,
615
+ args: [{
616
+ providedIn: 'root'
617
+ }]
32
618
  }] });
33
619
 
34
620
  class JIconsService {
35
621
  icons = {
36
- Info,
622
+ info: Info,
623
+ success: CircleCheck,
624
+ error: CircleX,
625
+ warning: TriangleAlert,
626
+ question: CircleHelp,
627
+ close: X,
628
+ check: Check,
629
+ zoomIn: ZoomIn,
630
+ zoomOut: ZoomOut,
631
+ rotateRight: RotateCw,
632
+ rotateLeft: RotateCcw,
633
+ reset: RefreshCcw,
634
+ fullscreen: Scan,
635
+ exitFullscreen: Minimize2,
636
+ imageOff: ImageOff,
637
+ upload: Upload,
638
+ view: Eye,
639
+ chevronDown: ChevronDown,
640
+ squareDashedMousePointer: SquareDashedMousePointer,
641
+ search: Search,
642
+ sun: Sun,
643
+ moon: Moon,
644
+ loading: Loader2,
37
645
  };
38
646
  constructor() { }
39
647
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JIconsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
@@ -46,13 +654,283 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
46
654
  }]
47
655
  }], ctorParameters: () => [] });
48
656
 
657
+ class JAlertDialogService {
658
+ isOpenSignal = signal(false);
659
+ configSignal = signal(null);
660
+ // Estados de carga para los botones
661
+ isLoadingConfirm = signal(false);
662
+ isLoadingCancel = signal(false);
663
+ isLoadingRetry = signal(false);
664
+ // Callbacks
665
+ onConfirmCallback;
666
+ onCancelCallback;
667
+ onRetryCallback;
668
+ isOpen = computed(() => this.isOpenSignal());
669
+ config = computed(() => this.configSignal());
670
+ isConfirmLoading = computed(() => this.isLoadingConfirm());
671
+ isCancelLoading = computed(() => this.isLoadingCancel());
672
+ isRetryLoading = computed(() => this.isLoadingRetry());
673
+ // Add a dialogs computed property that returns an array with a single dialog when open
674
+ dialogs = computed(() => {
675
+ if (!this.isOpenSignal())
676
+ return [];
677
+ return [{
678
+ config: this.configSignal(),
679
+ isConfirmLoading: this.isLoadingConfirm(),
680
+ isCancelLoading: this.isLoadingCancel(),
681
+ isRetryLoading: this.isLoadingRetry()
682
+ }];
683
+ });
684
+ getConfig() {
685
+ return this.configSignal();
686
+ }
687
+ AlertDialog(config) {
688
+ this.onConfirmCallback = "onConfirm" in config ? config.onConfirm : undefined;
689
+ this.onCancelCallback = "onCancel" in config ? config.onCancel : undefined;
690
+ this.onRetryCallback = "onRetry" in config ? config.onRetry : undefined;
691
+ // Reset loading states
692
+ this.isLoadingConfirm.set(false);
693
+ this.isLoadingCancel.set(false);
694
+ this.isLoadingRetry.set(false);
695
+ this.configSignal.set(config);
696
+ this.isOpenSignal.set(true);
697
+ }
698
+ closeDialog() {
699
+ this.isOpenSignal.set(false);
700
+ this.configSignal.set(null);
701
+ }
702
+ async executeAction(action) {
703
+ let callback;
704
+ let loadingSignal;
705
+ switch (action) {
706
+ case "confirm":
707
+ callback = this.onConfirmCallback;
708
+ loadingSignal = this.isLoadingConfirm;
709
+ break;
710
+ case "cancel":
711
+ callback = this.onCancelCallback;
712
+ loadingSignal = this.isLoadingCancel;
713
+ break;
714
+ case "retry":
715
+ callback = this.onRetryCallback;
716
+ loadingSignal = this.isLoadingRetry;
717
+ break;
718
+ }
719
+ if (!callback) {
720
+ this.closeDialog();
721
+ return;
722
+ }
723
+ loadingSignal.set(true);
724
+ try {
725
+ const result = callback();
726
+ // Soporte para Observable
727
+ if (isObservable(result)) {
728
+ await firstValueFrom(result);
729
+ }
730
+ // Soporte para Promise
731
+ if (result instanceof Promise) {
732
+ await result;
733
+ }
734
+ // Si es void, no hacemos nada extra
735
+ }
736
+ catch (error) {
737
+ console.error(`Error en la acción ${action}:`, error);
738
+ }
739
+ finally {
740
+ loadingSignal.set(false);
741
+ this.closeDialog();
742
+ }
743
+ }
744
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JAlertDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
745
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JAlertDialogService, providedIn: "root" });
746
+ }
747
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JAlertDialogService, decorators: [{
748
+ type: Injectable,
749
+ args: [{
750
+ providedIn: "root",
751
+ }]
752
+ }] });
753
+
754
+ class JAlertToastService {
755
+ toastsSignal = signal([]);
756
+ autoCloseTimers = new Map();
757
+ // Default auto-close delay in milliseconds
758
+ DEFAULT_AUTO_CLOSE_DELAY = 5000;
759
+ // Default action button text
760
+ DEFAULT_ACTION_BUTTON_TEXT = "Action";
761
+ // For compatibility with existing code
762
+ isOpenSignal = signal(false);
763
+ configSignal = signal(null);
764
+ isLoadingAction = signal(false);
765
+ isLoadingCancel = signal(false);
766
+ // Computed values for all toasts
767
+ toasts = computed(() => this.toastsSignal());
768
+ // For backward compatibility with existing code
769
+ isOpen = computed(() => this.isOpenSignal());
770
+ config = computed(() => this.configSignal());
771
+ isActionLoading = computed(() => this.isLoadingAction());
772
+ isCancelLoading = computed(() => this.isLoadingCancel());
773
+ getConfig() {
774
+ return this.configSignal();
775
+ }
776
+ AlertToast(config) {
777
+ const toastId = crypto.randomUUID();
778
+ // Store callbacks for this toast
779
+ const onActionCallback = "onAction" in config ? config.onAction : undefined;
780
+ const onCancelCallback = "onCancel" in config ? config.onCancel : undefined;
781
+ // Get action button text or use default
782
+ const actionNameButton = config.actionButtonText ?? this.DEFAULT_ACTION_BUTTON_TEXT;
783
+ const toast = {
784
+ id: toastId,
785
+ config,
786
+ isActionLoading: false,
787
+ isCancelLoading: false,
788
+ onActionCallback,
789
+ onCancelCallback,
790
+ actionNameButton, // Add the button text
791
+ createdAt: Date.now()
792
+ };
793
+ // Add the toast to our list
794
+ this.toastsSignal.update(toasts => [...toasts, toast]);
795
+ // Check if this toast should auto-close
796
+ // If autoClose is explicitly set to true OR
797
+ // if it's a success toast and autoClose is not explicitly set to false
798
+ const shouldAutoClose = config.autoClose === true ||
799
+ (config.type === 'success' && config.autoClose !== false);
800
+ if (shouldAutoClose) {
801
+ // Use the provided delay or the default
802
+ const delay = config.autoCloseDelay ?? this.DEFAULT_AUTO_CLOSE_DELAY;
803
+ const timerId = setTimeout(() => {
804
+ this.closeToastById(toastId);
805
+ this.autoCloseTimers.delete(toastId);
806
+ }, delay);
807
+ this.autoCloseTimers.set(toastId, timerId);
808
+ }
809
+ return toastId;
810
+ }
811
+ closeToastById(toastId) {
812
+ // Clear any auto-close timer
813
+ if (this.autoCloseTimers.has(toastId)) {
814
+ clearTimeout(this.autoCloseTimers.get(toastId));
815
+ this.autoCloseTimers.delete(toastId);
816
+ }
817
+ this.toastsSignal.update(toasts => toasts.filter(toast => toast.id !== toastId));
818
+ }
819
+ closeAllToasts() {
820
+ // Clear all timers
821
+ this.autoCloseTimers.forEach(timerId => clearTimeout(timerId));
822
+ this.autoCloseTimers.clear();
823
+ this.toastsSignal.set([]);
824
+ }
825
+ async executeToastAction(toastId, action) {
826
+ const toast = this.toastsSignal().find(t => t.id === toastId);
827
+ if (!toast)
828
+ return;
829
+ let callback;
830
+ let loadingProperty;
831
+ switch (action) {
832
+ case "action":
833
+ callback = toast.onActionCallback;
834
+ loadingProperty = 'isActionLoading';
835
+ break;
836
+ case "cancel":
837
+ callback = toast.onCancelCallback;
838
+ loadingProperty = 'isCancelLoading';
839
+ break;
840
+ }
841
+ if (callback) {
842
+ // Update loading state
843
+ this.toastsSignal.update(toasts => toasts.map(t => t.id === toastId ? { ...t, [loadingProperty]: true } : t));
844
+ try {
845
+ await callback();
846
+ }
847
+ catch (error) {
848
+ console.error(`Error en la acción ${action}:`, error);
849
+ }
850
+ finally {
851
+ // Update loading state back to false (in case the toast hasn't been closed)
852
+ this.toastsSignal.update(toasts => {
853
+ const updatedToasts = toasts.map(t => t.id === toastId ? { ...t, [loadingProperty]: false } : t);
854
+ return updatedToasts;
855
+ });
856
+ this.closeToastById(toastId);
857
+ }
858
+ }
859
+ else {
860
+ this.closeToastById(toastId);
861
+ }
862
+ }
863
+ // For backward compatibility with existing code
864
+ closeToast() {
865
+ this.closeAllToasts();
866
+ this.isOpenSignal.set(false);
867
+ this.configSignal.set(null);
868
+ }
869
+ // For backward compatibility with existing code
870
+ async executeAction(action) {
871
+ let callback;
872
+ let loadingSignal;
873
+ switch (action) {
874
+ case "action":
875
+ callback = "onAction" in (this.configSignal() || {})
876
+ ? this.configSignal().onAction
877
+ : undefined;
878
+ loadingSignal = this.isLoadingAction;
879
+ break;
880
+ case "cancel":
881
+ callback = "onCancel" in (this.configSignal() || {})
882
+ ? this.configSignal().onCancel
883
+ : undefined;
884
+ loadingSignal = this.isLoadingCancel;
885
+ break;
886
+ }
887
+ if (callback) {
888
+ loadingSignal.set(true);
889
+ try {
890
+ await callback();
891
+ }
892
+ catch (error) {
893
+ console.error(`Error en la acción ${action}:`, error);
894
+ }
895
+ finally {
896
+ loadingSignal.set(false);
897
+ this.closeToast();
898
+ }
899
+ }
900
+ else {
901
+ this.closeToast();
902
+ }
903
+ }
904
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JAlertToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
905
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JAlertToastService, providedIn: "root" });
906
+ }
907
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: JAlertToastService, decorators: [{
908
+ type: Injectable,
909
+ args: [{
910
+ providedIn: "root",
911
+ }]
912
+ }] });
913
+
914
+ // ======================================================
915
+ // Table Column Interface
916
+ // This interface defines the structure of a table column in a CRUD application.
917
+ // ======================================================
918
+
49
919
  /*
50
920
  * Public API Surface of tailjng
51
921
  */
922
+ // ========================================
923
+ // Config
924
+ // ========================================
925
+ // npm version patch
926
+ // npm run build
927
+ // cd dist/tailjng
928
+ // npm publish --access public
929
+ // npx tailjng add [component]
52
930
 
53
931
  /**
54
932
  * Generated bundle index. Do not edit.
55
933
  */
56
934
 
57
- export { JIconsService, TailjngComponent, TailjngService };
935
+ export { ErrorHandlerHttpService, JAlertDialogService, JAlertToastService, JCalendarService, JConverterCrudService, JGenericCrudService, JIconsService, JParamsHttpService, TAILJNG_CONFIG };
58
936
  //# sourceMappingURL=tailjng.mjs.map