@c80/ui 1.0.64 → 2.0.0

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 (110) hide show
  1. package/README.md +1 -1
  2. package/esm2022/index.js +3 -0
  3. package/esm2022/index.js.map +1 -1
  4. package/esm2022/lib/action-list/action-list.component.js +5 -5
  5. package/esm2022/lib/action-list/action-list.component.js.map +1 -1
  6. package/esm2022/lib/action-list/action-list.types.js +0 -1
  7. package/esm2022/lib/card-level/card-level.component.js +12 -12
  8. package/esm2022/lib/card-level/card-level.component.js.map +1 -1
  9. package/esm2022/lib/card-level/card-level.interface.js +0 -1
  10. package/esm2022/lib/error-notification/error-notification.component.js +5 -5
  11. package/esm2022/lib/error-notification/error-notification.component.js.map +1 -1
  12. package/esm2022/lib/error-notification/error-notification.types.js +0 -1
  13. package/esm2022/lib/header/header.component.js +7 -6
  14. package/esm2022/lib/header/header.component.js.map +1 -1
  15. package/esm2022/lib/header/header.types.js +0 -1
  16. package/esm2022/lib/icon/icon.component.js +26 -26
  17. package/esm2022/lib/icon/icon.component.js.map +1 -1
  18. package/esm2022/lib/icon/icon.definitions.js +3 -0
  19. package/esm2022/lib/icon/icon.definitions.js.map +1 -1
  20. package/esm2022/lib/icon/icon.types.js +0 -1
  21. package/esm2022/lib/icon/theme.service.js +23 -8
  22. package/esm2022/lib/icon/theme.service.js.map +1 -1
  23. package/esm2022/lib/info-list/info-list.component.js +4 -4
  24. package/esm2022/lib/info-list/info-list.component.js.map +1 -1
  25. package/esm2022/lib/info-list/info-list.types.js +0 -1
  26. package/esm2022/lib/info-message/index.js +3 -0
  27. package/esm2022/lib/info-message/index.js.map +1 -0
  28. package/esm2022/lib/info-message/info-message.component.js +25 -0
  29. package/esm2022/lib/info-message/info-message.component.js.map +1 -0
  30. package/esm2022/lib/info-message/info-message.types.js +1 -0
  31. package/esm2022/lib/info-message/info-message.types.js.map +1 -0
  32. package/esm2022/lib/input-field/input-field.component.js +11 -11
  33. package/esm2022/lib/input-field/input-field.component.js.map +1 -1
  34. package/esm2022/lib/input-search/c80-input-search.component.js +5 -5
  35. package/esm2022/lib/input-search/c80-input-search.component.js.map +1 -1
  36. package/esm2022/lib/legal-disclaimer/index.js +2 -0
  37. package/esm2022/lib/legal-disclaimer/index.js.map +1 -0
  38. package/esm2022/lib/legal-disclaimer/legal-disclaimer.component.js +21 -0
  39. package/esm2022/lib/legal-disclaimer/legal-disclaimer.component.js.map +1 -0
  40. package/esm2022/lib/modal/modal.component.js +12 -5
  41. package/esm2022/lib/modal/modal.component.js.map +1 -1
  42. package/esm2022/lib/modal/modal.service.js +22 -10
  43. package/esm2022/lib/modal/modal.service.js.map +1 -1
  44. package/esm2022/lib/modal/modal.types.js +0 -1
  45. package/esm2022/lib/modal/modal.types.js.map +1 -1
  46. package/esm2022/lib/navigation-card/index.js +3 -0
  47. package/esm2022/lib/navigation-card/index.js.map +1 -0
  48. package/esm2022/lib/navigation-card/navigation-card.component.js +18 -0
  49. package/esm2022/lib/navigation-card/navigation-card.component.js.map +1 -0
  50. package/esm2022/lib/navigation-card/navigation-card.types.js +1 -0
  51. package/esm2022/lib/navigation-card/navigation-card.types.js.map +1 -0
  52. package/esm2022/lib/profile-stats/profile-stats.component.js +4 -4
  53. package/esm2022/lib/profile-stats/profile-stats.component.js.map +1 -1
  54. package/esm2022/lib/profile-stats/profile-stats.types.js +0 -1
  55. package/esm2022/lib/rating-display/rating-display.component.js +7 -7
  56. package/esm2022/lib/rating-display/rating-display.component.js.map +1 -1
  57. package/esm2022/lib/rating-stars/rating-stars.component.js +8 -8
  58. package/esm2022/lib/rating-stars/rating-stars.component.js.map +1 -1
  59. package/esm2022/lib/select/select.component.js +17 -17
  60. package/esm2022/lib/select/select.component.js.map +1 -1
  61. package/esm2022/lib/select/select.types.js +0 -1
  62. package/esm2022/lib/snackbar/snackbar.component.js +6 -6
  63. package/esm2022/lib/snackbar/snackbar.component.js.map +1 -1
  64. package/esm2022/lib/snackbar/snackbar.service.js +3 -3
  65. package/esm2022/lib/snackbar/snackbar.types.js +0 -1
  66. package/esm2022/lib/spinner/spinner.component.js +7 -7
  67. package/esm2022/lib/spinner/spinner.component.js.map +1 -1
  68. package/esm2022/lib/stat-card/stat-card.component.js +5 -5
  69. package/esm2022/lib/stat-card/stat-card.component.js.map +1 -1
  70. package/esm2022/lib/stat-card/stat-card.types.js +0 -1
  71. package/esm2022/lib/tab/c80-tab.component.js +6 -6
  72. package/esm2022/lib/tab/c80-tab.component.js.map +1 -1
  73. package/esm2022/lib/tab/c80-tab.types.js +0 -1
  74. package/esm2022/lib/tab/directives/c80-tab-item.directive.js +3 -3
  75. package/esm2022/lib/tab/directives/c80-tab-label.directive.js +3 -3
  76. package/esm2022/lib/table/table-column-visibility.service.js +3 -3
  77. package/esm2022/lib/table/table-crud-state.service.js +7 -7
  78. package/esm2022/lib/table/table-crud-state.service.js.map +1 -1
  79. package/esm2022/lib/table/table-data-converter.service.js +3 -3
  80. package/esm2022/lib/table/table-data-utils.service.js +3 -3
  81. package/esm2022/lib/table/table-dto-mapper.service.js +32 -35
  82. package/esm2022/lib/table/table-dto-mapper.service.js.map +1 -1
  83. package/esm2022/lib/table/table-pagination.service.js +10 -10
  84. package/esm2022/lib/table/table-pagination.service.js.map +1 -1
  85. package/esm2022/lib/table/table-selection.service.js +22 -22
  86. package/esm2022/lib/table/table-selection.service.js.map +1 -1
  87. package/esm2022/lib/table/table.component.js +46 -30
  88. package/esm2022/lib/table/table.component.js.map +1 -1
  89. package/esm2022/lib/table/table.types.js +0 -1
  90. package/esm2022/lib/table/table.utils.js +4 -3
  91. package/esm2022/lib/table/table.utils.js.map +1 -1
  92. package/index.d.ts +3 -0
  93. package/lib/header/header.component.d.ts +2 -1
  94. package/lib/icon/theme.service.d.ts +34 -0
  95. package/lib/info-message/index.d.ts +2 -0
  96. package/lib/info-message/info-message.component.d.ts +17 -0
  97. package/lib/info-message/info-message.types.d.ts +5 -0
  98. package/lib/legal-disclaimer/index.d.ts +1 -0
  99. package/lib/legal-disclaimer/legal-disclaimer.component.d.ts +15 -0
  100. package/lib/modal/modal.component.d.ts +5 -0
  101. package/lib/modal/modal.service.d.ts +11 -2
  102. package/lib/modal/modal.types.d.ts +1 -0
  103. package/lib/navigation-card/index.d.ts +2 -0
  104. package/lib/navigation-card/navigation-card.component.d.ts +10 -0
  105. package/lib/navigation-card/navigation-card.types.d.ts +7 -0
  106. package/lib/table/table-dto-mapper.service.d.ts +12 -5
  107. package/lib/table/table-selection.service.d.ts +1 -1
  108. package/lib/table/table.component.d.ts +2 -1
  109. package/lib/table/table.utils.d.ts +2 -1
  110. package/package.json +4 -3
