tailjng 0.0.4 → 0.0.6

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.
@@ -1280,6 +1280,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
1280
1280
 
1281
1281
  const API_URL = new InjectionToken('API_URL');
1282
1282
 
1283
+ class JConverterService {
1284
+ constructor() { }
1285
+ /**
1286
+ * Obtener la clave de ordenación correcta
1287
+ * @param sortColumn
1288
+ * @returns
1289
+ */
1290
+ getSortKey(sortColumn) {
1291
+ // Verifica si sortColumn es un objeto y retorna la propiedad 'col'
1292
+ if (typeof sortColumn === 'object' && sortColumn !== null) {
1293
+ return sortColumn.col;
1294
+ }
1295
+ // Si no es un objeto, asume que es una cadena directa
1296
+ return sortColumn;
1297
+ }
1298
+ /**
1299
+ * Convierte un objeto a un array de objetos con clave y valor para iniciar el formulario
1300
+ * @param formGroup
1301
+ * @returns
1302
+ */
1303
+ initializeFormControls(formGroup) {
1304
+ const formControls = {};
1305
+ Object.keys(formGroup.controls).forEach(key => {
1306
+ formControls[`${key}_control`] = formGroup.get(key);
1307
+ });
1308
+ return formControls;
1309
+ }
1310
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: JConverterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1311
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: JConverterService, providedIn: 'root' });
1312
+ }
1313
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: JConverterService, decorators: [{
1314
+ type: Injectable,
1315
+ args: [{
1316
+ providedIn: 'root'
1317
+ }]
1318
+ }], ctorParameters: () => [] });
1319
+
1283
1320
  class JHttpParamsService {
1284
1321
  constructor() { }
1285
1322
  // Formatear parámetros para peticiones HTTP
@@ -1324,43 +1361,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
1324
1361
  }]
1325
1362
  }], ctorParameters: () => [] });
1326
1363
 
1327
- class ConverterService {
1328
- constructor() { }
1329
- /**
1330
- * Obtener la clave de ordenación correcta
1331
- * @param sortColumn
1332
- * @returns
1333
- */
1334
- getSortKey(sortColumn) {
1335
- // Verifica si sortColumn es un objeto y retorna la propiedad 'col'
1336
- if (typeof sortColumn === 'object' && sortColumn !== null) {
1337
- return sortColumn.col;
1338
- }
1339
- // Si no es un objeto, asume que es una cadena directa
1340
- return sortColumn;
1341
- }
1342
- /**
1343
- * Convierte un objeto a un array de objetos con clave y valor para iniciar el formulario
1344
- * @param formGroup
1345
- * @returns
1346
- */
1347
- initializeFormControls(formGroup) {
1348
- const formControls = {};
1349
- Object.keys(formGroup.controls).forEach(key => {
1350
- formControls[`${key}_control`] = formGroup.get(key);
1351
- });
1352
- return formControls;
1353
- }
1354
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ConverterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1355
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ConverterService, providedIn: 'root' });
1356
- }
1357
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ConverterService, decorators: [{
1358
- type: Injectable,
1359
- args: [{
1360
- providedIn: 'root'
1361
- }]
1362
- }], ctorParameters: () => [] });
1363
-
1364
1364
  class JGenericService {
1365
1365
  baseUrl;
1366
1366
  http;
@@ -1479,7 +1479,7 @@ class JGenericService {
1479
1479
  }
1480
1480
  return params;
1481
1481
  }
1482
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: JGenericService, deps: [{ token: API_URL }, { token: i1$2.HttpClient }, { token: JHttpParamsService }, { token: ConverterService }], target: i0.ɵɵFactoryTarget.Injectable });
1482
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: JGenericService, deps: [{ token: API_URL }, { token: i1$2.HttpClient }, { token: JHttpParamsService }, { token: JConverterService }], target: i0.ɵɵFactoryTarget.Injectable });
1483
1483
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: JGenericService, providedIn: 'root' });
1484
1484
  }
1485
1485
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: JGenericService, decorators: [{
@@ -1490,7 +1490,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
1490
1490
  }], ctorParameters: () => [{ type: undefined, decorators: [{
1491
1491
  type: Inject,
1492
1492
  args: [API_URL]
1493
- }] }, { type: i1$2.HttpClient }, { type: JHttpParamsService }, { type: ConverterService }] });
1493
+ }] }, { type: i1$2.HttpClient }, { type: JHttpParamsService }, { type: JConverterService }] });
1494
1494
 