@@ -1 +1 @@
1
- {"version":3,"file":"table-crud-state.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-crud-state.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, signal, inject, type Signal } from '@angular/core';\nimport type { TableColDef } from './table.types';\nimport { TableColumnVisibilityService } from './table-column-visibility.service';\nimport { TableDataUtilsService } from './table-data-utils.service';\n\ninterface CrudState<T extends Record<string, unknown>> {\n creating: Signal<boolean>;\n newRow: Signal<Partial<T> | null>;\n editing: Signal<string | null>;\n editRow: Signal<Partial<T> | null>;\n startCreate: (context: { columns: TableColDef[]; data: T[] }) => void;\n cancelCreate: () => void;\n updateNewRow: (key: string, value: unknown) => void;\n startEdit: (context: { row: T; columns: TableColDef[]; data: T[] }) => void;\n cancelEdit: () => void;\n updateEditRow: (key: string, value: unknown) => void;\n applyInputValues: (partialValues: Partial<T>) => void;\n}\n\n/**\n * Servicio para gestionar el estado CRUD (Crear, Leer, Actualizar, Eliminar) en tablas C80\n *\n * Maneja:\n * - Estado de creación y edición\n * - Gestión de datos temporales (newRow, editRow)\n * - Aplicación de valores dinámicos\n * - Validación y conversión de datos\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableCrudStateService {\n\n private readonly visibilityService = inject(TableColumnVisibilityService);\n private readonly dataUtils = inject(TableDataUtilsService);\n\n /**\n * Filtra columnas visibles y editables\n */\n private getEditableColumns<T extends Record<string, unknown>>(\n columns: TableColDef[],\n data: T[],\n includeHiddenIfNull: boolean\n ): TableColDef[] {\n return columns.filter(\n col => this.visibilityService.isColumnVisible(col, data, { forceShowInCreation: includeHiddenIfNull }) && !col.readOnly\n );\n }\n\n /**\n * Inicializa row para creación con valores por defecto\n */\n private initializeNewRow<T extends Record<string, unknown>>(\n columns: TableColDef[],\n data: T[]\n ): Partial<T> {\n const row: Partial<T> = {};\n for (const col of this.getEditableColumns(columns, data, true)) {\n const defaultValue = col.default === undefined ? '' : col.default;\n (row as Record<string, unknown>)[col.accessor] = defaultValue;\n }\n return row;\n }\n\n /**\n * Inicializa row para edición con valores actuales\n */\n private initializeEditRow<T extends Record<string, unknown>>(\n row: T,\n columns: TableColDef[],\n data: T[]\n ): Partial<T> {\n const edit: Partial<T> = {};\n for (const col of this.getEditableColumns(columns, data, true)) {\n const value = this.dataUtils.getCellValue(row, col.accessor);\n (edit as Record<string, unknown>)[col.accessor] = value;\n }\n return edit;\n }\n\n /**\n * Inicializa el estado CRUD para una nueva tabla\n * @returns Objeto con signals y métodos para gestión CRUD\n */\n createCrudState<T extends Record<string, unknown>>(): CrudState<T> {\n const creating = signal(false);\n const newRow = signal<Partial<T> | null>(null);\n const editing = signal<string | null>(null);\n const editRow = signal<Partial<T> | null>(null);\n\n return {\n creating: creating.asReadonly(),\n newRow: newRow.asReadonly(),\n editing: editing.asReadonly(),\n editRow: editRow.asReadonly(),\n startCreate: (context: { columns: TableColDef[]; data: T[] }) => this.startCreate(creating, newRow, context),\n cancelCreate: () => this.cancelCreate(creating, newRow),\n updateNewRow: (key: string, value: unknown) => this.updateRow(newRow, key, value),\n startEdit: (context: { row: T; columns: TableColDef[]; data: T[] }) => this.startEdit({ editing, editRow }, context),\n cancelEdit: () => this.cancelEdit(editing, editRow),\n updateEditRow: (key: string, value: unknown) => this.updateRow(editRow, key, value),\n applyInputValues: (partialValues: Partial<T>) => this.applyInputValues({ creating, newRow, editing, editRow }, partialValues),\n };\n }\n\n private startCreate<T extends Record<string, unknown>>(\n creating: ReturnType<typeof signal<boolean>>,\n newRow: ReturnType<typeof signal<Partial<T> | null>>,\n context: { columns: TableColDef[]; data: T[] }\n ): void {\n creating.set(true);\n newRow.set(this.initializeNewRow(context.columns, context.data));\n }\n\n private cancelCreate<T extends Record<string, unknown>>(\n creating: ReturnType<typeof signal<boolean>>,\n newRow: ReturnType<typeof signal<Partial<T> | null>>\n ): void {\n creating.set(false);\n newRow.set(null);\n }\n\n private updateRow<T extends Record<string, unknown>>(\n rowSignal: ReturnType<typeof signal<Partial<T> | null>>,\n key: string,\n value: unknown\n ): void {\n const current = rowSignal();\n if (!current) return;\n rowSignal.set({ ...current, [key]: value });\n }\n\n private startEdit<T extends Record<string, unknown>>(\n signals: {\n editing: ReturnType<typeof signal<string | null>>;\n editRow: ReturnType<typeof signal<Partial<T> | null>>;\n },\n context: { row: T; columns: TableColDef[]; data: T[] }\n ): void {\n signals.editing.set(context.row['id'] as string);\n signals.editRow.set(this.initializeEditRow(context.row, context.columns, context.data));\n }\n\n private cancelEdit<T extends Record<string, unknown>>(\n editing: ReturnType<typeof signal<string | null>>,\n editRow: ReturnType<typeof signal<Partial<T> | null>>\n ): void {\n editing.set(null);\n editRow.set(null);\n }\n\n private applyInputValues<T extends Record<string, unknown>>(\n signals: {\n creating: ReturnType<typeof signal<boolean>>;\n newRow: ReturnType<typeof signal<Partial<T> | null>>;\n editing: ReturnType<typeof signal<string | null>>;\n editRow: ReturnType<typeof signal<Partial<T> | null>>;\n },\n partialValues: Partial<T>\n ): void {\n if (!signals.creating() && signals.editing() === null) return;\n\n if (signals.creating()) {\n const currentRow = signals.newRow();\n if (currentRow) {\n signals.newRow.set({ ...currentRow, ...partialValues });\n }\n } else {\n const currentEditRow = signals.editRow();\n if (currentEditRow) {\n signals.editRow.set({ ...currentEditRow, ...partialValues });\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"table-crud-state.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-crud-state.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, signal, inject, type Signal } from '@angular/core';\nimport type { TableColDef } from './table.types';\nimport { TableColumnVisibilityService } from './table-column-visibility.service';\nimport { TableDataUtilsService } from './table-data-utils.service';\n\ninterface CrudState<T extends Record<string, unknown>> {\n creating: Signal<boolean>;\n newRow: Signal<Partial<T> | null>;\n editing: Signal<string | null>;\n editRow: Signal<Partial<T> | null>;\n startCreate: (context: { columns: TableColDef[]; data: T[] }) => void;\n cancelCreate: () => void;\n updateNewRow: (key: string, value: unknown) => void;\n startEdit: (context: { row: T; columns: TableColDef[]; data: T[] }) => void;\n cancelEdit: () => void;\n updateEditRow: (key: string, value: unknown) => void;\n applyInputValues: (partialValues: Partial<T>) => void;\n}\n\n/**\n * Servicio para gestionar el estado CRUD (Crear, Leer, Actualizar, Eliminar) en tablas C80\n *\n * Maneja:\n * - Estado de creación y edición\n * - Gestión de datos temporales (newRow, editRow)\n * - Aplicación de valores dinámicos\n * - Validación y conversión de datos\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableCrudStateService {\n\n private readonly visibilityService = inject(TableColumnVisibilityService);\n private readonly dataUtils = inject(TableDataUtilsService);\n\n /**\n * Filtra columnas visibles y editables\n */\n private getEditableColumns<T extends Record<string, unknown>>(\n columns: TableColDef[],\n data: T[],\n includeHiddenIfNull: boolean\n ): TableColDef[] {\n return columns.filter(\n col => this.visibilityService.isColumnVisible(col, data, { forceShowInCreation: includeHiddenIfNull }) && !col.readOnly\n );\n }\n\n /**\n * Inicializa row para creación con valores por defecto\n */\n private initializeNewRow<T extends Record<string, unknown>>(\n columns: TableColDef[],\n data: T[]\n ): Partial<T> {\n const row: Partial<T> = {};\n for (const col of this.getEditableColumns(columns, data, true)) {\n const defaultValue = col.default === undefined ? '' : col.default;\n (row as Record<string, unknown>)[col.accessor] = defaultValue;\n }\n return row;\n }\n\n /**\n * Inicializa row para edición con valores actuales\n */\n private initializeEditRow<T extends Record<string, unknown>>(\n row: T,\n columns: TableColDef[],\n data: T[]\n ): Partial<T> {\n const edit: Partial<T> = {};\n for (const col of this.getEditableColumns(columns, data, true)) {\n const value = this.dataUtils.getCellValue(row, col.accessor);\n (edit as Record<string, unknown>)[col.accessor] = value;\n }\n return edit;\n }\n\n /**\n * Inicializa el estado CRUD para una nueva tabla\n * @returns Objeto con signals y métodos para gestión CRUD\n */\n createCrudState<T extends Record<string, unknown>>(): CrudState<T> {\n const creating = signal(false);\n const newRow = signal<Partial<T> | null>(null);\n const editing = signal<string | null>(null);\n const editRow = signal<Partial<T> | null>(null);\n\n return {\n creating: creating.asReadonly(),\n newRow: newRow.asReadonly(),\n editing: editing.asReadonly(),\n editRow: editRow.asReadonly(),\n startCreate: (context: { columns: TableColDef[]; data: T[] }) => this.startCreate(creating, newRow, context),\n cancelCreate: () => this.cancelCreate(creating, newRow),\n updateNewRow: (key: string, value: unknown) => this.updateRow(newRow, key, value),\n startEdit: (context: { row: T; columns: TableColDef[]; data: T[] }) => this.startEdit({ editing, editRow }, context),\n cancelEdit: () => this.cancelEdit(editing, editRow),\n updateEditRow: (key: string, value: unknown) => this.updateRow(editRow, key, value),\n applyInputValues: (partialValues: Partial<T>) => this.applyInputValues({ creating, newRow, editing, editRow }, partialValues),\n };\n }\n\n private startCreate<T extends Record<string, unknown>>(\n creating: ReturnType<typeof signal<boolean>>,\n newRow: ReturnType<typeof signal<Partial<T> | null>>,\n context: { columns: TableColDef[]; data: T[] }\n ): void {\n creating.set(true);\n newRow.set(this.initializeNewRow(context.columns, context.data));\n }\n\n private cancelCreate<T extends Record<string, unknown>>(\n creating: ReturnType<typeof signal<boolean>>,\n newRow: ReturnType<typeof signal<Partial<T> | null>>\n ): void {\n creating.set(false);\n newRow.set(null);\n }\n\n private updateRow<T extends Record<string, unknown>>(\n rowSignal: ReturnType<typeof signal<Partial<T> | null>>,\n key: string,\n value: unknown\n ): void {\n const current = rowSignal();\n if (!current) return;\n rowSignal.set({ ...current, [key]: value });\n }\n\n private startEdit<T extends Record<string, unknown>>(\n signals: {\n editing: ReturnType<typeof signal<string | null>>;\n editRow: ReturnType<typeof signal<Partial<T> | null>>;\n },\n context: { row: T; columns: TableColDef[]; data: T[] }\n ): void {\n signals.editing.set(context.row['id'] as string);\n signals.editRow.set(this.initializeEditRow(context.row, context.columns, context.data));\n }\n\n private cancelEdit<T extends Record<string, unknown>>(\n editing: ReturnType<typeof signal<string | null>>,\n editRow: ReturnType<typeof signal<Partial<T> | null>>\n ): void {\n editing.set(null);\n editRow.set(null);\n }\n\n private applyInputValues<T extends Record<string, unknown>>(\n signals: {\n creating: ReturnType<typeof signal<boolean>>;\n newRow: ReturnType<typeof signal<Partial<T> | null>>;\n editing: ReturnType<typeof signal<string | null>>;\n editRow: ReturnType<typeof signal<Partial<T> | null>>;\n },\n partialValues: Partial<T>\n ): void {\n if (!signals.creating() && signals.editing() === null) return;\n\n if (signals.creating()) {\n const currentRow = signals.newRow();\n if (currentRow) {\n signals.newRow.set({ ...currentRow, ...partialValues });\n }\n } else {\n const currentEditRow = signals.editRow();\n if (currentEditRow) {\n signals.editRow.set({ ...currentEditRow, ...partialValues });\n }\n }\n }\n}\n"]}
@@ -141,10 +141,10 @@ export class TableDataConverterService {
141
141
  }