1495
1495
  class JErrorHandlerService {
1496
1496
  /**
@@ -3646,7 +3646,7 @@ class CardComponent {
3646
3646
  getExpansionState(row) {
3647
3647
  return this.expandedRows.has(row) ? 'expanded' : 'collapsed';
3648
3648
  }
3649
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: CardComponent, deps: [{ token: i1$1.CurrencyPipe }, { token: JGenericService }, { token: JAlertToastService }, { token: ConverterService }, { token: JCalendarService }], target: i0.ɵɵFactoryTarget.Component });
3649
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: CardComponent, deps: [{ token: i1$1.CurrencyPipe }, { token: JGenericService }, { token: JAlertToastService }, { token: JConverterService }, { token: JCalendarService }], target: i0.ɵɵFactoryTarget.Component });
3650
3650
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: CardComponent, isStandalone: true, selector: "JCrudCard", inputs: { endpoint: "endpoint", columns: "columns", defaultFilters: "defaultFilters", isPaginator: "isPaginator", isSearch: "isSearch", itemTemplate: "itemTemplate", itemsPerPageOptions: "itemsPerPageOptions", searchPlaceholder: "searchPlaceholder", filtersButton: "filtersButton", filtersSelect: "filtersSelect" }, outputs: { dataLoaded: "dataLoaded" }, ngImport: i0, template: "<div class=\"w-full\">\r\n @if (isSearch) {\r\n <JFilter\r\n [(searchQuery)]=\"searchQuery\" \r\n (search)=\"onSearch()\" \r\n [searchPlaceholder]=\"searchPlaceholder\"\r\n [(itemsPerPage)]=\"itemsPerPage\"\r\n [itemsPerPageOptions]=\"itemsPerPageOptions\" \r\n (onItemsPerPageChangeEvent)=\"onItemsPerPageChange()\"\r\n [isLoadingSearch]=\"isLoading('search')\" \r\n [isLoadingPerPage]=\"isLoading('itemsPerPage')\" \r\n [isLoadingAditionalButtons]=\"loadingStates.aditionalButtons\"\r\n (clearFilters)=\"onClearFilters($event)\"\r\n [filtersButton]=\"filtersButton\"\r\n [filtersSelect]=\"filtersSelect\"\r\n />\r\n }\r\n\r\n @if (isLoading('initialLoad') && displayData.length === 0) {\r\n <div class=\"w-full flex justify-center items-center h-100 bg-white dark:bg-foreground rounded-[20px] border border-border dark:border-dark-border\">\r\n <div class=\"flex flex-col gap-3 items-center justify-center py-4\">\r\n <lucide-icon [name]=\"icons['loading']\" size=\"30\" class=\"text-primary animate-spin\"></lucide-icon>\r\n <p>Cargando datos...</p>\r\n </div>\r\n </div>\r\n } @else if (displayData.length > 0) {\r\n\r\n @if (itemTemplate) {\r\n <div class=\"flex flex-wrap gap-4 my-4\">\r\n @for (item of displayData; track item?.id) {\r\n <div class=\"w-full sm:w-[48%] md:w-[31%] xl:w-[23.5%] min-w-[250px] max-w-full flex flex-col gap-3 rounded-xl border border-border dark:border-dark-border bg-white dark:bg-foreground shadow-sm hover:shadow-lg hover:border-primary/50 hover:dark:border-primary transition-all duration-300\">\r\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item, getValue: getValue.bind(this), columns: columns, item: item }\" />\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"w-full flex justify-center items-center h-100 bg-white dark:bg-foreground rounded-[20px]\">\r\n <p>No se ha definido ninguna plantilla personalizada (<code>itemTemplate</code>).</p>\r\n </div>\r\n }\r\n\r\n } @else if (!isLoading('pagination')) {\r\n <div class=\"w-full flex justify-center items-center h-100 bg-white dark:bg-foreground rounded-[20px] border border-border dark:border-dark-border\">\r\n No hay datos disponibles\r\n </div>\r\n }\r\n\r\n @if (isPaginator) {\r\n <JPaginator\r\n [currentPage]=\"currentPage\" \r\n [itemsPerPageOptions]=\"itemsPerPageOptions\" \r\n [itemsPerPage]=\"itemsPerPage\"\r\n [totalItems]=\"totalItems\" \r\n [pages]=\"pages\" \r\n (pageChange)=\"handlePageChange($event)\" \r\n [isLoading]=\"isLoading('pagination')\"\r\n />\r\n }\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: JPaginatorComponent, selector: "JPaginator", inputs: ["isLoading", "currentPage", "itemsPerPageOptions", "itemsPerPage", "totalItems", "pages"], outputs: ["pageChange"] }, { kind: "component", type: JFilterComponent, selector: "JFilter", inputs: ["isLoadingSearch", "isLoadingPerPage", "isLoadingAditionalButtons", "searchPlaceholder", "columns", "itemsPerPageOptions", "itemsPerPage", "searchQuery", "filtersButton", "filtersSelect"], outputs: ["search", "itemsPerPageChange", "searchQueryChange", "onItemsPerPageChangeEvent", "clearFilters"] }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i2.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }], animations: [
3651
3651
  trigger('slideToggle', [
3652
3652
  state('collapsed', style({
@@ -3682,7 +3682,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
3682
3682
  ])
3683
3683
  ])
3684
3684
  ], template: "<div class=\"w-full\">\r\n @if (isSearch) {\r\n <JFilter\r\n [(searchQuery)]=\"searchQuery\" \r\n (search)=\"onSearch()\" \r\n [searchPlaceholder]=\"searchPlaceholder\"\r\n [(itemsPerPage)]=\"itemsPerPage\"\r\n [itemsPerPageOptions]=\"itemsPerPageOptions\" \r\n (onItemsPerPageChangeEvent)=\"onItemsPerPageChange()\"\r\n [isLoadingSearch]=\"isLoading('search')\" \r\n [isLoadingPerPage]=\"isLoading('itemsPerPage')\" \r\n [isLoadingAditionalButtons]=\"loadingStates.aditionalButtons\"\r\n (clearFilters)=\"onClearFilters($event)\"\r\n [filtersButton]=\"filtersButton\"\r\n [filtersSelect]=\"filtersSelect\"\r\n />\r\n }\r\n\r\n @if (isLoading('initialLoad') && displayData.length === 0) {\r\n <div class=\"w-full flex justify-center items-center h-100 bg-white dark:bg-foreground rounded-[20px] border border-border dark:border-dark-border\">\r\n <div class=\"flex flex-col gap-3 items-center justify-center py-4\">\r\n <lucide-icon [name]=\"icons['loading']\" size=\"30\" class=\"text-primary animate-spin\"></lucide-icon>\r\n <p>Cargando datos...</p>\r\n </div>\r\n </div>\r\n } @else if (displayData.length > 0) {\r\n\r\n @if (itemTemplate) {\r\n <div class=\"flex flex-wrap gap-4 my-4\">\r\n @for (item of displayData; track item?.id) {\r\n <div class=\"w-full sm:w-[48%] md:w-[31%] xl:w-[23.5%] min-w-[250px] max-w-full flex flex-col gap-3 rounded-xl border border-border dark:border-dark-border bg-white dark:bg-foreground shadow-sm hover:shadow-lg hover:border-primary/50 hover:dark:border-primary transition-all duration-300\">\r\n <ng-container *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item, getValue: getValue.bind(this), columns: columns, item: item }\" />\r\n </div>\r\n }\r\n </div>\r\n } @else {\r\n <div class=\"w-full flex justify-center items-center h-100 bg-white dark:bg-foreground rounded-[20px]\">\r\n <p>No se ha definido ninguna plantilla personalizada (<code>itemTemplate</code>).</p>\r\n </div>\r\n }\r\n\r\n } @else if (!isLoading('pagination')) {\r\n <div class=\"w-full flex justify-center items-center h-100 bg-white dark:bg-foreground rounded-[20px] border border-border dark:border-dark-border\">\r\n No hay datos disponibles\r\n </div>\r\n }\r\n\r\n @if (isPaginator) {\r\n <JPaginator\r\n [currentPage]=\"currentPage\" \r\n [itemsPerPageOptions]=\"itemsPerPageOptions\" \r\n [itemsPerPage]=\"itemsPerPage\"\r\n [totalItems]=\"totalItems\" \r\n [pages]=\"pages\" \r\n (pageChange)=\"handlePageChange($event)\" \r\n [isLoading]=\"isLoading('pagination')\"\r\n />\r\n }\r\n</div>\r\n" }]
3685
- }], ctorParameters: () => [{ type: i1$1.CurrencyPipe }, { type: JGenericService }, { type: JAlertToastService }, { type: ConverterService }, { type: JCalendarService }], propDecorators: { dataLoaded: [{
3685
+ }], ctorParameters: () => [{ type: i1$1.CurrencyPipe }, { type: JGenericService }, { type: JAlertToastService }, { type: JConverterService }, { type: JCalendarService }], propDecorators: { dataLoaded: [{
3686
3686
  type: Output
3687
3687
  }], endpoint: [{
3688
3688
  type: Input
@@ -3706,6 +3706,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
3706
3706
  type: Input
3707
3707
  }] } });
3708
3708
 
3709
+ // =====================================================
3710
+
3709
3711
  class JFormShared {
3710
3712
  alertToastService;
3711
3713
  icons = {
@@ -3845,7 +3847,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
3845
3847
  args: ['document:keydown.escape', ['$event']]
3846
3848
  }] } });
3847
3849
 
3848
- class ErrorMessageComponent {
3850
+ class JErrorMessageComponent {
3849
3851
  control;
3850
3852
  errorMessages = {};
3851
3853
  classes = '';
@@ -3859,10 +3861,10 @@ class ErrorMessageComponent {
3859
3861
  .filter(errorKey => this.errorMessages[errorKey])
3860
3862
  .map(errorKey => this.errorMessages[errorKey]);
3861
3863
  }
3862
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ErrorMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3863
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: ErrorMessageComponent, isStandalone: true, selector: "JErrorMessage", inputs: { control: "control", errorMessages: "errorMessages", classes: "classes" }, ngImport: i0, template: "@if (hasErrors) {\r\n<div class=\"flex flex-col text-red-600 dark:text-red-300 text-sm\">\r\n @for (message of errors; track $index) {\r\n <span [class]=\"classes\">{{ message }}</span>\r\n }\r\n</div>\r\n}", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
3864
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: JErrorMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3865
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: JErrorMessageComponent, isStandalone: true, selector: "JErrorMessage", inputs: { control: "control", errorMessages: "errorMessages", classes: "classes" }, ngImport: i0, template: "@if (hasErrors) {\r\n<div class=\"flex flex-col text-red-600 dark:text-red-300 text-sm\">\r\n @for (message of errors; track $index) {\r\n <span [class]=\"classes\">{{ message }}</span>\r\n }\r\n</div>\r\n}", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
3864
3866
  }
3865
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: ErrorMessageComponent, decorators: [{
3867
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: JErrorMessageComponent, decorators: [{
3866
3868
  type: Component,
3867
3869
  args: [{ selector: 'JErrorMessage', standalone: true, imports: [CommonModule], template: "@if (hasErrors) {\r\n<div class=\"flex flex-col text-red-600 dark:text-red-300 text-sm\">\r\n @for (message of errors; track $index) {\r\n <span [class]=\"classes\">{{ message }}</span>\r\n }\r\n</div>\r\n}" }]
3868
3870
  }], propDecorators: { control: [{
@@ -4412,7 +4414,7 @@ class JTableComponent {
4412
4414
  getExpansionState(row) {
4413
4415
  return this.expandedRows.has(row) ? 'expanded' : 'collapsed';
4414
4416
  }
4415
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: JTableComponent, deps: [{ token: i1$1.CurrencyPipe }, { token: JGenericService }, { token: JAlertToastService }, { token: ConverterService }, { token: JCalendarService }], target: i0.ɵɵFactoryTarget.Component });
4417
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.7", ngImport: i0, type: JTableComponent, deps: [{ token: i1$1.CurrencyPipe }, { token: JGenericService }, { token: JAlertToastService }, { token: JConverterService }, { token: JCalendarService }], target: i0.ɵɵFactoryTarget.Component });
4416
4418
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.7", type: JTableComponent, isStandalone: true, selector: "JCrudTable", inputs: { endpoint: "endpoint", columns: "columns", defaultFilters: "defaultFilters", isPaginator: "isPaginator", isSearch: "isSearch", itemsPerPageOptions: "itemsPerPageOptions", searchPlaceholder: "searchPlaceholder", checked: "checked", checkedValues: "checkedValues", checkedTitles: "checkedTitles", filtersButton: "filtersButton", filtersSelect: "filtersSelect", optionsTable: "optionsTable" }, outputs: { dataLoaded: "dataLoaded" }, ngImport: i0, template: "<div class=\"w-full mb-3\">\r\n\r\n @if (isSearch) {\r\n <JFilter \r\n [columns]=\"columns\" \r\n [(searchQuery)]=\"searchQuery\" \r\n (search)=\"onSearch()\" \r\n [searchPlaceholder]=\"searchPlaceholder\"\r\n [(itemsPerPage)]=\"itemsPerPage\"\r\n [itemsPerPageOptions]=\"itemsPerPageOptions\" \r\n (onItemsPerPageChangeEvent)=\"onItemsPerPageChange()\"\r\n [isLoadingSearch]=\"isLoading('search')\" \r\n [isLoadingPerPage]=\"isLoading('itemsPerPage')\" \r\n [isLoadingAditionalButtons]=\"loadingStates.aditionalButtons\"\r\n (clearFilters)=\"onClearFilters($event)\"\r\n [filtersButton]=\"filtersButton\"\r\n [filtersSelect]=\"filtersSelect\"\r\n />\r\n }\r\n\r\n <!-- Table -->\r\n <div class=\"relative border border-border dark:border-dark-border rounded\">\r\n <div class=\"overflow-x-auto rounded scroll-element pr-0!\">\r\n <table class=\"min-w-full bg-background dark:bg-dark-background rounded\">\r\n <thead class=\"bg-primary dark:bg-dark-primary text-white dark:text-white select-none\">\r\n <tr>\r\n\r\n <!-- Expandable column -->\r\n @if (hasExpandable()) {\r\n <th class=\"px-4 py-2 text-center text-xs font-medium text-white uppercase tracking-wider border-b border-border dark:border-dark-border font-bold\"></th>\r\n }\r\n\r\n <!-- Counter column -->\r\n <th\r\n class=\"px-4 py-2 text-center text-xs font-medium text-white uppercase tracking-wider border-b border-border dark:border-dark-border font-bold\">\r\n N\u00B0\r\n </th>\r\n\r\n <!-- Data columns -->\r\n @for (column of columns; track column.key) {\r\n @if (column.visible) {\r\n <th\r\n class=\"px-2 py-2 text-xs font-medium text-white uppercase tracking-wider border-b border-border dark:border-dark-border font-bold\"\r\n (click)=\"onSort(column)\" (keydown)=\"onSortKeyPress($event, column)\" tabindex=\"0\"\r\n [class.pointer-events-none]=\"isLoading('sort') && column.key !== sortingColumn\">\r\n \r\n <div class=\"flex gap-1 items-center rounded p-3 justify-center\"\r\n [ngClass]=\"{'hover:bg-dark-primary dark:hover:bg-primary transition duration-300 ease-in-out border border-border/10 dark:border-dark-border' : column.sortable, 'text-center' : column.label === 'ID'}\"\r\n [class.cursor-pointer]=\"column.sortable\">\r\n {{ column.label }}\r\n \r\n @if (column.sortable) {\r\n <div class=\"ml-1\">\r\n <!-- Mostrar icono de carga si esta columna est\u00E1 siendo ordenada -->\r\n @if (isLoading('sort') && column.key === sortingColumn) {\r\n <lucide-icon [name]=\"icons['loading']\" size=\"16\" class=\"text-white animate-spin\"></lucide-icon>\r\n } @else if (getSortKey(sortColumn) !== column.key || sortDirection === 'none') {\r\n <lucide-icon [name]=\"icons['sortDefault']\" size=\"16\" class=\"text-white\"></lucide-icon>\r\n } @else if (sortDirection === 'asc') {\r\n <lucide-icon [name]=\"icons['sortAsc']\" size=\"16\" class=\"text-white\"></lucide-icon>\r\n } @else {\r\n <lucide-icon [name]=\"icons['sortDesc']\" size=\"16\" class=\"text-white\"></lucide-icon>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </th>\r\n }\r\n }\r\n\r\n <!-- Actions column - Sticky header -->\r\n <th\r\n class=\"!sticky !right-0 bg-primary dark:bg-dark-primary min-w-[50px] px-4 py-2 text-center text-xs font-medium text-white uppercase tracking-wider border-b border-border dark:border-dark-border font-bold shadow-[-4px_0_5px_rgba(0,0,0,0.1)]\">\r\n\r\n @if (checked) {\r\n <JCheckbox onKeyPress\r\n type=\"switch\"\r\n [title]=\"titleChecked\"\r\n [isChecked]=\"isChecked\"\r\n (click)=\"checkActiveInactive(isChecked)\"\r\n [isLoading]=\"isLoading('checked')\"\r\n />\r\n } @else {\r\n <span class=\"text-[10px] opacity-80 border border-border dark:border-dark-border p-2 pl-3 pr-3 rounded-full\">Opciones</span>\r\n }\r\n <!-- Pseudoelemento para el borde central -->\r\n <div class=\"absolute top-[15px] bottom-[15px] left-0 w-[1px] bg-border dark:bg-dark-border\"></div>\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @if (isLoading('initialLoad') && displayData.length === 0) {\r\n\r\n <!-- Loading state -->\r\n <tr>\r\n <td [attr.colspan]=\"getVisibleColumnsCount() + 3\"\r\n class=\"px-4 py-8 text-center text-sm text-black dark:text-white\">\r\n <div class=\"flex flex-col gap-3 items-center justify-center py-4\">\r\n <lucide-icon [name]=\"icons['loading']\" size=\"30\" class=\"text-primary animate-spin\"></lucide-icon>\r\n <p>Cargando datos...</p>\r\n </div>\r\n </td>\r\n </tr>\r\n\r\n } @else if (displayData.length > 0) {\r\n\r\n <!-- Data rows -->\r\n @for (item of displayData; track $index) {\r\n <tr onKeyPress class=\"hover:bg-primary/10 dark:hover:bg-dark-primary/10\" (click)=\"toggleRow(item)\" [ngClass]=\"{ 'cursor-pointer': hasExpandable() }\">\r\n\r\n <!-- Expandable column -->\r\n @if (hasExpandable()) {\r\n <td class=\"px-4 py-2 h-[50px] text-center text-xs border-b border-border dark:border-dark-border text-black dark:text-white\">\r\n <lucide-icon [name]=\"icons['chevronRight']\" size=\"16\" class=\"transition-transform duration-300\"\r\n [class]=\"expandedRows.has(item) ? 'rotate-90' : ''\" />\r\n </td>\r\n }\r\n\r\n <!-- Counter column -->\r\n <td class=\"px-4 py-2 h-[50px] text-center text-xs border-b border-border dark:border-dark-border text-black dark:text-white\">\r\n {{ getRowNumber($index) }}\r\n </td>\r\n\r\n <!-- Data columns -->\r\n @for (column of columns; track column.key) {\r\n @if (column.visible) {\r\n <td\r\n class=\"px-4 py-2 h-[50px] text-xs border-b border-border dark:border-dark-border text-black dark:text-white\"\r\n [ngClass]=\"{'text-center': column.label === 'ID'}\"\r\n [ngStyle]=\"column.styles\">\r\n \r\n <span [ngClass]=\"{'p-2 pl-4 pr-4 border border-border dark:border-dark-border rounded-full': column.isDecorator}\">\r\n @if (isBoolean(getValue(item, column))) {\r\n <JCheckbox\r\n [item]=\"item\"\r\n [column]=\"column\"\r\n [getValue]=\"getValue.bind(this)\"\r\n [onCheckboxChange]=\"onCheckboxChange.bind(this)\"\r\n [iconSize]=\"20\"\r\n [disabled]=\"column?.isDisaled\"\r\n />\r\n } @else {\r\n {{ getValue(item, column) }}\r\n }\r\n\r\n </span>\r\n </td>\r\n }\r\n }\r\n\r\n <!-- Actions column - Sticky cell -->\r\n <td\r\n class=\"!sticky !right-0 bg-background dark:bg-dark-background text-center whitespace-nowrap text-sm border-b border-border dark:border-dark-border shadow-[-4px_0_5px_rgba(0,0,0,0.1)] relative\">\r\n <div class=\"flex justify-center items-center space-x-2 min-w-[50px] px-4 py-2 h-[50px]\">\r\n @for (option of optionsTable; track $index) {\r\n @if (getIsVisible(option, item)) {\r\n <JButton onKeyPress \r\n [icon]=\"getIcon(option.icon, item)\"\r\n [iconSize]=\"20\" \r\n (clicked)=\"$event.stopPropagation(); onButtonClick(option, item)\"\r\n [tooltip]=\"getTooltip(option.tooltip ?? '', item)\"\r\n [tooltipPosition]=\"option.tooltipPosition ?? 'top'\"\r\n [disabled]=\"getDisabled(option, item)\"\r\n [isLoading]=\"isAditionalButtonLoading(option.type ?? '', item?.id_student_course)\"\r\n [classes]=\"option.classes ?? ''\"\r\n [ngClasses]=\"mergeNgClasses(option.ngClass, item)\" \r\n />\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Pseudoelemento para el borde central -->\r\n <div class=\"absolute top-[15px] bottom-[15px] left-0 w-[1px] bg-border dark:bg-dark-border\"></div>\r\n </td>\r\n </tr>\r\n\r\n @if (hasExpandable()) {\r\n <tr>\r\n <td [attr.colspan]=\"getVisibleColumnsCount() + 3\">\r\n <div [@slideToggle]=\"getExpansionState(item)\" [ngClass]=\"{'border-b border-border dark:border-dark-border': expandedRows.has(item)}\"\r\n class=\"overflow-hidden transition-all duration-300 ease-in-out\"\r\n >\r\n <div class=\"w-full border border-gray-300 dark:border-zinc-700 bg-white dark:bg-zinc-900 p-3\">\r\n <div [innerHTML]=\"getExpandedContent(item)\"></div>\r\n </div> \r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n }\r\n } @else if (!isLoading('pagination')) {\r\n <!-- Empty state -->\r\n <tr>\r\n <td [attr.colspan]=\"getVisibleColumnsCount() + 3\"\r\n class=\"px-4 py-8 text-center text-sm text-black dark:text-white\">\r\n No hay datos disponibles\r\n </td>\r\n </tr>\r\n }\r\n\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n\r\n @if (isPaginator) {\r\n <JPaginator \r\n [currentPage]=\"currentPage\" \r\n [itemsPerPageOptions]=\"itemsPerPageOptions\" \r\n [itemsPerPage]=\"itemsPerPage\"\r\n [totalItems]=\"totalItems\" \r\n [pages]=\"pages\" \r\n (pageChange)=\"handlePageChange($event)\" \r\n [isLoading]=\"isLoading('pagination')\"\r\n />\r\n }\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: JPaginatorComponent, selector: "JPaginator", inputs: ["isLoading", "currentPage", "itemsPerPageOptions", "itemsPerPage", "totalItems", "pages"], outputs: ["pageChange"] }, { kind: "component", type: JFilterComponent, selector: "JFilter", inputs: ["isLoadingSearch", "isLoadingPerPage", "isLoadingAditionalButtons", "searchPlaceholder", "columns", "itemsPerPageOptions", "itemsPerPage", "searchQuery", "filtersButton", "filtersSelect"], outputs: ["search", "itemsPerPageChange", "searchQueryChange", "onItemsPerPageChangeEvent", "clearFilters"] }, { kind: "ngmodule", type: LucideAngularModule }, { kind: "component", type: i2.LucideAngularComponent, selector: "lucide-angular, lucide-icon, i-lucide, span-lucide", inputs: ["class", "name", "img", "color", "absoluteStrokeWidth", "size", "strokeWidth"] }, { kind: "component", type: JButtonComponent, selector: "JButton", inputs: ["type", "disabled", "isLoading", "icon", "iconSize", "text", "isChangeIcon", "iconChange", "tooltip", "tooltipPosition", "classes", "ngClasses"], outputs: ["clicked"] }, { kind: "component", type: JCheckboxComponent, selector: "JCheckbox", inputs: ["type", "icon", "iconSize", "disabled", "isLoading", "classes", "title", "isChecked", "item", "column", "getValue", "onCheckboxChange", "toggleSwitch"] }], animations: [
4417
4419
  trigger('slideToggle', [
4418
4420
  state('collapsed', style({
@@ -4448,7 +4450,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
4448
4450
  ])
4449
4451
  ])
4450
4452
  ], template: "<div class=\"w-full mb-3\">\r\n\r\n @if (isSearch) {\r\n <JFilter \r\n [columns]=\"columns\" \r\n [(searchQuery)]=\"searchQuery\" \r\n (search)=\"onSearch()\" \r\n [searchPlaceholder]=\"searchPlaceholder\"\r\n [(itemsPerPage)]=\"itemsPerPage\"\r\n [itemsPerPageOptions]=\"itemsPerPageOptions\" \r\n (onItemsPerPageChangeEvent)=\"onItemsPerPageChange()\"\r\n [isLoadingSearch]=\"isLoading('search')\" \r\n [isLoadingPerPage]=\"isLoading('itemsPerPage')\" \r\n [isLoadingAditionalButtons]=\"loadingStates.aditionalButtons\"\r\n (clearFilters)=\"onClearFilters($event)\"\r\n [filtersButton]=\"filtersButton\"\r\n [filtersSelect]=\"filtersSelect\"\r\n />\r\n }\r\n\r\n <!-- Table -->\r\n <div class=\"relative border border-border dark:border-dark-border rounded\">\r\n <div class=\"overflow-x-auto rounded scroll-element pr-0!\">\r\n <table class=\"min-w-full bg-background dark:bg-dark-background rounded\">\r\n <thead class=\"bg-primary dark:bg-dark-primary text-white dark:text-white select-none\">\r\n <tr>\r\n\r\n <!-- Expandable column -->\r\n @if (hasExpandable()) {\r\n <th class=\"px-4 py-2 text-center text-xs font-medium text-white uppercase tracking-wider border-b border-border dark:border-dark-border font-bold\"></th>\r\n }\r\n\r\n <!-- Counter column -->\r\n <th\r\n class=\"px-4 py-2 text-center text-xs font-medium text-white uppercase tracking-wider border-b border-border dark:border-dark-border font-bold\">\r\n N\u00B0\r\n </th>\r\n\r\n <!-- Data columns -->\r\n @for (column of columns; track column.key) {\r\n @if (column.visible) {\r\n <th\r\n class=\"px-2 py-2 text-xs font-medium text-white uppercase tracking-wider border-b border-border dark:border-dark-border font-bold\"\r\n (click)=\"onSort(column)\" (keydown)=\"onSortKeyPress($event, column)\" tabindex=\"0\"\r\n [class.pointer-events-none]=\"isLoading('sort') && column.key !== sortingColumn\">\r\n \r\n <div class=\"flex gap-1 items-center rounded p-3 justify-center\"\r\n [ngClass]=\"{'hover:bg-dark-primary dark:hover:bg-primary transition duration-300 ease-in-out border border-border/10 dark:border-dark-border' : column.sortable, 'text-center' : column.label === 'ID'}\"\r\n [class.cursor-pointer]=\"column.sortable\">\r\n {{ column.label }}\r\n \r\n @if (column.sortable) {\r\n <div class=\"ml-1\">\r\n <!-- Mostrar icono de carga si esta columna est\u00E1 siendo ordenada -->\r\n @if (isLoading('sort') && column.key === sortingColumn) {\r\n <lucide-icon [name]=\"icons['loading']\" size=\"16\" class=\"text-white animate-spin\"></lucide-icon>\r\n } @else if (getSortKey(sortColumn) !== column.key || sortDirection === 'none') {\r\n <lucide-icon [name]=\"icons['sortDefault']\" size=\"16\" class=\"text-white\"></lucide-icon>\r\n } @else if (sortDirection === 'asc') {\r\n <lucide-icon [name]=\"icons['sortAsc']\" size=\"16\" class=\"text-white\"></lucide-icon>\r\n } @else {\r\n <lucide-icon [name]=\"icons['sortDesc']\" size=\"16\" class=\"text-white\"></lucide-icon>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </th>\r\n }\r\n }\r\n\r\n <!-- Actions column - Sticky header -->\r\n <th\r\n class=\"!sticky !right-0 bg-primary dark:bg-dark-primary min-w-[50px] px-4 py-2 text-center text-xs font-medium text-white uppercase tracking-wider border-b border-border dark:border-dark-border font-bold shadow-[-4px_0_5px_rgba(0,0,0,0.1)]\">\r\n\r\n @if (checked) {\r\n <JCheckbox onKeyPress\r\n type=\"switch\"\r\n [title]=\"titleChecked\"\r\n [isChecked]=\"isChecked\"\r\n (click)=\"checkActiveInactive(isChecked)\"\r\n [isLoading]=\"isLoading('checked')\"\r\n />\r\n } @else {\r\n <span class=\"text-[10px] opacity-80 border border-border dark:border-dark-border p-2 pl-3 pr-3 rounded-full\">Opciones</span>\r\n }\r\n <!-- Pseudoelemento para el borde central -->\r\n <div class=\"absolute top-[15px] bottom-[15px] left-0 w-[1px] bg-border dark:bg-dark-border\"></div>\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @if (isLoading('initialLoad') && displayData.length === 0) {\r\n\r\n <!-- Loading state -->\r\n <tr>\r\n <td [attr.colspan]=\"getVisibleColumnsCount() + 3\"\r\n class=\"px-4 py-8 text-center text-sm text-black dark:text-white\">\r\n <div class=\"flex flex-col gap-3 items-center justify-center py-4\">\r\n <lucide-icon [name]=\"icons['loading']\" size=\"30\" class=\"text-primary animate-spin\"></lucide-icon>\r\n <p>Cargando datos...</p>\r\n </div>\r\n </td>\r\n </tr>\r\n\r\n } @else if (displayData.length > 0) {\r\n\r\n <!-- Data rows -->\r\n @for (item of displayData; track $index) {\r\n <tr onKeyPress class=\"hover:bg-primary/10 dark:hover:bg-dark-primary/10\" (click)=\"toggleRow(item)\" [ngClass]=\"{ 'cursor-pointer': hasExpandable() }\">\r\n\r\n <!-- Expandable column -->\r\n @if (hasExpandable()) {\r\n <td class=\"px-4 py-2 h-[50px] text-center text-xs border-b border-border dark:border-dark-border text-black dark:text-white\">\r\n <lucide-icon [name]=\"icons['chevronRight']\" size=\"16\" class=\"transition-transform duration-300\"\r\n [class]=\"expandedRows.has(item) ? 'rotate-90' : ''\" />\r\n </td>\r\n }\r\n\r\n <!-- Counter column -->\r\n <td class=\"px-4 py-2 h-[50px] text-center text-xs border-b border-border dark:border-dark-border text-black dark:text-white\">\r\n {{ getRowNumber($index) }}\r\n </td>\r\n\r\n <!-- Data columns -->\r\n @for (column of columns; track column.key) {\r\n @if (column.visible) {\r\n <td\r\n class=\"px-4 py-2 h-[50px] text-xs border-b border-border dark:border-dark-border text-black dark:text-white\"\r\n [ngClass]=\"{'text-center': column.label === 'ID'}\"\r\n [ngStyle]=\"column.styles\">\r\n \r\n <span [ngClass]=\"{'p-2 pl-4 pr-4 border border-border dark:border-dark-border rounded-full': column.isDecorator}\">\r\n @if (isBoolean(getValue(item, column))) {\r\n <JCheckbox\r\n [item]=\"item\"\r\n [column]=\"column\"\r\n [getValue]=\"getValue.bind(this)\"\r\n [onCheckboxChange]=\"onCheckboxChange.bind(this)\"\r\n [iconSize]=\"20\"\r\n [disabled]=\"column?.isDisaled\"\r\n />\r\n } @else {\r\n {{ getValue(item, column) }}\r\n }\r\n\r\n </span>\r\n </td>\r\n }\r\n }\r\n\r\n <!-- Actions column - Sticky cell -->\r\n <td\r\n class=\"!sticky !right-0 bg-background dark:bg-dark-background text-center whitespace-nowrap text-sm border-b border-border dark:border-dark-border shadow-[-4px_0_5px_rgba(0,0,0,0.1)] relative\">\r\n <div class=\"flex justify-center items-center space-x-2 min-w-[50px] px-4 py-2 h-[50px]\">\r\n @for (option of optionsTable; track $index) {\r\n @if (getIsVisible(option, item)) {\r\n <JButton onKeyPress \r\n [icon]=\"getIcon(option.icon, item)\"\r\n [iconSize]=\"20\" \r\n (clicked)=\"$event.stopPropagation(); onButtonClick(option, item)\"\r\n [tooltip]=\"getTooltip(option.tooltip ?? '', item)\"\r\n [tooltipPosition]=\"option.tooltipPosition ?? 'top'\"\r\n [disabled]=\"getDisabled(option, item)\"\r\n [isLoading]=\"isAditionalButtonLoading(option.type ?? '', item?.id_student_course)\"\r\n [classes]=\"option.classes ?? ''\"\r\n [ngClasses]=\"mergeNgClasses(option.ngClass, item)\" \r\n />\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Pseudoelemento para el borde central -->\r\n <div class=\"absolute top-[15px] bottom-[15px] left-0 w-[1px] bg-border dark:bg-dark-border\"></div>\r\n </td>\r\n </tr>\r\n\r\n @if (hasExpandable()) {\r\n <tr>\r\n <td [attr.colspan]=\"getVisibleColumnsCount() + 3\">\r\n <div [@slideToggle]=\"getExpansionState(item)\" [ngClass]=\"{'border-b border-border dark:border-dark-border': expandedRows.has(item)}\"\r\n class=\"overflow-hidden transition-all duration-300 ease-in-out\"\r\n >\r\n <div class=\"w-full border border-gray-300 dark:border-zinc-700 bg-white dark:bg-zinc-900 p-3\">\r\n <div [innerHTML]=\"getExpandedContent(item)\"></div>\r\n </div> \r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n }\r\n } @else if (!isLoading('pagination')) {\r\n <!-- Empty state -->\r\n <tr>\r\n <td [attr.colspan]=\"getVisibleColumnsCount() + 3\"\r\n class=\"px-4 py-8 text-center text-sm text-black dark:text-white\">\r\n No hay datos disponibles\r\n </td>\r\n </tr>\r\n }\r\n\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n\r\n @if (isPaginator) {\r\n <JPaginator \r\n [currentPage]=\"currentPage\" \r\n [itemsPerPageOptions]=\"itemsPerPageOptions\" \r\n [itemsPerPage]=\"itemsPerPage\"\r\n [totalItems]=\"totalItems\" \r\n [pages]=\"pages\" \r\n (pageChange)=\"handlePageChange($event)\" \r\n [isLoading]=\"isLoading('pagination')\"\r\n />\r\n }\r\n</div>" }]
4451
- }], ctorParameters: () => [{ type: i1$1.CurrencyPipe }, { type: JGenericService }, { type: JAlertToastService }, { type: ConverterService }, { type: JCalendarService }], propDecorators: { dataLoaded: [{
4453
+ }], ctorParameters: () => [{ type: i1$1.CurrencyPipe }, { type: JGenericService }, { type: JAlertToastService }, { type: JConverterService }, { type: JCalendarService }], propDecorators: { dataLoaded: [{
4452
4454
  type: Output
4453
4455
  }], endpoint: [{
4454
4456
  type: Input
@@ -4478,6 +4480,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
4478
4480
  type: Input
4479
4481
  }] } });
4480
4482
 
4483
+ // ===================================================
4484
+
4481
4485
  // =======================================
4482
4486
  // Publicar libreria
4483
4487
  // =======================================
@@ -4495,5 +4499,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.7", ngImpor
4495
4499
  * Generated bundle index. Do not edit.
4496
4500
  */
4497
4501
 
4498
- export { API_URL, CardComponent, ErrorMessageComponent, JAlertDialogComponent, JAlertDialogService, JAlertToastComponent, JAlertToastService, JButtonComponent, JCheckboxComponent, JContentFormComponent, JDialogComponent, JDialogShared, JErrorHandlerService, JFilterComponent, JFormComponent, JFormShared, JGenericService, JHttpParamsService, JInputComponent, JLabelComponent, JModeToggleComponent, JPaginatorComponent, JSelectComponent, JTableComponent, JThemeComponent, JToggleRadioComponent, JTooltipModule };
4502
+ export { API_URL, CardComponent, JAlertDialogComponent, JAlertDialogService, JAlertToastComponent, JAlertToastService, JButtonComponent, JCheckboxComponent, JContentFormComponent, JConverterService, JDialogComponent, JDialogShared, JErrorHandlerService, JErrorMessageComponent, JFilterComponent, JFormComponent, JFormShared, JGenericService, JHttpParamsService, JInputComponent, JLabelComponent, JModeToggleComponent, JPaginatorComponent, JSelectComponent, JTableComponent, JThemeComponent, JToggleRadioComponent, JTooltipModule };
4499
4503
  //# sourceMappingURL=tailjng.mjs.map