142
142
  return false;
143
143
  }
144
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TableDataConverterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
145
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TableDataConverterService, providedIn: 'root' });
144
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableDataConverterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
145
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableDataConverterService, providedIn: 'root' });
146
146
  }
147
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TableDataConverterService, decorators: [{
147
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableDataConverterService, decorators: [{
148
148
  type: Injectable,
149
149
  args: [{
150
150
  providedIn: 'root'
@@ -195,10 +195,10 @@ export class TableDataUtilsService {
195
195
  const maxHeight = Math.round(baseHeight * size);
196
196
  return `${maxHeight}px`;
197
197
  }
198
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TableDataUtilsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
199
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TableDataUtilsService, providedIn: 'root' });
198
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableDataUtilsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
199
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableDataUtilsService, providedIn: 'root' });
200
200
  }
201
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TableDataUtilsService, decorators: [{
201
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableDataUtilsService, decorators: [{
202
202
  type: Injectable,
203
203
  args: [{
204
204
  providedIn: 'root'
@@ -1,4 +1,5 @@
1
- import { Injectable } from '@angular/core';
1
+ import { Injectable, inject } from '@angular/core';
2
+ import { TableDataConverterService } from './table-data-converter.service';
2
3
  import * as i0 from "@angular/core";
3
4
  /**
4
5
  * Servicio para mapear automáticamente datos de tabla a DTOs
@@ -7,9 +8,15 @@ import * as i0 from "@angular/core";
7
8
  * Reglas de exclusión:
8
9
  * - readOnly: true → campo NO se incluye
9
10
  * - accessor: 'id' → campo NO se incluye (IDs van en URL, no en body)
11
+ * - undefined / null → campo NO se incluye (no hubo cambio)
12
+ * - '' (cadena vacía) → se envía null para LIMPIAR el campo
10
13
  * - readOnly: false o undefined → campo se incluye
14
+ *
15
+ * La conversión de tipos delega en TableDataConverterService (que acepta
16
+ * strings, tal como llegan desde los inputs HTML).
11
17
  */
12
18
  export class TableDtoMapperService {
19
+ converter = inject(TableDataConverterService);
13
20
  /**
14
21
  * Mapea un objeto de fila a DTO, excluyendo campos readOnly e id
15
22
  * @param row - Datos de la fila
@@ -23,10 +30,16 @@ export class TableDtoMapperService {
23
30
  const editableColumns = columns.filter(col => !col.readOnly && col.accessor !== 'id');
24
31
  for (const col of editableColumns) {
25
32
  const value = row[col.accessor];
26
- // Solo incluir si el valor existe
27
- if (value !== undefined && value !== null && value !== '') {
28
- dto[col.accessor] = this.convertValue(value, col);
33
+ // undefined / null: el campo no cambió, no se incluye
34
+ if (value === undefined || value === null) {
35
+ continue;
36
+ }
37
+ // Cadena vacía: se interpreta como "limpiar el campo" → null explícito
38
+ if (value === '') {
39
+ dto[col.accessor] = null;
40
+ continue;
29
41
  }
42
+ dto[col.accessor] = this.convertValue(value, col);
30
43
  }
31
44
  // Agregar campos adicionales (ej: boxId, profileId)
32
45
  if (additionalFields) {
@@ -35,7 +48,8 @@ export class TableDtoMapperService {
35
48
  return dto;
36
49
  }
37
50
  /**
38
- * Convierte un valor según el tipo de columna
51
+ * Convierte un valor según el tipo de columna, reutilizando
52
+ * TableDataConverterService (acepta strings provenientes de inputs HTML).
39
53
  * @param value - Valor a convertir
40
54
  * @param col - Definición de columna
41
55
  * @returns Valor convertido
@@ -43,53 +57,36 @@ export class TableDtoMapperService {
43
57
  convertValue(value, col) {
44
58
  switch (col.type) {
45
59
  case 'integer':
46
- return this.toInteger(value, col);
60
+ return this.applyBounds(this.converter.toInteger(value), col);
47
61
  case 'number':
48
- return this.toNumber(value);
62
+ return this.converter.toNumber(value);
49
63
  case 'boolean':
50
- return this.toBoolean(value);
64
+ return this.converter.toBoolean(value);
51
65
  case 'string':
52
66
  case 'password':
53
67
  case 'enum':
54
- return this.toString(value);
68
+ return this.converter.toStringValue(value);
55
69
  default:
56
70
  return value;
57
71
  }
58
72
  }
59
- toInteger(value, col) {
60
- if (typeof value !== 'number')
73
+ /**
74
+ * Aplica los límites min/max declarados en la columna a un valor numérico.
75
+ */
76
+ applyBounds(value, col) {
77
+ if (value === undefined)
61
78
  return undefined;
62
- let result = Math.floor(value);
63
- // Aplicar min/max si existen
79
+ let result = value;
64
80
  if (col.min !== undefined)
65
81
  result = Math.max(result, col.min);
66
82
  if (col.max !== undefined)
67
83
  result = Math.min(result, col.max);
68
84
  return result;
69
85
  }
70
- toNumber(value) {
71
- if (typeof value === 'number')
72
- return value;
73
- if (typeof value === 'string') {
74
- const num = Number(value);
75
- return Number.isNaN(num) ? undefined : num;
76
- }
77
- return undefined;
78
- }
79
- toBoolean(value) {
80
- if (typeof value === 'boolean')
81
- return value;
82
- if (typeof value === 'string')
83
- return value.toLowerCase() === 'true';
84
- return Boolean(value);
85
- }
86
- toString(value) {
87
- return String(value);
88
- }
89
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TableDtoMapperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
90
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TableDtoMapperService, providedIn: 'root' });
86
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableDtoMapperService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
87
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableDtoMapperService, providedIn: 'root' });
91
88
  }
92
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TableDtoMapperService, decorators: [{
89
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableDtoMapperService, decorators: [{
93
90
  type: Injectable,
94
91
  args: [{
95
92
  providedIn: 'root'
@@ -1 +1 @@
1
- {"version":3,"file":"table-dto-mapper.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-dto-mapper.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport type { TableColDef } from './table.types';\n\n/**\n * Servicio para mapear automáticamente datos de tabla a DTOs\n * basándose en la configuración de TableColDef.\n * \n * Reglas de exclusión:\n * - readOnly: true → campo NO se incluye\n * - accessor: 'id' → campo NO se incluye (IDs van en URL, no en body)\n * - readOnly: false o undefined → campo se incluye\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableDtoMapperService {\n\n /**\n * Mapea un objeto de fila a DTO, excluyendo campos readOnly e id\n * @param row - Datos de la fila\n * @param columns - Definiciones de columnas\n * @param additionalFields - Campos adicionales a agregar al DTO (ej: boxId)\n * @returns DTO con solo campos editables (sin id)\n */\n mapToDto(\n row: Record<string, unknown>,\n columns: TableColDef[],\n additionalFields?: Record<string, unknown>\n ): Record<string, unknown> {\n const dto: Record<string, unknown> = {};\n\n // Mapear solo columnas NO readOnly y NO id\n const editableColumns = columns.filter(col =>\n !col.readOnly && col.accessor !== 'id'\n );\n\n for (const col of editableColumns) {\n const value = row[col.accessor];\n\n // Solo incluir si el valor existe\n if (value !== undefined && value !== null && value !== '') {\n dto[col.accessor] = this.convertValue(value, col);\n }\n }\n\n // Agregar campos adicionales (ej: boxId, profileId)\n if (additionalFields) {\n Object.assign(dto, additionalFields);\n }\n\n return dto;\n }\n\n /**\n * Convierte un valor según el tipo de columna\n * @param value - Valor a convertir\n * @param col - Definición de columna\n * @returns Valor convertido\n */\n private convertValue(value: unknown, col: TableColDef): unknown {\n switch (col.type) {\n case 'integer':\n return this.toInteger(value, col);\n case 'number':\n return this.toNumber(value);\n case 'boolean':\n return this.toBoolean(value);\n case 'string':\n case 'password':\n case 'enum':\n return this.toString(value);\n default:\n return value;\n }\n }\n\n private toInteger(value: unknown, col: TableColDef): number | undefined {\n if (typeof value !== 'number') return undefined;\n\n let result = Math.floor(value);\n\n // Aplicar min/max si existen\n if (col.min !== undefined) result = Math.max(result, col.min);\n if (col.max !== undefined) result = Math.min(result, col.max);\n\n return result;\n }\n\n private toNumber(value: unknown): number | undefined {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const num = Number(value);\n return Number.isNaN(num) ? undefined : num;\n }\n return undefined;\n }\n\n private toBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') return value.toLowerCase() === 'true';\n return Boolean(value);\n }\n\n private toString(value: unknown): string {\n return String(value);\n }\n}\n"]}
1
+ {"version":3,"file":"table-dto-mapper.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-dto-mapper.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEnD,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;;AAE3E;;;;;;;;;;;;;GAaG;AAIH,MAAM,OAAO,qBAAqB;IAEb,SAAS,GAAG,MAAM,CAAC,yBAAyB,CAAC,CAAC;IAE/D;;;;;;OAMG;IACH,QAAQ,CACJ,GAA4B,EAC5B,OAAsB,EACtB,gBAA0C;QAE1C,MAAM,GAAG,GAA4B,EAAE,CAAC;QAExC,2CAA2C;QAC3C,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACzC,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,CACzC,CAAC;QAEF,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAEhC,sDAAsD;YACtD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACxC,SAAS;YACb,CAAC;YAED,uEAAuE;YACvE,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;gBACf,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;gBACzB,SAAS;YACb,CAAC;YAED,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACtD,CAAC;QAED,oDAAoD;QACpD,IAAI,gBAAgB,EAAE,CAAC;YACnB,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,GAAG,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACK,YAAY,CAAC,KAAc,EAAE,GAAgB;QACjD,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,SAAS;gBACV,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC;YAClE,KAAK,QAAQ;gBACT,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC1C,KAAK,SAAS;gBACV,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC3C,KAAK,QAAQ,CAAC;YACd,KAAK,UAAU,CAAC;YAChB,KAAK,MAAM;gBACP,OAAO,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC/C;gBACI,OAAO,KAAK,CAAC;QACrB,CAAC;IACL,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,KAAyB,EAAE,GAAgB;QAC3D,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAE1C,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,GAAG,CAAC,GAAG,KAAK,SAAS;YAAE,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9D,IAAI,GAAG,CAAC,GAAG,KAAK,SAAS;YAAE,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAE9D,OAAO,MAAM,CAAC;IAClB,CAAC;wGAnFQ,qBAAqB;4GAArB,qBAAqB,cAFlB,MAAM;;4FAET,qBAAqB;kBAHjC,UAAU;mBAAC;oBACR,UAAU,EAAE,MAAM;iBACrB","sourcesContent":["import { Injectable, inject } from '@angular/core';\nimport type { TableColDef } from './table.types';\nimport { TableDataConverterService } from './table-data-converter.service';\n\n/**\n * Servicio para mapear automáticamente datos de tabla a DTOs\n * basándose en la configuración de TableColDef.\n *\n * Reglas de exclusión:\n * - readOnly: true → campo NO se incluye\n * - accessor: 'id' → campo NO se incluye (IDs van en URL, no en body)\n * - undefined / null → campo NO se incluye (no hubo cambio)\n * - '' (cadena vacía) → se envía null para LIMPIAR el campo\n * - readOnly: false o undefined → campo se incluye\n *\n * La conversión de tipos delega en TableDataConverterService (que acepta\n * strings, tal como llegan desde los inputs HTML).\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableDtoMapperService {\n\n private readonly converter = inject(TableDataConverterService);\n\n /**\n * Mapea un objeto de fila a DTO, excluyendo campos readOnly e id\n * @param row - Datos de la fila\n * @param columns - Definiciones de columnas\n * @param additionalFields - Campos adicionales a agregar al DTO (ej: boxId)\n * @returns DTO con solo campos editables (sin id)\n */\n mapToDto(\n row: Record<string, unknown>,\n columns: TableColDef[],\n additionalFields?: Record<string, unknown>\n ): Record<string, unknown> {\n const dto: Record<string, unknown> = {};\n\n // Mapear solo columnas NO readOnly y NO id\n const editableColumns = columns.filter(col =>\n !col.readOnly && col.accessor !== 'id'\n );\n\n for (const col of editableColumns) {\n const value = row[col.accessor];\n\n // undefined / null: el campo no cambió, no se incluye\n if (value === undefined || value === null) {\n continue;\n }\n\n // Cadena vacía: se interpreta como \"limpiar el campo\" → null explícito\n if (value === '') {\n dto[col.accessor] = null;\n continue;\n }\n\n dto[col.accessor] = this.convertValue(value, col);\n }\n\n // Agregar campos adicionales (ej: boxId, profileId)\n if (additionalFields) {\n Object.assign(dto, additionalFields);\n }\n\n return dto;\n }\n\n /**\n * Convierte un valor según el tipo de columna, reutilizando\n * TableDataConverterService (acepta strings provenientes de inputs HTML).\n * @param value - Valor a convertir\n * @param col - Definición de columna\n * @returns Valor convertido\n */\n private convertValue(value: unknown, col: TableColDef): unknown {\n switch (col.type) {\n case 'integer':\n return this.applyBounds(this.converter.toInteger(value), col);\n case 'number':\n return this.converter.toNumber(value);\n case 'boolean':\n return this.converter.toBoolean(value);\n case 'string':\n case 'password':\n case 'enum':\n return this.converter.toStringValue(value);\n default:\n return value;\n }\n }\n\n /**\n * Aplica los límites min/max declarados en la columna a un valor numérico.\n */\n private applyBounds(value: number | undefined, col: TableColDef): number | undefined {\n if (value === undefined) return undefined;\n\n let result = value;\n if (col.min !== undefined) result = Math.max(result, col.min);\n if (col.max !== undefined) result = Math.min(result, col.max);\n\n return result;\n }\n}\n"]}
@@ -16,17 +16,17 @@ export class TablePaginationService {
16
16
  * @returns Objeto con signals y métodos de paginación
17
17
  */
18
18
  createPaginationState(initialPageSize = 10) {
19
- const currentPage = signal(1, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
20
- const pageSize = signal(initialPageSize, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
21
- const totalItems = signal(0, ...(ngDevMode ? [{ debugName: "totalItems" }] : []));
19
+ const currentPage = signal(1, ...(ngDevMode ? [{ debugName: "currentPage" }] : /* istanbul ignore next */ []));
20
+ const pageSize = signal(initialPageSize, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
21
+ const totalItems = signal(0, ...(ngDevMode ? [{ debugName: "totalItems" }] : /* istanbul ignore next */ []));
22
22
  const totalPages = computed(() => {
23
23
  const total = totalItems();
24
24
  const size = pageSize();
25
25
  return Math.ceil(total / size) || 1;
26
- }, ...(ngDevMode ? [{ debugName: "totalPages" }] : []));
27
- const hasNextPage = computed(() => currentPage() < totalPages(), ...(ngDevMode ? [{ debugName: "hasNextPage" }] : []));
28
- const hasPrevPage = computed(() => currentPage() > 1, ...(ngDevMode ? [{ debugName: "hasPrevPage" }] : []));
29
- const offset = computed(() => (currentPage() - 1) * pageSize(), ...(ngDevMode ? [{ debugName: "offset" }] : []));
26
+ }, ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
27
+ const hasNextPage = computed(() => currentPage() < totalPages(), ...(ngDevMode ? [{ debugName: "hasNextPage" }] : /* istanbul ignore next */ []));
28
+ const hasPrevPage = computed(() => currentPage() > 1, ...(ngDevMode ? [{ debugName: "hasPrevPage" }] : /* istanbul ignore next */ []));
29
+ const offset = computed(() => (currentPage() - 1) * pageSize(), ...(ngDevMode ? [{ debugName: "offset" }] : /* istanbul ignore next */ []));
30
30
  return {
31
31
  currentPage,
32
32
  pageSize,
@@ -67,10 +67,10 @@ export class TablePaginationService {
67
67
  currentPageSignal.set(1);
68
68
  totalItemsSignal.set(0);
69
69
  }
70
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TablePaginationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
71
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TablePaginationService, providedIn: 'root' });
70
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TablePaginationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
71
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TablePaginationService, providedIn: 'root' });
72
72
  }
73
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TablePaginationService, decorators: [{
73
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TablePaginationService, decorators: [{
74
74
  type: Injectable,
75
75
  args: [{
76
76
  providedIn: 'root'
@@ -1 +1 @@
1
- {"version":3,"file":"table-pagination.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-pagination.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, signal, computed, type Signal } from '@angular/core';\n\nexport interface TablePaginationState {\n currentPage: Signal<number>;\n pageSize: Signal<number>;\n totalItems: Signal<number>;\n totalPages: Signal<number>;\n hasNextPage: Signal<boolean>;\n hasPrevPage: Signal<boolean>;\n offset: Signal<number>;\n setPage: (page: number) => void;\n setPageSize: (size: number) => void;\n setTotalItems: (total: number) => void;\n nextPage: () => void;\n prevPage: () => void;\n reset: () => void;\n}\n\n/**\n * Servicio para gestionar el estado de paginación en tablas C80\n *\n * Maneja:\n * - Estado de paginación (página actual, tamaño, total)\n * - Cálculo automático de offset para API (limit/offset)\n * - Navegación (siguiente, anterior)\n * - Validaciones de límites\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TablePaginationService {\n\n /**\n * Inicializa el estado de paginación para una nueva tabla\n * @param initialPageSize - Tamaño de página inicial (default: 10)\n * @returns Objeto con signals y métodos de paginación\n */\n createPaginationState(initialPageSize = 10): TablePaginationState {\n const currentPage = signal(1);\n const pageSize = signal(initialPageSize);\n const totalItems = signal(0);\n\n const totalPages = computed(() => {\n const total = totalItems();\n const size = pageSize();\n return Math.ceil(total / size) || 1;\n });\n\n const hasNextPage = computed(() => currentPage() < totalPages());\n const hasPrevPage = computed(() => currentPage() > 1);\n const offset = computed(() => (currentPage() - 1) * pageSize());\n\n return {\n currentPage,\n pageSize,\n totalItems,\n totalPages,\n hasNextPage,\n hasPrevPage,\n offset,\n setPage: (page: number) => this.setPage(currentPage, page, totalPages),\n setPageSize: (size: number) => this.setPageSize(pageSize, currentPage, size),\n setTotalItems: (total: number) => totalItems.set(total),\n nextPage: () => this.nextPage(currentPage, totalPages),\n prevPage: () => this.prevPage(currentPage),\n reset: () => this.reset(currentPage, totalItems)\n };\n }\n\n private setPage(\n currentPageSignal: ReturnType<typeof signal<number>>,\n page: number,\n totalPages: Signal<number>\n ): void {\n const validPage = Math.max(1, Math.min(page, totalPages()));\n currentPageSignal.set(validPage);\n }\n\n private setPageSize(\n pageSizeSignal: ReturnType<typeof signal<number>>,\n currentPageSignal: ReturnType<typeof signal<number>>,\n size: number\n ): void {\n pageSizeSignal.set(Math.max(1, size));\n currentPageSignal.set(1);\n }\n\n private nextPage(\n currentPageSignal: ReturnType<typeof signal<number>>,\n totalPages: Signal<number>\n ): void {\n const current = currentPageSignal();\n if (current < totalPages()) {\n currentPageSignal.set(current + 1);\n }\n }\n\n private prevPage(\n currentPageSignal: ReturnType<typeof signal<number>>\n ): void {\n const current = currentPageSignal();\n if (current > 1) {\n currentPageSignal.set(current - 1);\n }\n }\n\n private reset(\n currentPageSignal: ReturnType<typeof signal<number>>,\n totalItemsSignal: ReturnType<typeof signal<number>>\n ): void {\n currentPageSignal.set(1);\n totalItemsSignal.set(0);\n }\n}\n"]}
1
+ {"version":3,"file":"table-pagination.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-pagination.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, signal, computed, type Signal } from '@angular/core';\n\nexport interface TablePaginationState {\n currentPage: Signal<number>;\n pageSize: Signal<number>;\n totalItems: Signal<number>;\n totalPages: Signal<number>;\n hasNextPage: Signal<boolean>;\n hasPrevPage: Signal<boolean>;\n offset: Signal<number>;\n setPage: (page: number) => void;\n setPageSize: (size: number) => void;\n setTotalItems: (total: number) => void;\n nextPage: () => void;\n prevPage: () => void;\n reset: () => void;\n}\n\n/**\n * Servicio para gestionar el estado de paginación en tablas C80\n *\n * Maneja:\n * - Estado de paginación (página actual, tamaño, total)\n * - Cálculo automático de offset para API (limit/offset)\n * - Navegación (siguiente, anterior)\n * - Validaciones de límites\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TablePaginationService {\n\n /**\n * Inicializa el estado de paginación para una nueva tabla\n * @param initialPageSize - Tamaño de página inicial (default: 10)\n * @returns Objeto con signals y métodos de paginación\n */\n createPaginationState(initialPageSize = 10): TablePaginationState {\n const currentPage = signal(1);\n const pageSize = signal(initialPageSize);\n const totalItems = signal(0);\n\n const totalPages = computed(() => {\n const total = totalItems();\n const size = pageSize();\n return Math.ceil(total / size) || 1;\n });\n\n const hasNextPage = computed(() => currentPage() < totalPages());\n const hasPrevPage = computed(() => currentPage() > 1);\n const offset = computed(() => (currentPage() - 1) * pageSize());\n\n return {\n currentPage,\n pageSize,\n totalItems,\n totalPages,\n hasNextPage,\n hasPrevPage,\n offset,\n setPage: (page: number) => this.setPage(currentPage, page, totalPages),\n setPageSize: (size: number) => this.setPageSize(pageSize, currentPage, size),\n setTotalItems: (total: number) => totalItems.set(total),\n nextPage: () => this.nextPage(currentPage, totalPages),\n prevPage: () => this.prevPage(currentPage),\n reset: () => this.reset(currentPage, totalItems)\n };\n }\n\n private setPage(\n currentPageSignal: ReturnType<typeof signal<number>>,\n page: number,\n totalPages: Signal<number>\n ): void {\n const validPage = Math.max(1, Math.min(page, totalPages()));\n currentPageSignal.set(validPage);\n }\n\n private setPageSize(\n pageSizeSignal: ReturnType<typeof signal<number>>,\n currentPageSignal: ReturnType<typeof signal<number>>,\n size: number\n ): void {\n pageSizeSignal.set(Math.max(1, size));\n currentPageSignal.set(1);\n }\n\n private nextPage(\n currentPageSignal: ReturnType<typeof signal<number>>,\n totalPages: Signal<number>\n ): void {\n const current = currentPageSignal();\n if (current < totalPages()) {\n currentPageSignal.set(current + 1);\n }\n }\n\n private prevPage(\n currentPageSignal: ReturnType<typeof signal<number>>\n ): void {\n const current = currentPageSignal();\n if (current > 1) {\n currentPageSignal.set(current - 1);\n }\n }\n\n private reset(\n currentPageSignal: ReturnType<typeof signal<number>>,\n totalItemsSignal: ReturnType<typeof signal<number>>\n ): void {\n currentPageSignal.set(1);\n totalItemsSignal.set(0);\n }\n}\n"]}
@@ -14,21 +14,21 @@ export class TableSelectionService {
14
14
  * Inicializa el estado de selección para una nueva tabla
15
15
  * @returns Objeto con signals y métodos de selección
16
16
  */
17
- createSelectionState() {
18
- const selectedItems = signal(new Set(), ...(ngDevMode ? [{ debugName: "selectedItems" }] : []));
19
- const selectAllChecked = signal(false, ...(ngDevMode ? [{ debugName: "selectAllChecked" }] : []));
20
- const selectAllIndeterminate = signal(false, ...(ngDevMode ? [{ debugName: "selectAllIndeterminate" }] : []));
17
+ createSelectionState(getRowId = (item) => item['id']) {
18
+ const selectedItems = signal(new Set(), ...(ngDevMode ? [{ debugName: "selectedItems" }] : /* istanbul ignore next */ []));
19
+ const selectAllChecked = signal(false, ...(ngDevMode ? [{ debugName: "selectAllChecked" }] : /* istanbul ignore next */ []));
20
+ const selectAllIndeterminate = signal(false, ...(ngDevMode ? [{ debugName: "selectAllIndeterminate" }] : /* istanbul ignore next */ []));
21
21
  const signals = { selectedItems, selectAllChecked, selectAllIndeterminate };
22
22
  return {
23
23
  selectedItems: selectedItems.asReadonly(),
24
24
  selectAllChecked: selectAllChecked.asReadonly(),
25
25
  selectAllIndeterminate: selectAllIndeterminate.asReadonly(),
26
26
  clearSelection: () => this.clearSelection(signals),
27
- toggleSelectAll: (allItems) => this.toggleSelectAll(signals, allItems),
28
- toggleItemSelection: (item, multiple) => this.toggleItemSelection(selectedItems, item, multiple),
29
- isItemSelected: (item) => this.isItemSelected(selectedItems, item),
30
- preserveSelection: (newData) => this.preserveSelection(signals, newData),
31
- getSelectedItems: (allData) => this.getSelectedItems(selectedItems, allData),
27
+ toggleSelectAll: (allItems) => this.toggleSelectAll(signals, allItems, getRowId),
28
+ toggleItemSelection: (item, multiple) => this.toggleItemSelection(selectedItems, item, multiple, getRowId),
29
+ isItemSelected: (item) => this.isItemSelected(selectedItems, item, getRowId),
30
+ preserveSelection: (newData) => this.preserveSelection(signals, newData, getRowId),
31
+ getSelectedItems: (allData) => this.getSelectedItems(selectedItems, allData, getRowId),
32
32
  };
33
33
  }
34
34
  clearSelection(signals) {
@@ -36,7 +36,7 @@ export class TableSelectionService {
36
36
  signals.selectAllChecked.set(false);
37
37
  signals.selectAllIndeterminate.set(false);
38
38
  }
39
- toggleSelectAll(signals, allItems) {
39
+ toggleSelectAll(signals, allItems, getRowId) {
40
40
  const currentSelection = signals.selectedItems();
41
41
  if (currentSelection.size === allItems.length) {
42
42
  signals.selectedItems.set(new Set());
@@ -44,7 +44,7 @@ export class TableSelectionService {
44
44
  signals.selectAllIndeterminate.set(false);
45
45
  }
46
46
  else {
47
- const allIds = new Set(allItems.map(item => item['id']));
47
+ const allIds = new Set(allItems.map(getRowId));
48
48
  signals.selectedItems.set(allIds);
49
49
  this.updateSelectAllState({
50
50
  allItems,
@@ -54,8 +54,8 @@ export class TableSelectionService {
54
54
  });
55
55
  }
56
56
  }
57
- toggleItemSelection(selectedItems, item, multiple) {
58
- const id = item['id'];
57
+ toggleItemSelection(selectedItems, item, multiple, getRowId) {
58
+ const id = getRowId(item);
59
59
  const currentSelection = new Set(selectedItems());
60
60
  if (!multiple) {
61
61
  currentSelection.clear();
@@ -71,16 +71,16 @@ export class TableSelectionService {
71
71
  }
72
72
  selectedItems.set(currentSelection);
73
73
  }
74
- isItemSelected(selectedItems, item) {
75
- return selectedItems().has(item['id']);
74
+ isItemSelected(selectedItems, item, getRowId) {
75
+ return selectedItems().has(getRowId(item));
76
76
  }
77
- preserveSelection(signals, newData) {
77
+ preserveSelection(signals, newData, getRowId) {
78
78
  const currentSelection = signals.selectedItems();
79
79
  if (currentSelection.size === 0 || newData.length === 0) {
80
80
  this.clearSelection(signals);
81
81
  return;
82
82
  }
83
- const availableIds = new Set(newData.map(item => item['id']));
83
+ const availableIds = new Set(newData.map(getRowId));
84
84
  const preservedSelection = new Set(Array.from(currentSelection).filter(id => availableIds.has(id)));
85
85
  signals.selectedItems.set(preservedSelection);
86
86
  this.updateSelectAllState({
@@ -90,9 +90,9 @@ export class TableSelectionService {
90
90
  selectAllIndeterminate: signals.selectAllIndeterminate
91
91
  });
92
92
  }
93
- getSelectedItems(selectedItems, allData) {
93
+ getSelectedItems(selectedItems, allData, getRowId) {
94
94
  const selectedIds = selectedItems();
95
- return allData.filter(item => selectedIds.has(item['id']));
95
+ return allData.filter(item => selectedIds.has(getRowId(item)));
96
96
  }
97
97
  updateSelectAllState(context) {
98
98
  const { allItems, selectedCount, selectAllChecked, selectAllIndeterminate } = context;
@@ -120,10 +120,10 @@ export class TableSelectionService {
120
120
  const selectedItems = selectionState.getSelectedItems(allData);
121
121
  selectableEmitter.emit(selectedItems);
122
122
  }
123
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TableSelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
124
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TableSelectionService, providedIn: 'root' });
123
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableSelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
124
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableSelectionService, providedIn: 'root' });
125
125
  }
126
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.10", ngImport: i0, type: TableSelectionService, decorators: [{
126
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableSelectionService, decorators: [{
127
127
  type: Injectable,
128
128
  args: [{
129
129
  providedIn: 'root'
@@ -1 +1 @@
1
- {"version":3,"file":"table-selection.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-selection.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { type OutputEmitterRef, Injectable, signal, type Signal } from '@angular/core';\n\ninterface SelectionState<T extends Record<string, unknown>> {\n selectedItems: Signal<Set<string>>;\n selectAllChecked: Signal<boolean>;\n selectAllIndeterminate: Signal<boolean>;\n clearSelection: () => void;\n toggleSelectAll: (allItems: T[]) => void;\n toggleItemSelection: (item: T, multiple: boolean) => void;\n isItemSelected: (item: T) => boolean;\n preserveSelection: (newData: T[]) => void;\n getSelectedItems: (allData: T[]) => T[];\n}\n\n/**\n * Servicio para gestionar la selección de elementos en tablas C80\n *\n * Maneja:\n * - Selección simple y múltiple\n * - Estado de selección completa\n * - Preservación de selección tras actualizaciones de datos\n * - Emisión de eventos de selección\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableSelectionService {\n\n /**\n * Inicializa el estado de selección para una nueva tabla\n * @returns Objeto con signals y métodos de selección\n */\n createSelectionState<T extends Record<string, unknown>>(): SelectionState<T> {\n const selectedItems = signal<Set<string>>(new Set());\n const selectAllChecked = signal(false);\n const selectAllIndeterminate = signal(false);\n\n const signals = { selectedItems, selectAllChecked, selectAllIndeterminate };\n\n return {\n selectedItems: selectedItems.asReadonly(),\n selectAllChecked: selectAllChecked.asReadonly(),\n selectAllIndeterminate: selectAllIndeterminate.asReadonly(),\n clearSelection: () => this.clearSelection(signals),\n toggleSelectAll: (allItems: T[]) => this.toggleSelectAll(signals, allItems),\n toggleItemSelection: (item: T, multiple: boolean) => this.toggleItemSelection(selectedItems, item, multiple),\n isItemSelected: (item: T) => this.isItemSelected(selectedItems, item),\n preserveSelection: (newData: T[]) => this.preserveSelection(signals, newData),\n getSelectedItems: (allData: T[]) => this.getSelectedItems(selectedItems, allData),\n };\n }\n\n private clearSelection(signals: {\n selectedItems: ReturnType<typeof signal<Set<string>>>;\n selectAllChecked: ReturnType<typeof signal<boolean>>;\n selectAllIndeterminate: ReturnType<typeof signal<boolean>>;\n }): void {\n signals.selectedItems.set(new Set());\n signals.selectAllChecked.set(false);\n signals.selectAllIndeterminate.set(false);\n }\n\n private toggleSelectAll<T extends Record<string, unknown>>(\n signals: {\n selectedItems: ReturnType<typeof signal<Set<string>>>;\n selectAllChecked: ReturnType<typeof signal<boolean>>;\n selectAllIndeterminate: ReturnType<typeof signal<boolean>>;\n },\n allItems: T[]\n ): void {\n const currentSelection = signals.selectedItems();\n\n if (currentSelection.size === allItems.length) {\n signals.selectedItems.set(new Set());\n signals.selectAllChecked.set(false);\n signals.selectAllIndeterminate.set(false);\n } else {\n const allIds = new Set(allItems.map(item => item['id'] as string));\n signals.selectedItems.set(allIds);\n this.updateSelectAllState({\n allItems,\n selectedCount: allIds.size,\n selectAllChecked: signals.selectAllChecked,\n selectAllIndeterminate: signals.selectAllIndeterminate\n });\n }\n }\n\n private toggleItemSelection<T extends Record<string, unknown>>(\n selectedItems: ReturnType<typeof signal<Set<string>>>,\n item: T,\n multiple: boolean\n ): void {\n const id = item['id'] as string;\n const currentSelection = new Set(selectedItems());\n\n if (!multiple) {\n currentSelection.clear();\n if (!selectedItems().has(id)) {\n currentSelection.add(id);\n }\n } else if (currentSelection.has(id)) {\n currentSelection.delete(id);\n } else {\n currentSelection.add(id);\n }\n\n selectedItems.set(currentSelection);\n }\n\n private isItemSelected<T extends Record<string, unknown>>(\n selectedItems: ReturnType<typeof signal<Set<string>>>,\n item: T\n ): boolean {\n return selectedItems().has(item['id'] as string);\n }\n\n private preserveSelection<T extends Record<string, unknown>>(\n signals: {\n selectedItems: ReturnType<typeof signal<Set<string>>>;\n selectAllChecked: ReturnType<typeof signal<boolean>>;\n selectAllIndeterminate: ReturnType<typeof signal<boolean>>;\n },\n newData: T[]\n ): void {\n const currentSelection = signals.selectedItems();\n\n if (currentSelection.size === 0 || newData.length === 0) {\n this.clearSelection(signals);\n return;\n }\n\n const availableIds = new Set(newData.map(item => item['id'] as string));\n const preservedSelection = new Set(\n Array.from(currentSelection).filter(id => availableIds.has(id))\n );\n\n signals.selectedItems.set(preservedSelection);\n this.updateSelectAllState({\n allItems: newData,\n selectedCount: preservedSelection.size,\n selectAllChecked: signals.selectAllChecked,\n selectAllIndeterminate: signals.selectAllIndeterminate\n });\n }\n\n private getSelectedItems<T extends Record<string, unknown>>(\n selectedItems: ReturnType<typeof signal<Set<string>>>,\n allData: T[]\n ): T[] {\n const selectedIds = selectedItems();\n return allData.filter(item => selectedIds.has(item['id'] as string));\n }\n\n private updateSelectAllState<T extends Record<string, unknown>>(context: {\n allItems: T[];\n selectedCount: number;\n selectAllChecked: ReturnType<typeof signal<boolean>>;\n selectAllIndeterminate: ReturnType<typeof signal<boolean>>;\n }): void {\n const { allItems, selectedCount, selectAllChecked, selectAllIndeterminate } = context;\n const totalCount = allItems.length;\n\n if (selectedCount === 0) {\n selectAllChecked.set(false);\n selectAllIndeterminate.set(false);\n } else if (selectedCount === totalCount) {\n selectAllChecked.set(true);\n selectAllIndeterminate.set(false);\n } else {\n selectAllChecked.set(false);\n selectAllIndeterminate.set(true);\n }\n }\n\n /**\n * Emite los elementos seleccionados a través del output proporcionado\n * @param selectionState - Estado de selección\n * @param allData - Todos los datos de la tabla\n * @param selectableEmitter - Output para emitir la selección\n */\n emitSelection<T extends Record<string, unknown>>(\n selectionState: { getSelectedItems: (allData: T[]) => T[] },\n allData: T[],\n selectableEmitter: OutputEmitterRef<T[]>\n ): void {\n const selectedItems = selectionState.getSelectedItems(allData);\n selectableEmitter.emit(selectedItems);\n }\n}\n"]}
1
+ {"version":3,"file":"table-selection.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-selection.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { type OutputEmitterRef, Injectable, signal, type Signal } from '@angular/core';\n\ninterface SelectionState<T extends Record<string, unknown>> {\n selectedItems: Signal<Set<string>>;\n selectAllChecked: Signal<boolean>;\n selectAllIndeterminate: Signal<boolean>;\n clearSelection: () => void;\n toggleSelectAll: (allItems: T[]) => void;\n toggleItemSelection: (item: T, multiple: boolean) => void;\n isItemSelected: (item: T) => boolean;\n preserveSelection: (newData: T[]) => void;\n getSelectedItems: (allData: T[]) => T[];\n}\n\n/**\n * Servicio para gestionar la selección de elementos en tablas C80\n *\n * Maneja:\n * - Selección simple y múltiple\n * - Estado de selección completa\n * - Preservación de selección tras actualizaciones de datos\n * - Emisión de eventos de selección\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableSelectionService {\n\n /**\n * Inicializa el estado de selección para una nueva tabla\n * @returns Objeto con signals y métodos de selección\n */\n createSelectionState<T extends Record<string, unknown>>(\n getRowId: (item: T) => string = (item) => item['id'] as string\n ): SelectionState<T> {\n const selectedItems = signal<Set<string>>(new Set());\n const selectAllChecked = signal(false);\n const selectAllIndeterminate = signal(false);\n\n const signals = { selectedItems, selectAllChecked, selectAllIndeterminate };\n\n return {\n selectedItems: selectedItems.asReadonly(),\n selectAllChecked: selectAllChecked.asReadonly(),\n selectAllIndeterminate: selectAllIndeterminate.asReadonly(),\n clearSelection: () => this.clearSelection(signals),\n toggleSelectAll: (allItems: T[]) => this.toggleSelectAll(signals, allItems, getRowId),\n toggleItemSelection: (item: T, multiple: boolean) => this.toggleItemSelection(selectedItems, item, multiple, getRowId),\n isItemSelected: (item: T) => this.isItemSelected(selectedItems, item, getRowId),\n preserveSelection: (newData: T[]) => this.preserveSelection(signals, newData, getRowId),\n getSelectedItems: (allData: T[]) => this.getSelectedItems(selectedItems, allData, getRowId),\n };\n }\n\n private clearSelection(signals: {\n selectedItems: ReturnType<typeof signal<Set<string>>>;\n selectAllChecked: ReturnType<typeof signal<boolean>>;\n selectAllIndeterminate: ReturnType<typeof signal<boolean>>;\n }): void {\n signals.selectedItems.set(new Set());\n signals.selectAllChecked.set(false);\n signals.selectAllIndeterminate.set(false);\n }\n\n private toggleSelectAll<T extends Record<string, unknown>>(\n signals: {\n selectedItems: ReturnType<typeof signal<Set<string>>>;\n selectAllChecked: ReturnType<typeof signal<boolean>>;\n selectAllIndeterminate: ReturnType<typeof signal<boolean>>;\n },\n allItems: T[],\n getRowId: (item: T) => string\n ): void {\n const currentSelection = signals.selectedItems();\n\n if (currentSelection.size === allItems.length) {\n signals.selectedItems.set(new Set());\n signals.selectAllChecked.set(false);\n signals.selectAllIndeterminate.set(false);\n } else {\n const allIds = new Set(allItems.map(getRowId));\n signals.selectedItems.set(allIds);\n this.updateSelectAllState({\n allItems,\n selectedCount: allIds.size,\n selectAllChecked: signals.selectAllChecked,\n selectAllIndeterminate: signals.selectAllIndeterminate\n });\n }\n }\n\n private toggleItemSelection<T extends Record<string, unknown>>(\n selectedItems: ReturnType<typeof signal<Set<string>>>,\n item: T,\n multiple: boolean,\n getRowId: (item: T) => string\n ): void {\n const id = getRowId(item);\n const currentSelection = new Set(selectedItems());\n\n if (!multiple) {\n currentSelection.clear();\n if (!selectedItems().has(id)) {\n currentSelection.add(id);\n }\n } else if (currentSelection.has(id)) {\n currentSelection.delete(id);\n } else {\n currentSelection.add(id);\n }\n\n selectedItems.set(currentSelection);\n }\n\n private isItemSelected<T extends Record<string, unknown>>(\n selectedItems: ReturnType<typeof signal<Set<string>>>,\n item: T,\n getRowId: (item: T) => string\n ): boolean {\n return selectedItems().has(getRowId(item));\n }\n\n private preserveSelection<T extends Record<string, unknown>>(\n signals: {\n selectedItems: ReturnType<typeof signal<Set<string>>>;\n selectAllChecked: ReturnType<typeof signal<boolean>>;\n selectAllIndeterminate: ReturnType<typeof signal<boolean>>;\n },\n newData: T[],\n getRowId: (item: T) => string\n ): void {\n const currentSelection = signals.selectedItems();\n\n if (currentSelection.size === 0 || newData.length === 0) {\n this.clearSelection(signals);\n return;\n }\n\n const availableIds = new Set(newData.map(getRowId));\n const preservedSelection = new Set(\n Array.from(currentSelection).filter(id => availableIds.has(id))\n );\n\n signals.selectedItems.set(preservedSelection);\n this.updateSelectAllState({\n allItems: newData,\n selectedCount: preservedSelection.size,\n selectAllChecked: signals.selectAllChecked,\n selectAllIndeterminate: signals.selectAllIndeterminate\n });\n }\n\n private getSelectedItems<T extends Record<string, unknown>>(\n selectedItems: ReturnType<typeof signal<Set<string>>>,\n allData: T[],\n getRowId: (item: T) => string\n ): T[] {\n const selectedIds = selectedItems();\n return allData.filter(item => selectedIds.has(getRowId(item)));\n }\n\n private updateSelectAllState<T extends Record<string, unknown>>(context: {\n allItems: T[];\n selectedCount: number;\n selectAllChecked: ReturnType<typeof signal<boolean>>;\n selectAllIndeterminate: ReturnType<typeof signal<boolean>>;\n }): void {\n const { allItems, selectedCount, selectAllChecked, selectAllIndeterminate } = context;\n const totalCount = allItems.length;\n\n if (selectedCount === 0) {\n selectAllChecked.set(false);\n selectAllIndeterminate.set(false);\n } else if (selectedCount === totalCount) {\n selectAllChecked.set(true);\n selectAllIndeterminate.set(false);\n } else {\n selectAllChecked.set(false);\n selectAllIndeterminate.set(true);\n }\n }\n\n /**\n * Emite los elementos seleccionados a través del output proporcionado\n * @param selectionState - Estado de selección\n * @param allData - Todos los datos de la tabla\n * @param selectableEmitter - Output para emitir la selección\n */\n emitSelection<T extends Record<string, unknown>>(\n selectionState: { getSelectedItems: (allData: T[]) => T[] },\n allData: T[],\n selectableEmitter: OutputEmitterRef<T[]>\n ): void {\n const selectedItems = selectionState.getSelectedItems(allData);\n selectableEmitter.emit(selectedItems);\n }\n}\n"]}