@c80/ui 1.0.50 → 1.0.52
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.
- package/esm2022/index.js +1 -0
- package/esm2022/index.js.map +1 -1
- package/esm2022/lib/card-level/card-level.component.js +12 -14
- package/esm2022/lib/card-level/card-level.component.js.map +1 -1
- package/esm2022/lib/icon/icon.component.js +4 -4
- package/esm2022/lib/icon/icon.component.js.map +1 -1
- package/esm2022/lib/icon/icon.constants.js +84 -13
- package/esm2022/lib/icon/icon.constants.js.map +1 -1
- package/esm2022/lib/icon/icon.types.js.map +1 -1
- package/esm2022/lib/modal/modal.component.js +7 -7
- package/esm2022/lib/modal/modal.component.js.map +1 -1
- package/esm2022/lib/modal/modal.service.js +2 -2
- package/esm2022/lib/modal/modal.service.js.map +1 -1
- package/esm2022/lib/select/select.component.js +2 -3
- package/esm2022/lib/select/select.component.js.map +1 -1
- package/esm2022/lib/snackbar/snackbar.component.js +8 -3
- package/esm2022/lib/snackbar/snackbar.component.js.map +1 -1
- package/esm2022/lib/snackbar/snackbar.service.js +2 -3
- package/esm2022/lib/snackbar/snackbar.service.js.map +1 -1
- package/esm2022/lib/stat-card/stat-card.component.js +3 -3
- package/esm2022/lib/stat-card/stat-card.component.js.map +1 -1
- package/esm2022/lib/tab/c80-tab-item.directive.js +16 -0
- package/esm2022/lib/tab/c80-tab-item.directive.js.map +1 -0
- package/esm2022/lib/tab/c80-tab-label.directive.js +16 -0
- package/esm2022/lib/tab/c80-tab-label.directive.js.map +1 -0
- package/esm2022/lib/tab/c80-tab.component.js +32 -0
- package/esm2022/lib/tab/c80-tab.component.js.map +1 -0
- package/esm2022/lib/tab/c80-tab.model.js +2 -0
- package/esm2022/lib/tab/c80-tab.model.js.map +1 -0
- package/esm2022/lib/tab/index.js +4 -0
- package/esm2022/lib/tab/index.js.map +1 -0
- package/esm2022/lib/table/table-column-visibility.service.js.map +1 -1
- package/esm2022/lib/table/table-crud-state.service.js.map +1 -1
- package/esm2022/lib/table/table-data-converter.service.js.map +1 -1
- package/esm2022/lib/table/table-data-utils.service.js.map +1 -1
- package/esm2022/lib/table/table-selection.service.js.map +1 -1
- package/esm2022/lib/table/table.component.js +20 -4
- package/esm2022/lib/table/table.component.js.map +1 -1
- package/esm2022/lib/table/table.utils.js +2 -2
- package/esm2022/lib/table/table.utils.js.map +1 -1
- package/index.d.ts +1 -0
- package/lib/card-level/card-level.component.d.ts +4 -5
- package/lib/icon/icon.component.d.ts +1 -1
- package/lib/icon/icon.constants.d.ts +12 -2
- package/lib/icon/icon.types.d.ts +2 -2
- package/lib/modal/modal.service.d.ts +1 -1
- package/lib/select/select.component.d.ts +2 -2
- package/lib/snackbar/snackbar.component.d.ts +1 -0
- package/lib/stat-card/stat-card.component.d.ts +1 -1
- package/lib/tab/c80-tab-item.directive.d.ts +7 -0
- package/lib/tab/c80-tab-label.directive.d.ts +7 -0
- package/lib/tab/c80-tab.component.d.ts +15 -0
- package/lib/tab/c80-tab.model.d.ts +4 -0
- package/lib/tab/index.d.ts +4 -0
- package/lib/table/table-column-visibility.service.d.ts +1 -1
- package/lib/table/table-crud-state.service.d.ts +1 -1
- package/lib/table/table-data-converter.service.d.ts +1 -1
- package/lib/table/table-data-utils.service.d.ts +1 -1
- package/lib/table/table-selection.service.d.ts +1 -1
- package/lib/table/table.component.d.ts +8 -3
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/tab/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC","sourcesContent":["export { C80TabComponent } from './c80-tab.component';\nexport { C80TabItemDirective } from './c80-tab-item.directive';\nexport { C80TabLabelDirective } from './c80-tab-label.directive';\nexport type { C80Tab } from './c80-tab.model';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-column-visibility.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-column-visibility.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, inject } from '@angular/core';\nimport { C80TableColDef } from './table.types';\nimport { TableDataConverterService } from './table-data-converter.service';\nimport { TableDataUtilsService } from './table-data-utils.service';\n\n/**\n * Servicio para gestionar la lógica de visibilidad de columnas en tablas C80\n *\n * Maneja las reglas complejas de visibilidad basadas en:\n * - Configuración explícita (visible: false)\n * - Ocultación automática (hideIfAllValuesAreNull)\n * - Estado de creación y edición\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableColumnVisibilityService {\n\n private readonly dataConverter = inject(TableDataConverterService);\n private readonly dataUtils = inject(TableDataUtilsService);\n\n /**\n * Actualiza las keys de columnas visibles basándose en el estado actual\n * @param columns - Definiciones de columnas\n * @param data - Datos actuales de la tabla\n * @param creating - Si está en modo creación\n * @param editing - ID de fila en edición (null si no hay edición)\n * @returns Array de accessors de columnas visibles\n */\n updateVisibleKeys<T extends Record<string, unknown>>(\n columns: C80TableColDef[],\n data: T[],\n creating: boolean,\n editing: string | null\n ): string[] {\n const visibleColumns = columns.filter(col =>\n this.isColumnVisibleInHeader(col, data, creating, editing)\n );\n return visibleColumns.map(col => col.accessor);\n }\n\n /**\n * Determina si una columna debe ser visible basándose en su configuración y datos\n * Método unificado que maneja todos los casos de visibilidad\n * @param column - La definición de la columna\n * @param data - Datos actuales de la tabla\n * @param options - Opciones de contexto (creación, edición, fila específica)\n * @returns true si la columna debe ser visible\n */\n isColumnVisible<T extends Record<string, unknown>>(\n column: C80TableColDef,\n data: T[],\n options: {\n forceShowInCreation?: boolean;\n creating?: boolean;\n editing?: string | null;\n row?: T;\n } = {}\n ): boolean {\n // PRIORIDAD 1: Si visible está explícitamente establecido en false, SIEMPRE ocultar\n if (column.visible === false) {\n return false;\n }\n\n // Si no tiene hideIfAllValuesAreNull, mostrar siempre\n if (!column.hideIfAllValuesAreNull) {\n return true;\n }\n\n // PRIORIDAD 2: Para columnas con hideIfAllValuesAreNull, ocultar si el valor es falsy (excepto 0)\n // Esto aplica tanto en modo creación como edición\n\n // CONTEXTO: Modo creación\n if (options.creating) {\n // En creación, verificar el valor de la fila en creación si existe\n const creatingRow = options.row;\n if (creatingRow) {\n const cellValue = this.dataUtils.getCellValue(creatingRow, column.accessor);\n return !this.dataConverter.isValueEmpty(cellValue);\n }\n // Si no hay fila, ocultar (valor vacío por defecto)\n return false;\n }\n\n // CONTEXTO: Fila en edición\n if (options.editing !== undefined && options.editing !== null) {\n const editingRow = options.row ?? data.find(r => r['id'] === options.editing);\n if (editingRow) {\n const cellValue = this.dataUtils.getCellValue(editingRow, column.accessor);\n return !this.dataConverter.isValueEmpty(cellValue);\n }\n return false;\n }\n\n // CONTEXTO: Vista normal - verificar si todos los valores están vacíos\n return !this.areAllColumnValuesEmpty(column, data);\n }\n\n /**\n * Determina si una columna debe ser visible en los headers\n * Wrapper para mantener compatibilidad con API existente\n */\n isColumnVisibleInHeader<T extends Record<string, unknown>>(\n column: C80TableColDef,\n data: T[],\n creating: boolean,\n editing: string | null\n ): boolean {\n return this.isColumnVisible(column, data, { creating, editing });\n }\n\n /**\n * Determina si una columna debe ser visible en una fila específica\n * Wrapper para mantener compatibilidad con API existente\n */\n isColumnVisibleForRow<T extends Record<string, unknown>>(\n column: C80TableColDef,\n row: T,\n data: T[],\n editing: string | null\n ): boolean {\n return this.isColumnVisible(column, data, { editing, row });\n }\n\n /**\n * Verifica si todos los valores de una columna están vacíos/nulos\n */\n private areAllColumnValuesEmpty<T extends Record<string, unknown>>(\n column: C80TableColDef,\n data: T[]\n ): boolean {\n if (data.length === 0) {\n return true;\n }\n\n return data.every(row => {\n const value = this.dataUtils.getCellValue(row, column.accessor);\n return this.dataConverter.isValueEmpty(value);\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"table-column-visibility.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-column-visibility.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, inject } from '@angular/core';\nimport type { C80TableColDef } from './table.types';\nimport { TableDataConverterService } from './table-data-converter.service';\nimport { TableDataUtilsService } from './table-data-utils.service';\n\n/**\n * Servicio para gestionar la lógica de visibilidad de columnas en tablas C80\n *\n * Maneja las reglas complejas de visibilidad basadas en:\n * - Configuración explícita (visible: false)\n * - Ocultación automática (hideIfAllValuesAreNull)\n * - Estado de creación y edición\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableColumnVisibilityService {\n\n private readonly dataConverter = inject(TableDataConverterService);\n private readonly dataUtils = inject(TableDataUtilsService);\n\n /**\n * Actualiza las keys de columnas visibles basándose en el estado actual\n * @param columns - Definiciones de columnas\n * @param data - Datos actuales de la tabla\n * @param creating - Si está en modo creación\n * @param editing - ID de fila en edición (null si no hay edición)\n * @returns Array de accessors de columnas visibles\n */\n updateVisibleKeys<T extends Record<string, unknown>>(\n columns: C80TableColDef[],\n data: T[],\n creating: boolean,\n editing: string | null\n ): string[] {\n const visibleColumns = columns.filter(col =>\n this.isColumnVisibleInHeader(col, data, creating, editing)\n );\n return visibleColumns.map(col => col.accessor);\n }\n\n /**\n * Determina si una columna debe ser visible basándose en su configuración y datos\n * Método unificado que maneja todos los casos de visibilidad\n * @param column - La definición de la columna\n * @param data - Datos actuales de la tabla\n * @param options - Opciones de contexto (creación, edición, fila específica)\n * @returns true si la columna debe ser visible\n */\n isColumnVisible<T extends Record<string, unknown>>(\n column: C80TableColDef,\n data: T[],\n options: {\n forceShowInCreation?: boolean;\n creating?: boolean;\n editing?: string | null;\n row?: T;\n } = {}\n ): boolean {\n // PRIORIDAD 1: Si visible está explícitamente establecido en false, SIEMPRE ocultar\n if (column.visible === false) {\n return false;\n }\n\n // Si no tiene hideIfAllValuesAreNull, mostrar siempre\n if (!column.hideIfAllValuesAreNull) {\n return true;\n }\n\n // PRIORIDAD 2: Para columnas con hideIfAllValuesAreNull, ocultar si el valor es falsy (excepto 0)\n // Esto aplica tanto en modo creación como edición\n\n // CONTEXTO: Modo creación\n if (options.creating) {\n // En creación, verificar el valor de la fila en creación si existe\n const creatingRow = options.row;\n if (creatingRow) {\n const cellValue = this.dataUtils.getCellValue(creatingRow, column.accessor);\n return !this.dataConverter.isValueEmpty(cellValue);\n }\n // Si no hay fila, ocultar (valor vacío por defecto)\n return false;\n }\n\n // CONTEXTO: Fila en edición\n if (options.editing !== undefined && options.editing !== null) {\n const editingRow = options.row ?? data.find(r => r['id'] === options.editing);\n if (editingRow) {\n const cellValue = this.dataUtils.getCellValue(editingRow, column.accessor);\n return !this.dataConverter.isValueEmpty(cellValue);\n }\n return false;\n }\n\n // CONTEXTO: Vista normal - verificar si todos los valores están vacíos\n return !this.areAllColumnValuesEmpty(column, data);\n }\n\n /**\n * Determina si una columna debe ser visible en los headers\n * Wrapper para mantener compatibilidad con API existente\n */\n isColumnVisibleInHeader<T extends Record<string, unknown>>(\n column: C80TableColDef,\n data: T[],\n creating: boolean,\n editing: string | null\n ): boolean {\n return this.isColumnVisible(column, data, { creating, editing });\n }\n\n /**\n * Determina si una columna debe ser visible en una fila específica\n * Wrapper para mantener compatibilidad con API existente\n */\n isColumnVisibleForRow<T extends Record<string, unknown>>(\n column: C80TableColDef,\n row: T,\n data: T[],\n editing: string | null\n ): boolean {\n return this.isColumnVisible(column, data, { editing, row });\n }\n\n /**\n * Verifica si todos los valores de una columna están vacíos/nulos\n */\n private areAllColumnValuesEmpty<T extends Record<string, unknown>>(\n column: C80TableColDef,\n data: T[]\n ): boolean {\n if (data.length === 0) {\n return true;\n }\n\n return data.every(row => {\n const value = this.dataUtils.getCellValue(row, column.accessor);\n return this.dataConverter.isValueEmpty(value);\n });\n }\n}\n"]}
|
|
@@ -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 } from '@angular/core';\nimport { C80TableColDef } from './table.types';\nimport { TableColumnVisibilityService } from './table-column-visibility.service';\nimport { TableDataUtilsService } from './table-data-utils.service';\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: C80TableColDef[],\n data: T[],\n includeHiddenIfNull: boolean\n ): C80TableColDef[] {\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: C80TableColDef[],\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: C80TableColDef[],\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>>() {\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: (columns: C80TableColDef[], data: T[]) => this.startCreate(creating, newRow, columns, data),\n cancelCreate: () => this.cancelCreate(creating, newRow),\n updateNewRow: (key: string, value: unknown) => this.updateRow(newRow, key, value),\n startEdit: (row: T, columns: C80TableColDef[], data: T[]) => this.startEdit({ editing, editRow }, row, columns, data),\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 columns: C80TableColDef[],\n data: T[]\n ): void {\n creating.set(true);\n newRow.set(this.initializeNewRow(columns, 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 row: T,\n columns: C80TableColDef[],\n data: T[]\n ): void {\n signals.editing.set(row['id'] as string);\n signals.editRow.set(this.initializeEditRow(row, columns, 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 } from '@angular/core';\nimport type { C80TableColDef } from './table.types';\nimport { TableColumnVisibilityService } from './table-column-visibility.service';\nimport { TableDataUtilsService } from './table-data-utils.service';\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: C80TableColDef[],\n data: T[],\n includeHiddenIfNull: boolean\n ): C80TableColDef[] {\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: C80TableColDef[],\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: C80TableColDef[],\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>>() {\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: (columns: C80TableColDef[], data: T[]) => this.startCreate(creating, newRow, columns, data),\n cancelCreate: () => this.cancelCreate(creating, newRow),\n updateNewRow: (key: string, value: unknown) => this.updateRow(newRow, key, value),\n startEdit: (row: T, columns: C80TableColDef[], data: T[]) => this.startEdit({ editing, editRow }, row, columns, data),\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 columns: C80TableColDef[],\n data: T[]\n ): void {\n creating.set(true);\n newRow.set(this.initializeNewRow(columns, 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 row: T,\n columns: C80TableColDef[],\n data: T[]\n ): void {\n signals.editing.set(row['id'] as string);\n signals.editRow.set(this.initializeEditRow(row, columns, 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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-data-converter.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-data-converter.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { C80TableColDef } from './table.types';\n\n/**\n * Servicio para conversión y validación de tipos de datos en tablas C80\n *\n * Maneja la conversión entre diferentes tipos de datos y la validación de valores vacíos.\n * Soporta los tipos: string, number, integer, boolean, password, enum\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableDataConverterService {\n\n /**\n * Convierte un valor de celda basándose en el tipo de columna o datos de muestra\n * @param value - Valor a convertir\n * @param col - Definición de la columna\n * @param sampleValue - Valor de muestra para inferir el tipo (opcional)\n * @returns Valor convertido al tipo apropiado\n */\n convertCellValue(value: unknown, col: C80TableColDef, sampleValue?: unknown): unknown {\n if (col.type === 'boolean') return this.toBoolean(value);\n if (col.type === 'number') return this.toNumber(value);\n if (col.type === 'integer') return this.toInteger(value);\n if (col.type === 'string' || col.type === 'password')\n return this.toStringValue(value);\n\n // Fallback: usar datos de muestra si están disponibles\n if (sampleValue) {\n if (typeof sampleValue === 'boolean') return this.toBoolean(value);\n if (typeof sampleValue === 'number') return this.toNumber(value);\n if (typeof sampleValue === 'string') return this.toStringValue(value);\n }\n\n return value;\n }\n\n /**\n * Convierte un valor a boolean usando mejores prácticas\n * @param value - Valor a convertir\n * @returns Valor booleano\n */\n toBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string')\n return value.trim().toLowerCase() === 'true' || value.trim() === '1';\n if (typeof value === 'number') return value === 1;\n return false;\n }\n\n /**\n * Convierte un valor a number usando mejores prácticas\n * @param value - Valor a convertir\n * @returns Número o undefined si no es válido\n */\n toNumber(value: unknown): number | undefined {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return undefined;\n const num = Number(trimmed);\n return Number.isNaN(num) ? undefined : num;\n }\n if (typeof value === 'boolean') return value ? 1 : 0;\n return undefined;\n }\n\n /**\n * Convierte un valor a integer usando mejores prácticas\n * @param value - Valor a convertir\n * @returns Entero o undefined si no es válido\n */\n toInteger(value: unknown): number | undefined {\n if (typeof value === 'number') return Math.floor(value);\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return undefined;\n const num = Number(trimmed);\n return Number.isNaN(num) ? undefined : Math.floor(num);\n }\n if (typeof value === 'boolean') return value ? 1 : 0;\n return undefined;\n }\n\n /**\n * Convierte un valor a string usando mejores prácticas, siempre stringifica objetos\n * @param value - Valor a convertir\n * @returns Cadena de texto\n */\n toStringValue(value: unknown): string {\n if (value == null) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean')\n return String(value);\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return '[object Object]';\n }\n }\n // Para funciones, símbolos, undefined, etc., devolver cadena vacía\n return '';\n }\n\n /**\n * Verifica si un valor individual está vacío/nulo\n * @param value - Valor a verificar\n * @returns true si el valor se considera vacío\n */\n isValueEmpty(value: unknown): boolean {\n // Considerar vacío: null, undefined, ''\n if (value === null || value === undefined || value === '') {\n return true;\n }\n\n // Para números y booleanos, siempre son valores válidos\n if (typeof value === 'number' || typeof value === 'boolean') {\n return false;\n }\n\n // Para arrays vacíos\n if (Array.isArray(value)) {\n return value.length === 0;\n }\n\n // Para objetos vacíos\n if (typeof value === 'object' && value !== null) {\n return Object.keys(value).length === 0;\n }\n\n return false;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"table-data-converter.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-data-converter.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport type { C80TableColDef } from './table.types';\n\n/**\n * Servicio para conversión y validación de tipos de datos en tablas C80\n *\n * Maneja la conversión entre diferentes tipos de datos y la validación de valores vacíos.\n * Soporta los tipos: string, number, integer, boolean, password, enum\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableDataConverterService {\n\n /**\n * Convierte un valor de celda basándose en el tipo de columna o datos de muestra\n * @param value - Valor a convertir\n * @param col - Definición de la columna\n * @param sampleValue - Valor de muestra para inferir el tipo (opcional)\n * @returns Valor convertido al tipo apropiado\n */\n convertCellValue(value: unknown, col: C80TableColDef, sampleValue?: unknown): unknown {\n if (col.type === 'boolean') return this.toBoolean(value);\n if (col.type === 'number') return this.toNumber(value);\n if (col.type === 'integer') return this.toInteger(value);\n if (col.type === 'string' || col.type === 'password')\n return this.toStringValue(value);\n\n // Fallback: usar datos de muestra si están disponibles\n if (sampleValue) {\n if (typeof sampleValue === 'boolean') return this.toBoolean(value);\n if (typeof sampleValue === 'number') return this.toNumber(value);\n if (typeof sampleValue === 'string') return this.toStringValue(value);\n }\n\n return value;\n }\n\n /**\n * Convierte un valor a boolean usando mejores prácticas\n * @param value - Valor a convertir\n * @returns Valor booleano\n */\n toBoolean(value: unknown): boolean {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string')\n return value.trim().toLowerCase() === 'true' || value.trim() === '1';\n if (typeof value === 'number') return value === 1;\n return false;\n }\n\n /**\n * Convierte un valor a number usando mejores prácticas\n * @param value - Valor a convertir\n * @returns Número o undefined si no es válido\n */\n toNumber(value: unknown): number | undefined {\n if (typeof value === 'number') return value;\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return undefined;\n const num = Number(trimmed);\n return Number.isNaN(num) ? undefined : num;\n }\n if (typeof value === 'boolean') return value ? 1 : 0;\n return undefined;\n }\n\n /**\n * Convierte un valor a integer usando mejores prácticas\n * @param value - Valor a convertir\n * @returns Entero o undefined si no es válido\n */\n toInteger(value: unknown): number | undefined {\n if (typeof value === 'number') return Math.floor(value);\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') return undefined;\n const num = Number(trimmed);\n return Number.isNaN(num) ? undefined : Math.floor(num);\n }\n if (typeof value === 'boolean') return value ? 1 : 0;\n return undefined;\n }\n\n /**\n * Convierte un valor a string usando mejores prácticas, siempre stringifica objetos\n * @param value - Valor a convertir\n * @returns Cadena de texto\n */\n toStringValue(value: unknown): string {\n if (value == null) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean')\n return String(value);\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return '[object Object]';\n }\n }\n // Para funciones, símbolos, undefined, etc., devolver cadena vacía\n return '';\n }\n\n /**\n * Verifica si un valor individual está vacío/nulo\n * @param value - Valor a verificar\n * @returns true si el valor se considera vacío\n */\n isValueEmpty(value: unknown): boolean {\n // Considerar vacío: null, undefined, ''\n if (value === null || value === undefined || value === '') {\n return true;\n }\n\n // Para números y booleanos, siempre son valores válidos\n if (typeof value === 'number' || typeof value === 'boolean') {\n return false;\n }\n\n // Para arrays vacíos\n if (Array.isArray(value)) {\n return value.length === 0;\n }\n\n // Para objetos vacíos\n if (typeof value === 'object' && value !== null) {\n return Object.keys(value).length === 0;\n }\n\n return false;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-data-utils.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-data-utils.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { C80TableColDef } from './table.types';\n\n/**\n * Servicio para utilidades de manipulación de datos en tablas C80\n *\n * Proporciona métodos para:\n * - Acceso a valores de celdas (incluyendo propiedades anidadas)\n * - Formateo de valores para display\n * - Gestión de enums y colores\n * - Ordenamiento de datos\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableDataUtilsService {\n\n /**\n * Obtiene el valor de una celda usando el accessor, soportando notación de punto para propiedades anidadas\n * @param row - La fila de datos\n * @param accessor - El accessor de la columna\n * @returns El valor de la celda\n */\n getCellValue<T extends Record<string, unknown>>(row: T, accessor: string): unknown {\n if (accessor.includes('.')) {\n return this.getNestedValue(row, accessor);\n }\n return (row as Record<string, unknown>)[accessor];\n }\n\n /**\n * Obtiene el valor de un objeto usando notación de punto (ej: 'task.name')\n * @param obj - Objeto del cual obtener el valor\n * @param accessor - Ruta de acceso usando notación de punto\n * @returns El valor anidado o undefined\n */\n getNestedValue(obj: Record<string, unknown>, accessor: string): unknown {\n return accessor.split('.').reduce((current, key) => {\n return current && typeof current === 'object' ? (current as Record<string, unknown>)[key] : undefined;\n }, obj as unknown);\n }\n\n /**\n * Devuelve el valor de display para una celda, mostrando '-' para valores falsy excepto 0, false y objetos/arrays vacíos\n * @param value - Valor a formatear\n * @param col - Definición de columna (opcional) para formateo específico por tipo\n * @returns Cadena formateada para display\n */\n getDisplayValue(value: unknown, col?: C80TableColDef): string {\n return this.formatValueByType(value, col);\n }\n\n private formatValueByType(value: unknown, col?: C80TableColDef): string {\n if (value === 0) return '0';\n if (value === false) return 'false';\n if (col?.type === 'date' && value) return this.formatDateValue(value);\n if (typeof value === 'object' && value !== null) return this.formatObjectValue(value);\n if (!value) return '-';\n return this.formatPrimitiveValue(value);\n }\n\n private formatPrimitiveValue(value: unknown): string {\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n return '-';\n }\n\n /**\n * Formatea un valor de fecha a formato legible\n * @param value - Valor de fecha (Date, string ISO, timestamp)\n * @returns Fecha formateada como DD/MM/YYYY HH:MM\n */\n private formatDateValue(value: unknown): string {\n try {\n const date = this.parseDate(value);\n if (!date || Number.isNaN(date.getTime())) return '-';\n\n const day = String(date.getDate()).padStart(2, '0');\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const year = date.getFullYear();\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n\n return `${day}/${month}/${year} ${hours}:${minutes}`;\n } catch {\n return '-';\n }\n }\n\n private parseDate(value: unknown): Date | null {\n if (value instanceof Date) return value;\n if (typeof value === 'string' || typeof value === 'number') return new Date(value);\n return null;\n }\n\n private formatObjectValue(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return '[object Object]';\n }\n } /**\n * Obtiene el texto de display para un valor enum\n * @param value - Valor del enum\n * @param col - Definición de la columna\n * @returns Texto formateado del enum\n */\n getEnumDisplayValue(value: unknown, col: C80TableColDef): string {\n if (!col.enum || (value !== 0 && !value)) {\n return '-';\n }\n const displayValue = col.enum[value as string | number];\n return (\n displayValue ||\n (typeof value === 'string' || typeof value === 'number'\n ? String(value)\n : '-')\n );\n }\n\n /**\n * Obtiene las opciones del enum como array para dropdowns select\n * @param col - Definición de la columna\n * @returns Array de opciones con value y label\n */\n getEnumOptions(col: C80TableColDef): { value: string | number; label: string }[] {\n if (!col.enum) return [];\n return Object.entries(col.enum).map(([value, label]) => ({\n value: Number.isNaN(Number(value)) ? value : Number(value),\n label,\n }));\n }\n\n /**\n * Obtiene el color CSS para un valor de celda basado en la configuración de color de la columna\n * @param value - Valor de la celda\n * @param col - Definición de la columna\n * @returns Color CSS o undefined si no hay configuración\n */\n getCellColor(value: unknown, col: C80TableColDef): string | undefined {\n if (!col.color || (value !== 0 && !value)) {\n return undefined;\n }\n return col.color[value as string | number];\n }\n\n /**\n * Aplica ordenamiento a los items basándose en las columnas con configuración de orden\n * @param items - Array de items a ordenar (se modifica in-place)\n * @param columns - Definiciones de columnas\n */\n applySorting<T extends Record<string, unknown>>(items: T[], columns: C80TableColDef[]): void {\n const orderedColumns = columns.filter((col) => col.order);\n if (orderedColumns.length > 0) {\n for (const col of orderedColumns) {\n items.sort((a, b) => {\n const valueA = this.getCellValue(a, col.accessor) as string | number;\n const valueB = this.getCellValue(b, col.accessor) as string | number;\n\n if (col.order === 'ASC') {\n if (valueA > valueB) return 1;\n if (valueA < valueB) return -1;\n return 0;\n } else {\n if (valueA < valueB) return 1;\n if (valueA > valueB) return -1;\n return 0;\n }\n });\n }\n }\n }\n\n /**\n * Calcula el max-height de la tabla basado en el tamaño\n * @param size - Tamaño configurado (0 = sin límite)\n * @returns String CSS para max-height o undefined si sin límite\n */\n getTableMaxHeight(size: number): string | undefined {\n if (size <= 0) {\n return undefined; // Sin límite de altura\n }\n // Altura base de 400px * size\n const baseHeight = 400;\n const maxHeight = Math.round(baseHeight * size);\n return `${maxHeight}px`;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"table-data-utils.service.js","sourceRoot":"","sources":["../../../../../libs/ui/src/lib/table/table-data-utils.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport type { C80TableColDef } from './table.types';\n\n/**\n * Servicio para utilidades de manipulación de datos en tablas C80\n *\n * Proporciona métodos para:\n * - Acceso a valores de celdas (incluyendo propiedades anidadas)\n * - Formateo de valores para display\n * - Gestión de enums y colores\n * - Ordenamiento de datos\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TableDataUtilsService {\n\n /**\n * Obtiene el valor de una celda usando el accessor, soportando notación de punto para propiedades anidadas\n * @param row - La fila de datos\n * @param accessor - El accessor de la columna\n * @returns El valor de la celda\n */\n getCellValue<T extends Record<string, unknown>>(row: T, accessor: string): unknown {\n if (accessor.includes('.')) {\n return this.getNestedValue(row, accessor);\n }\n return (row as Record<string, unknown>)[accessor];\n }\n\n /**\n * Obtiene el valor de un objeto usando notación de punto (ej: 'task.name')\n * @param obj - Objeto del cual obtener el valor\n * @param accessor - Ruta de acceso usando notación de punto\n * @returns El valor anidado o undefined\n */\n getNestedValue(obj: Record<string, unknown>, accessor: string): unknown {\n return accessor.split('.').reduce((current, key) => {\n return current && typeof current === 'object' ? (current as Record<string, unknown>)[key] : undefined;\n }, obj as unknown);\n }\n\n /**\n * Devuelve el valor de display para una celda, mostrando '-' para valores falsy excepto 0, false y objetos/arrays vacíos\n * @param value - Valor a formatear\n * @param col - Definición de columna (opcional) para formateo específico por tipo\n * @returns Cadena formateada para display\n */\n getDisplayValue(value: unknown, col?: C80TableColDef): string {\n return this.formatValueByType(value, col);\n }\n\n private formatValueByType(value: unknown, col?: C80TableColDef): string {\n if (value === 0) return '0';\n if (value === false) return 'false';\n if (col?.type === 'date' && value) return this.formatDateValue(value);\n if (typeof value === 'object' && value !== null) return this.formatObjectValue(value);\n if (!value) return '-';\n return this.formatPrimitiveValue(value);\n }\n\n private formatPrimitiveValue(value: unknown): string {\n if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n return '-';\n }\n\n /**\n * Formatea un valor de fecha a formato legible\n * @param value - Valor de fecha (Date, string ISO, timestamp)\n * @returns Fecha formateada como DD/MM/YYYY HH:MM\n */\n private formatDateValue(value: unknown): string {\n try {\n const date = this.parseDate(value);\n if (!date || Number.isNaN(date.getTime())) return '-';\n\n const day = String(date.getDate()).padStart(2, '0');\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const year = date.getFullYear();\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n\n return `${day}/${month}/${year} ${hours}:${minutes}`;\n } catch {\n return '-';\n }\n }\n\n private parseDate(value: unknown): Date | null {\n if (value instanceof Date) return value;\n if (typeof value === 'string' || typeof value === 'number') return new Date(value);\n return null;\n }\n\n private formatObjectValue(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n return '[object Object]';\n }\n } /**\n * Obtiene el texto de display para un valor enum\n * @param value - Valor del enum\n * @param col - Definición de la columna\n * @returns Texto formateado del enum\n */\n getEnumDisplayValue(value: unknown, col: C80TableColDef): string {\n if (!col.enum || (value !== 0 && !value)) {\n return '-';\n }\n const displayValue = col.enum[value as string | number];\n return (\n displayValue ||\n (typeof value === 'string' || typeof value === 'number'\n ? String(value)\n : '-')\n );\n }\n\n /**\n * Obtiene las opciones del enum como array para dropdowns select\n * @param col - Definición de la columna\n * @returns Array de opciones con value y label\n */\n getEnumOptions(col: C80TableColDef): { value: string | number; label: string }[] {\n if (!col.enum) return [];\n return Object.entries(col.enum).map(([value, label]) => ({\n value: Number.isNaN(Number(value)) ? value : Number(value),\n label,\n }));\n }\n\n /**\n * Obtiene el color CSS para un valor de celda basado en la configuración de color de la columna\n * @param value - Valor de la celda\n * @param col - Definición de la columna\n * @returns Color CSS o undefined si no hay configuración\n */\n getCellColor(value: unknown, col: C80TableColDef): string | undefined {\n if (!col.color || (value !== 0 && !value)) {\n return undefined;\n }\n return col.color[value as string | number];\n }\n\n /**\n * Aplica ordenamiento a los items basándose en las columnas con configuración de orden\n * @param items - Array de items a ordenar (se modifica in-place)\n * @param columns - Definiciones de columnas\n */\n applySorting<T extends Record<string, unknown>>(items: T[], columns: C80TableColDef[]): void {\n const orderedColumns = columns.filter((col) => col.order);\n if (orderedColumns.length > 0) {\n for (const col of orderedColumns) {\n items.sort((a, b) => {\n const valueA = this.getCellValue(a, col.accessor) as string | number;\n const valueB = this.getCellValue(b, col.accessor) as string | number;\n\n if (col.order === 'ASC') {\n if (valueA > valueB) return 1;\n if (valueA < valueB) return -1;\n return 0;\n } else {\n if (valueA < valueB) return 1;\n if (valueA > valueB) return -1;\n return 0;\n }\n });\n }\n }\n }\n\n /**\n * Calcula el max-height de la tabla basado en el tamaño\n * @param size - Tamaño configurado (0 = sin límite)\n * @returns String CSS para max-height o undefined si sin límite\n */\n getTableMaxHeight(size: number): string | undefined {\n if (size <= 0) {\n return undefined; // Sin límite de altura\n }\n // Altura base de 400px * size\n const baseHeight = 400;\n const maxHeight = Math.round(baseHeight * size);\n return `${maxHeight}px`;\n }\n}\n"]}
|
|
@@ -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 { Injectable, signal, OutputEmitterRef } from '@angular/core';\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 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(allItems, allIds.size, signals.selectAllChecked, signals.selectAllIndeterminate);\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(newData, preservedSelection.size, signals.selectAllChecked, signals.selectAllIndeterminate);\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>>(\n allItems: T[],\n selectedCount: number,\n selectAllChecked: ReturnType<typeof signal<boolean>>,\n selectAllIndeterminate: ReturnType<typeof signal<boolean>>\n ): void {\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 } from '@angular/core';\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 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(allItems, allIds.size, signals.selectAllChecked, signals.selectAllIndeterminate);\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(newData, preservedSelection.size, signals.selectAllChecked, signals.selectAllIndeterminate);\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>>(\n allItems: T[],\n selectedCount: number,\n selectAllChecked: ReturnType<typeof signal<boolean>>,\n selectAllIndeterminate: ReturnType<typeof signal<boolean>>\n ): void {\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,4 +1,4 @@
|
|
|
1
|
-
import { Component, input, signal, computed, output, inject, } from '@angular/core';
|
|
1
|
+
import { Component, ChangeDetectionStrategy, input, signal, computed, output, inject, } from '@angular/core';
|
|
2
2
|
import { C80IconComponent } from '../icon';
|
|
3
3
|
import { TableColumnVisibilityService } from './table-column-visibility.service';
|
|
4
4
|
import { TableDataUtilsService } from './table-data-utils.service';
|
|
@@ -337,7 +337,7 @@ import * as i0 from "@angular/core";
|
|
|
337
337
|
async handleActionWithConfirmation(action, row) {
|
|
338
338
|
if (!action.confirmation)
|
|
339
339
|
return;
|
|
340
|
-
const confirmed = await this.modalService.confirm(action.confirmation.title, action.confirmation.message, action.confirmation.confirmText
|
|
340
|
+
const confirmed = await this.modalService.confirm(action.confirmation.title, action.confirmation.message, action.confirmation.confirmText ?? 'Confirmar', action.confirmation.cancelText ?? 'Cancelar');
|
|
341
341
|
if (confirmed) {
|
|
342
342
|
this.actionClick.emit({ action: action.name, row });
|
|
343
343
|
}
|
|
@@ -403,11 +403,27 @@ import * as i0 from "@angular/core";
|
|
|
403
403
|
isColumnVisibleForRow(column, row) {
|
|
404
404
|
return this.visibilityService.isColumnVisibleForRow(column, row, this.data(), this.editing());
|
|
405
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* Obtiene el color de una acción considerando el tema actual.
|
|
408
|
+
* Si la acción tiene color explícito, lo usa. Si no, aplica color por tema.
|
|
409
|
+
*/
|
|
410
|
+
getActionColor(action) {
|
|
411
|
+
// Delete siempre en rojo (color warn de Material)
|
|
412
|
+
if (action.name === 'delete') {
|
|
413
|
+
return undefined; // Deja que el atributo [color]="warn" lo maneje
|
|
414
|
+
}
|
|
415
|
+
// Si la acción tiene color explícito (rojo/verde para toggles), respetarlo
|
|
416
|
+
if (action.color) {
|
|
417
|
+
return action.color;
|
|
418
|
+
}
|
|
419
|
+
// Para acciones sin color explícito, usar el color de dark mode
|
|
420
|
+
return '#e9ecef';
|
|
421
|
+
}
|
|
406
422
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: C80TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
407
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: C80TableComponent, isStandalone: true, selector: "c80-table", inputs: { data$: { classPropertyName: "data$", publicName: "data$", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, inputValues$: { classPropertyName: "inputValues$", publicName: "inputValues$", isSignal: true, isRequired: false, transformFunction: null }, customActions: { classPropertyName: "customActions", publicName: "customActions", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, allowSelection: { classPropertyName: "allowSelection", publicName: "allowSelection", isSignal: true, isRequired: false, transformFunction: null }, noConfirm: { classPropertyName: "noConfirm", publicName: "noConfirm", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionClick: "actionClick", searchTerm: "searchTerm", errorEvent: "errorEvent", selectable: "selectable" }, ngImport: i0, template: "<div class=\"table-responsive\" [style.max-height]=\"tableMaxHeight()\" [style.overflow-y]=\"size() > 0 ? 'auto' : 'visible'\">\n <!-- Search Bar -->\n @if (searchable()) {\n <div class=\"search-container\">\n <div class=\"search-input-wrapper\">\n <div class=\"input-group\">\n <span class=\"input-group-text\">\n <c80-icon icon=\"search\" [size]=\".8\"></c80-icon>\n </span>\n <input type=\"text\" class=\"form-control search-input\" placeholder=\"Buscar...\" [value]=\"searchValue()\" (input)=\"onSearchInput($event)\" aria-label=\"Buscar en la tabla\" />\n @if (searchValue()) {\n <button class=\"btn btn-outline-secondary btn-borrar\" type=\"button\" (click)=\"clearSearch()\" title=\"Limpiar b\u00FAsqueda\">\n <c80-icon icon=\"cancel\" [size]=\".7\"></c80-icon>\n </button>\n }\n </div>\n </div>\n </div>\n }\n\n <table class=\"table table-bordered table-hover align-middle\">\n <thead class=\"thead table-light sticky-header\">\n <tr>\n @if (allowSelection() && data().length !== 0) {\n <th class=\"text-center selection-column\">\n @if (multiple()) {\n <input type=\"checkbox\" [checked]=\"selectAllChecked()\" [indeterminate]=\"selectAllIndeterminate()\" (change)=\"toggleSelectAll()\" aria-label=\"Seleccionar todo\" />\n }\n </th>\n }\n @for (col of columns(); track col) {\n @if (isColumnVisibleInHeader(col)) {\n @if (col.type === 'boolean') {\n <th class=\"text-center boolean-column\">{{ col.label }}</th>\n }\n @else if (col.type === 'number' || col.type === 'integer') {\n <th class=\"text-center number-column\">{{ col.label }}</th>\n }\n @else {\n <th>{{ col.label }}</th>\n }\n }\n }\n @if (hasAnyActions()) {\n <th class=\"table-actions-header\">\n <div class=\"actions-wrapper\">\n <span>Actions</span>\n @if (hasCrudCreate()) {\n <c80-icon button icon=\"add\" [disabled]=\"creating()\" title=\"Agregar\" [size]=\".6\" (iconClick)=\"startCreate()\"></c80-icon>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of data(); track trackById(i, row); let i = $index) {\n <tr>\n @if (allowSelection() && data().length !== 0) {\n <td class=\"text-center selection-column\">\n <input type=\"checkbox\" [checked]=\"isItemSelected(row)\" (change)=\"toggleItemSelection(row)\" [attr.aria-label]=\"'Seleccionar fila ' + (i + 1)\" />\n </td>\n }\n @for (col of columns(); track col) {\n @if (isColumnVisibleForRow(col, row)) {\n @if (col.type === 'boolean') {\n <td class=\"text-center boolean-column\">\n @if (editing() === row['id'] && !col.readOnly) {\n <input type=\"checkbox\" [checked]=\"!!editRow()?.[col.accessor]\" (change)=\"onEditInput($event, col.accessor, col)\" [attr.aria-label]=\"col.label\" />\n }\n @else {\n @if (getCellValue(row, col.accessor) === true) {\n <c80-icon icon=\"check\" [size]=\".7\"></c80-icon>\n <br />\n }\n @else if (getCellValue(row, col.accessor) === false) {\n <c80-icon icon=\"cancel\" [size]=\".7\"></c80-icon>\n <br />\n }\n }\n </td>\n }\n @else if (col.type === 'number' || col.type === 'integer') {\n <td class=\"text-center number-column\">\n @if (editing() === row['id'] && !col.readOnly) {\n <input class=\"form-control form-control-sm\" type=\"number\" [value]=\"editRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" [min]=\"col.min\" [max]=\"col.max\" [step]=\"col.type === 'integer' ? '1' : 'any'\"\n (input)=\"onEditInput($event, col.accessor, col)\" />\n }\n @else {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{ getDisplayValue(getCellValue(row,\n col.accessor), col) }}</span>\n }\n </td>\n }\n @else {\n <td>\n @if (editing() === row['id'] && !col.readOnly) {\n @if (col.type === 'enum') {\n <select class=\"form-control form-control-sm\" [value]=\"editRow()?.[col.accessor] ?? ''\" (change)=\"onEditInput($event, col.accessor, col)\">\n <option value=\"\">{{ col.label }}</option>\n @for (option of getEnumOptions(col); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <input class=\"form-control form-control-sm\" [type]=\"col.type === 'password' ? 'password' : 'text'\" [value]=\"editRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" (input)=\"onEditInput($event, col.accessor, col)\" />\n }\n }\n @else {\n @if (col.type === 'password') {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">******</span>\n }\n @else if (col.type === 'enum') {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{\n getEnumDisplayValue(getCellValue(row, col.accessor), col)\n }}</span>\n }\n @else if (getCellValue(row, col.accessor) === true) {\n <c80-icon icon=\"check\" [size]=\".7\"></c80-icon>\n }\n @else if (getCellValue(row, col.accessor) === false) {\n <c80-icon icon=\"cancel\" [size]=\".7\"></c80-icon>\n }\n @else {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{ getDisplayValue(getCellValue(row,\n col.accessor), col) }}</span>\n }\n }\n </td>\n }\n }\n }\n @if (hasAnyActions()) {\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (editing() === row['id']) {\n <!-- Modo edici\u00F3n: mostrar guardar y cancelar -->\n @if (hasCrudUpdate()) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveEdit(row)\" [size]=\".7\"></c80-icon>\n }\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelEdit()\" [size]=\".7\"></c80-icon>\n }\n @else {\n @for (action of customActions(); track action.name) {\n @if (shouldShowAction(action, row)) {\n <c80-icon button [icon]=\"action.icon\" [customColor]=\"action.color\" [color]=\"action.name === 'delete' ? 'warn' : 'primary'\" [title]=\"getActionTooltip(action)\" (iconClick)=\"onDynamicAction(action, row)\" [size]=\".7\"></c80-icon>\n }\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n @if (creating() && hasCrudCreate()) {\n <tr>\n @if (allowSelection() && data().length !== 0) {\n <td class=\"text-center selection-column\">\n <!-- Empty cell for alignment -->\n </td>\n }\n @for (col of columns(); track col) {\n @if (isColumnVisible(col)) {\n @if (col.type === 'boolean') {\n <td class=\"text-center\">\n @if (!col.readOnly) {\n <input type=\"checkbox\" [checked]=\"!!newRow()?.[col.accessor]\" (change)=\"onInput($event, col.accessor, col)\" [attr.aria-label]=\"col.label\" />\n }\n @else {\n <!-- ReadOnly boolean column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n } @else if (col.type === 'number' || col.type === 'integer') {\n <td class=\"text-center number-column\">\n @if (!col.readOnly) {\n <input class=\"form-control form-control-sm\" type=\"number\" [value]=\"newRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" [min]=\"col.min\" [max]=\"col.max\" [step]=\"col.type === 'integer' ? '1' : 'any'\"\n (input)=\"onInput($event, col.accessor, col)\" />\n }\n @else {\n <!-- ReadOnly number column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n } @else {\n <td>\n @if (!col.readOnly) {\n @if (col.type === 'enum') {\n <select class=\"form-control form-control-sm\" [value]=\"newRow()?.[col.accessor] ?? ''\" (change)=\"onInput($event, col.accessor, col)\">\n <option value=\"\">{{ col.label }}</option>\n @for (option of getEnumOptions(col); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <input class=\"form-control form-control-sm\" type=\"text\" [value]=\"newRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" (input)=\"onInput($event, col.accessor, col)\" />\n }\n }\n @else {\n <!-- ReadOnly column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n }\n }\n }\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (hasCrudCreate()) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveCreate()\" [size]=\".7\"></c80-icon>\n }\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelCreate()\" [size]=\".7\"></c80-icon>\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n @if (data().length === 0 && !creating()) {\n <div class=\"text-center text-muted py-3 small\">\n No hay datos para mostrar.\n </div>\n }\n</div>\n\n<c80-modal></c80-modal>", styles: ["@charset \"UTF-8\";input[type=checkbox]{width:1.3rem!important;height:1.3rem!important;accent-color:rgba(226,0,0,.7647058824);background:#fff;margin:0 .25rem;vertical-align:middle;cursor:pointer}.table-responsive{width:100%;overflow-x:auto}.table-responsive .search-container{margin-bottom:-.06rem}.table-responsive .search-container .search-input-wrapper .input-group .btn-borrar{border-bottom-right-radius:0;border-color:#dee2e6}.table-responsive .search-container .search-input-wrapper .input-group .input-group-text{background-color:#f8f9fa;border-color:#dee2e6;border-bottom-left-radius:0;color:#495057;width:56px}.table-responsive .search-container .search-input-wrapper .input-group .input-group-text c80-icon{display:flex;align-items:center;justify-content:center;padding-bottom:.2rem}.table-responsive .search-container .search-input-wrapper .input-group .search-input{border-color:#dee2e6;border-bottom-right-radius:0;font-size:.95rem;outline:none!important}.table-responsive .search-container .search-input-wrapper .input-group .search-input:focus{outline:none!important}.table-responsive .search-container .search-input-wrapper .input-group .search-input::placeholder{color:#999;font-style:italic}.table-responsive .table{min-width:0px;margin-bottom:.5rem}.table-responsive .table .sticky-header{position:sticky;top:0;z-index:10;background-color:#f8f9fa!important}.table-responsive .table .sticky-header .table-actions-header{display:table-cell;vertical-align:middle;padding:.2rem .6rem!important;background-color:#f8f9fa!important}.table-responsive .table .sticky-header .actions-wrapper{display:flex;align-items:center;justify-content:center;gap:.5rem;height:100%}.table-responsive .table .sticky-header th{max-height:31px!important;vertical-align:middle!important;padding:.2rem .6rem!important;font-size:small!important;background-color:#f8f9fa!important;border-bottom:2px solid #dee2e6}.table-responsive .table tbody td{height:35px!important;min-height:35px!important;max-height:35px!important;vertical-align:middle!important;padding:.2rem .8rem!important;font-size:small}.table-responsive .table tbody tr{height:35px!important;min-height:35px!important;max-height:35px!important;cursor:pointer}.table-responsive .table tbody tr:hover{background-color:#f5f5f5}.table-responsive .table tbody input{border:1px solid rgba(34,0,255,.37);height:100%!important;font-size:smaller!important}.table-responsive .table tbody input[type=text],.table-responsive .table tbody input:not([type]){width:100%!important}.table-responsive .table tbody input[type=number]{min-width:80px!important;width:80px!important;text-align:center}.table-responsive .table thead th.boolean-column,.table-responsive .table tbody td.boolean-column,.table-responsive .table thead th.selection-column,.table-responsive .table tbody td.selection-column,.table-responsive .table thead th.table-actions-header,.table-responsive .table tbody td.table-actions-header{width:1%;white-space:nowrap}.table-responsive .table thead th.number-column,.table-responsive .table tbody td.number-column{width:1%;white-space:nowrap;text-align:center}.table-responsive .table thead th.number-column input[type=number],.table-responsive .table tbody td.number-column input[type=number]{min-width:80px!important;width:80px!important;text-align:center}.table-responsive .table .actions-cell{white-space:nowrap;padding:0!important}.table-responsive .table .actions-container{display:flex;flex-direction:row;justify-content:center;align-items:center;width:100%;height:100%}\n"], dependencies: [{ kind: "component", type: C80IconComponent, selector: "c80-icon", inputs: ["icon", "color", "customColor", "disabled", "size", "button", "border", "type", "textLeft", "textRight"], outputs: ["iconClick"] }, { kind: "component", type: C80ModalComponent, selector: "c80-modal" }] });
|
|
423
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: C80TableComponent, isStandalone: true, selector: "c80-table", inputs: { data$: { classPropertyName: "data$", publicName: "data$", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, inputValues$: { classPropertyName: "inputValues$", publicName: "inputValues$", isSignal: true, isRequired: false, transformFunction: null }, customActions: { classPropertyName: "customActions", publicName: "customActions", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, allowSelection: { classPropertyName: "allowSelection", publicName: "allowSelection", isSignal: true, isRequired: false, transformFunction: null }, noConfirm: { classPropertyName: "noConfirm", publicName: "noConfirm", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionClick: "actionClick", searchTerm: "searchTerm", errorEvent: "errorEvent", selectable: "selectable" }, ngImport: i0, template: "<!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n<div class=\"table-responsive\" [style.max-height]=\"tableMaxHeight()\" [style.overflow-y]=\"size() > 0 ? 'auto' : 'visible'\">\n <!-- Search Bar -->\n @if (searchable()) {\n <div class=\"search-container\">\n <div class=\"search-input-wrapper\">\n <div class=\"input-group\">\n <span class=\"input-group-text\">\n <c80-icon icon=\"search\" [size]=\".65\" [button]=\"false\" color=\"dark\" />\n </span>\n <input type=\"text\" class=\"form-control search-input\" placeholder=\"Buscar...\" [value]=\"searchValue()\" (input)=\"onSearchInput($event)\" aria-label=\"Buscar en la tabla\" />\n @if (searchValue()) {\n <button class=\"btn btn-outline-secondary btn-borrar\" type=\"button\" (click)=\"clearSearch()\" title=\"Limpiar b\u00FAsqueda\">\n <c80-icon icon=\"cancel\" [size]=\".6\" color=\"dark\" />\n </button>\n }\n </div>\n </div>\n </div>\n }\n\n <table class=\"table table-bordered table-hover align-middle\">\n <thead class=\"thead table-light sticky-header\">\n <tr>\n @if (allowSelection() && data().length !== 0) {\n <th class=\"text-center selection-column\">\n @if (multiple()) {\n <input type=\"checkbox\" [checked]=\"selectAllChecked()\" [indeterminate]=\"selectAllIndeterminate()\" (change)=\"toggleSelectAll()\" aria-label=\"Seleccionar todo\" />\n }\n </th>\n }\n @for (col of columns(); track col) {\n @if (isColumnVisibleInHeader(col)) {\n @if (col.type === 'boolean') {\n <th class=\"text-center boolean-column\">{{ col.label }}</th>\n }\n @else if (col.type === 'number' || col.type === 'integer') {\n <th class=\"text-center number-column\">{{ col.label }}</th>\n }\n @else {\n <th>{{ col.label }}</th>\n }\n }\n }\n @if (hasAnyActions()) {\n <th class=\"table-actions-header\">\n <div class=\"actions-wrapper\">\n <span>Actions</span>\n @if (hasCrudCreate()) {\n <c80-icon button icon=\"add\" [disabled]=\"creating()\" title=\"Agregar\" [size]=\".6\" (iconClick)=\"startCreate()\" color=\"dark\" />\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of data(); track trackById(i, row); let i = $index) {\n <tr>\n @if (allowSelection() && data().length !== 0) {\n <td class=\"text-center selection-column\">\n <input type=\"checkbox\" [checked]=\"isItemSelected(row)\" (change)=\"toggleItemSelection(row)\" [attr.aria-label]=\"'Seleccionar fila ' + (i + 1)\" />\n </td>\n }\n @for (col of columns(); track col) {\n @if (isColumnVisibleForRow(col, row)) {\n @if (col.type === 'boolean') {\n <td class=\"text-center boolean-column\">\n @if (editing() === row['id'] && !col.readOnly) {\n <input type=\"checkbox\" [checked]=\"!!editRow()?.[col.accessor]\" (change)=\"onEditInput($event, col.accessor, col)\" [attr.aria-label]=\"col.label\" />\n }\n @else {\n @if (getCellValue(row, col.accessor) === true) {\n <c80-icon icon=\"check\" [size]=\".7\" color=\"dark\" />\n <br />\n }\n @else if (getCellValue(row, col.accessor) === false) {\n <c80-icon icon=\"cancel\" [size]=\".7\" color=\"dark\" />\n <br />\n }\n }\n </td>\n }\n @else if (col.type === 'number' || col.type === 'integer') {\n <td class=\"text-center number-column\">\n @if (editing() === row['id'] && !col.readOnly) {\n <input class=\"form-control form-control-sm\" type=\"number\" [value]=\"editRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" [min]=\"col.min\" [max]=\"col.max\" [step]=\"col.type === 'integer' ? '1' : 'any'\"\n (input)=\"onEditInput($event, col.accessor, col)\" />\n }\n @else {\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{ getDisplayValue(getCellValue(row,\n col.accessor), col) }}</span>\n }\n </td>\n }\n @else {\n <td>\n @if (editing() === row['id'] && !col.readOnly) {\n @if (col.type === 'enum') {\n <select class=\"form-control form-control-sm\" [value]=\"editRow()?.[col.accessor] ?? ''\" (change)=\"onEditInput($event, col.accessor, col)\">\n <option value=\"\">{{ col.label }}</option>\n @for (option of getEnumOptions(col); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <input class=\"form-control form-control-sm\" [type]=\"col.type === 'password' ? 'password' : 'text'\" [value]=\"editRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" (input)=\"onEditInput($event, col.accessor, col)\" />\n }\n }\n @else {\n @if (col.type === 'password') {\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">******</span>\n }\n @else if (col.type === 'enum') {\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{\n getEnumDisplayValue(getCellValue(row, col.accessor), col)\n }}</span>\n }\n @else if (getCellValue(row, col.accessor) === true) {\n <c80-icon icon=\"check\" [size]=\".7\" color=\"dark\" />\n }\n @else if (getCellValue(row, col.accessor) === false) {\n <c80-icon icon=\"cancel\" [size]=\".7\" color=\"dark\" />\n }\n @else {\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{ getDisplayValue(getCellValue(row,\n col.accessor), col) }}</span>\n }\n }\n </td>\n }\n }\n }\n @if (hasAnyActions()) {\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (editing() === row['id']) {\n <!-- Modo edici\u00F3n: mostrar guardar y cancelar -->\n @if (hasCrudUpdate()) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveEdit(row)\" [size]=\".7\" color=\"dark\" />\n }\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelEdit()\" [size]=\".7\" />\n }\n @else {\n @for (action of customActions(); track action.name) {\n @if (shouldShowAction(action, row)) {\n <c80-icon button [icon]=\"action.icon\" [customColor]=\"getActionColor(action)\" [color]=\"action.name === 'delete' ? 'warn' : 'primary'\" [title]=\"getActionTooltip(action)\" (iconClick)=\"onDynamicAction(action, row)\" [size]=\".7\" />\n }\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n @if (creating() && hasCrudCreate()) {\n <tr>\n @if (allowSelection() && data().length !== 0) {\n <td class=\"text-center selection-column\">\n <!-- Empty cell for alignment -->\n </td>\n }\n @for (col of columns(); track col) {\n @if (isColumnVisible(col)) {\n @if (col.type === 'boolean') {\n <td class=\"text-center\">\n @if (!col.readOnly) {\n <input type=\"checkbox\" [checked]=\"!!newRow()?.[col.accessor]\" (change)=\"onInput($event, col.accessor, col)\" [attr.aria-label]=\"col.label\" />\n }\n @else {\n <!-- ReadOnly boolean column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n } @else if (col.type === 'number' || col.type === 'integer') {\n <td class=\"text-center number-column\">\n @if (!col.readOnly) {\n <input class=\"form-control form-control-sm\" type=\"number\" [value]=\"newRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" [min]=\"col.min\" [max]=\"col.max\" [step]=\"col.type === 'integer' ? '1' : 'any'\"\n (input)=\"onInput($event, col.accessor, col)\" />\n }\n @else {\n <!-- ReadOnly number column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n } @else {\n <td>\n @if (!col.readOnly) {\n @if (col.type === 'enum') {\n <select class=\"form-control form-control-sm\" [value]=\"newRow()?.[col.accessor] ?? ''\" (change)=\"onInput($event, col.accessor, col)\">\n <option value=\"\">{{ col.label }}</option>\n @for (option of getEnumOptions(col); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <input class=\"form-control form-control-sm\" type=\"text\" [value]=\"newRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" (input)=\"onInput($event, col.accessor, col)\" />\n }\n }\n @else {\n <!-- ReadOnly column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n }\n }\n }\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (hasCrudCreate()) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveCreate()\" [size]=\".7\" color=\"dark\" />\n }\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelCreate()\" [size]=\".7\" />\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n @if (data().length === 0 && !creating()) {\n <div class=\"text-center text-muted py-3 small\">\n No hay datos para mostrar.\n </div>\n }\n</div>\n\n<c80-modal />", styles: ["@charset \"UTF-8\";input[type=checkbox]{width:1.3rem!important;height:1.3rem!important;accent-color:var(--color-icon-danger);background:var(--color-bg-primary);margin:0 .25rem;vertical-align:middle;cursor:pointer}.table-responsive{width:100%;overflow-x:auto}.table-responsive .search-container{margin-bottom:-.06rem}.table-responsive .search-container .search-input-wrapper .input-group .btn-borrar{border-bottom-right-radius:0;border-color:var(--color-border-default);height:32px}.table-responsive .search-container .search-input-wrapper .input-group .input-group-text{background-color:var(--color-bg-secondary);border-color:var(--color-border-default);border-bottom-left-radius:0;color:var(--color-text-secondary);width:56.1px;height:32px;padding:.25rem .5rem}.table-responsive .search-container .search-input-wrapper .input-group .input-group-text c80-icon{display:flex;align-items:center;justify-content:center}.table-responsive .search-container .search-input-wrapper .input-group .search-input{border-color:var(--color-border-default);border-bottom-right-radius:0;font-size:.75rem;height:32px;padding:.25rem .5rem;outline:none!important;background-color:var(--color-bg-primary);color:var(--color-text-primary)}.table-responsive .search-container .search-input-wrapper .input-group .search-input:focus{outline:none!important}.table-responsive .search-container .search-input-wrapper .input-group .search-input::placeholder{color:var(--color-text-muted);font-style:italic}.table-responsive .table{min-width:0px;margin-bottom:.5rem;background-color:var(--color-bg-primary);color:var(--color-text-primary);border-color:var(--color-border-default)}.table-responsive .table.table-bordered,.table-responsive .table.table-bordered th,.table-responsive .table.table-bordered td{border-color:var(--color-border-default)}.table-responsive .table.table-hover tbody tr:hover{background-color:var(--color-bg-hover)!important;color:var(--color-text-primary)}.table-responsive .table.table-hover tbody tr:hover td{background-color:var(--color-bg-hover)}.table-responsive .table .sticky-header{position:sticky;top:0;z-index:10;background-color:var(--color-bg-secondary)!important}.table-responsive .table .sticky-header .table-actions-header{display:table-cell;vertical-align:middle;padding:.2rem .6rem!important;background-color:var(--color-bg-secondary)!important}.table-responsive .table .sticky-header .actions-wrapper{display:flex;align-items:center;justify-content:center;gap:.5rem;height:100%}.table-responsive .table .sticky-header th{max-height:31px!important;vertical-align:middle!important;padding:.2rem .6rem!important;font-size:small!important;background-color:var(--color-bg-secondary)!important;border-bottom:2px solid var(--color-border-default);color:var(--color-text-primary)}.table-responsive .table tbody{background-color:var(--color-bg-primary)}.table-responsive .table tbody td{height:35px!important;min-height:35px!important;max-height:35px!important;vertical-align:middle!important;padding:.2rem .8rem!important;font-size:small;color:var(--color-text-primary);background-color:var(--color-bg-primary);border-color:var(--color-border-default)}.table-responsive .table tbody tr{height:35px!important;min-height:35px!important;max-height:35px!important;cursor:pointer;background-color:var(--color-bg-primary)}.table-responsive .table tbody tr:hover{background-color:var(--color-bg-hover)!important}.table-responsive .table tbody tr:hover td{background-color:var(--color-bg-hover)}.table-responsive .table tbody .text-muted{color:var(--color-text-muted)!important}.table-responsive .table tbody input,.table-responsive .table tbody select{border:1px solid var(--color-border-default);height:100%!important;font-size:smaller!important;background-color:var(--color-bg-primary);color:var(--color-text-primary)}.table-responsive .table tbody input:focus,.table-responsive .table tbody select:focus{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus)}.table-responsive .table tbody input::placeholder,.table-responsive .table tbody select::placeholder{color:var(--color-text-muted)}.table-responsive .table tbody input[type=text],.table-responsive .table tbody input:not([type]){width:100%!important}.table-responsive .table tbody input[type=number]{min-width:80px!important;width:80px!important;text-align:center}.table-responsive .table tbody select{width:100%!important;padding:.25rem .5rem}.table-responsive .table thead th.boolean-column,.table-responsive .table tbody td.boolean-column,.table-responsive .table thead th.selection-column,.table-responsive .table tbody td.selection-column,.table-responsive .table thead th.table-actions-header,.table-responsive .table tbody td.table-actions-header{width:1%;white-space:nowrap}.table-responsive .table thead th.number-column,.table-responsive .table tbody td.number-column{width:1%;white-space:nowrap;text-align:center}.table-responsive .table thead th.number-column input[type=number],.table-responsive .table tbody td.number-column input[type=number]{min-width:80px!important;width:80px!important;text-align:center}.table-responsive .table .actions-cell{white-space:nowrap;padding:0!important}.table-responsive .table .actions-container{display:flex;flex-direction:row;justify-content:center;align-items:center;width:100%;height:100%}.table-responsive .text-center.text-muted{color:var(--color-text-muted)!important}.table-responsive .btn-outline-secondary{background-color:var(--color-bg-primary);color:var(--color-text-primary);border-color:var(--color-border-default)}.table-responsive .btn-outline-secondary:hover{background-color:var(--color-bg-hover);border-color:var(--color-border-medium)}.table-responsive .btn-outline-secondary:focus{box-shadow:var(--shadow-focus)}\n"], dependencies: [{ kind: "component", type: C80IconComponent, selector: "c80-icon", inputs: ["icon", "color", "customColor", "disabled", "size", "button", "border", "type", "textLeft", "textRight"], outputs: ["iconClick"] }, { kind: "component", type: C80ModalComponent, selector: "c80-modal" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
408
424
|
}
|
|
409
425
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: C80TableComponent, decorators: [{
|
|
410
426
|
type: Component,
|
|
411
|
-
args: [{ selector: 'c80-table', standalone: true, imports: [C80IconComponent, C80ModalComponent], template: "<div class=\"table-responsive\" [style.max-height]=\"tableMaxHeight()\" [style.overflow-y]=\"size() > 0 ? 'auto' : 'visible'\">\n <!-- Search Bar -->\n @if (searchable()) {\n <div class=\"search-container\">\n <div class=\"search-input-wrapper\">\n <div class=\"input-group\">\n <span class=\"input-group-text\">\n <c80-icon icon=\"search\" [size]=\".8\"></c80-icon>\n </span>\n <input type=\"text\" class=\"form-control search-input\" placeholder=\"Buscar...\" [value]=\"searchValue()\" (input)=\"onSearchInput($event)\" aria-label=\"Buscar en la tabla\" />\n @if (searchValue()) {\n <button class=\"btn btn-outline-secondary btn-borrar\" type=\"button\" (click)=\"clearSearch()\" title=\"Limpiar b\u00FAsqueda\">\n <c80-icon icon=\"cancel\" [size]=\".7\"></c80-icon>\n </button>\n }\n </div>\n </div>\n </div>\n }\n\n <table class=\"table table-bordered table-hover align-middle\">\n <thead class=\"thead table-light sticky-header\">\n <tr>\n @if (allowSelection() && data().length !== 0) {\n <th class=\"text-center selection-column\">\n @if (multiple()) {\n <input type=\"checkbox\" [checked]=\"selectAllChecked()\" [indeterminate]=\"selectAllIndeterminate()\" (change)=\"toggleSelectAll()\" aria-label=\"Seleccionar todo\" />\n }\n </th>\n }\n @for (col of columns(); track col) {\n @if (isColumnVisibleInHeader(col)) {\n @if (col.type === 'boolean') {\n <th class=\"text-center boolean-column\">{{ col.label }}</th>\n }\n @else if (col.type === 'number' || col.type === 'integer') {\n <th class=\"text-center number-column\">{{ col.label }}</th>\n }\n @else {\n <th>{{ col.label }}</th>\n }\n }\n }\n @if (hasAnyActions()) {\n <th class=\"table-actions-header\">\n <div class=\"actions-wrapper\">\n <span>Actions</span>\n @if (hasCrudCreate()) {\n <c80-icon button icon=\"add\" [disabled]=\"creating()\" title=\"Agregar\" [size]=\".6\" (iconClick)=\"startCreate()\"></c80-icon>\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of data(); track trackById(i, row); let i = $index) {\n <tr>\n @if (allowSelection() && data().length !== 0) {\n <td class=\"text-center selection-column\">\n <input type=\"checkbox\" [checked]=\"isItemSelected(row)\" (change)=\"toggleItemSelection(row)\" [attr.aria-label]=\"'Seleccionar fila ' + (i + 1)\" />\n </td>\n }\n @for (col of columns(); track col) {\n @if (isColumnVisibleForRow(col, row)) {\n @if (col.type === 'boolean') {\n <td class=\"text-center boolean-column\">\n @if (editing() === row['id'] && !col.readOnly) {\n <input type=\"checkbox\" [checked]=\"!!editRow()?.[col.accessor]\" (change)=\"onEditInput($event, col.accessor, col)\" [attr.aria-label]=\"col.label\" />\n }\n @else {\n @if (getCellValue(row, col.accessor) === true) {\n <c80-icon icon=\"check\" [size]=\".7\"></c80-icon>\n <br />\n }\n @else if (getCellValue(row, col.accessor) === false) {\n <c80-icon icon=\"cancel\" [size]=\".7\"></c80-icon>\n <br />\n }\n }\n </td>\n }\n @else if (col.type === 'number' || col.type === 'integer') {\n <td class=\"text-center number-column\">\n @if (editing() === row['id'] && !col.readOnly) {\n <input class=\"form-control form-control-sm\" type=\"number\" [value]=\"editRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" [min]=\"col.min\" [max]=\"col.max\" [step]=\"col.type === 'integer' ? '1' : 'any'\"\n (input)=\"onEditInput($event, col.accessor, col)\" />\n }\n @else {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{ getDisplayValue(getCellValue(row,\n col.accessor), col) }}</span>\n }\n </td>\n }\n @else {\n <td>\n @if (editing() === row['id'] && !col.readOnly) {\n @if (col.type === 'enum') {\n <select class=\"form-control form-control-sm\" [value]=\"editRow()?.[col.accessor] ?? ''\" (change)=\"onEditInput($event, col.accessor, col)\">\n <option value=\"\">{{ col.label }}</option>\n @for (option of getEnumOptions(col); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <input class=\"form-control form-control-sm\" [type]=\"col.type === 'password' ? 'password' : 'text'\" [value]=\"editRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" (input)=\"onEditInput($event, col.accessor, col)\" />\n }\n }\n @else {\n @if (col.type === 'password') {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">******</span>\n }\n @else if (col.type === 'enum') {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{\n getEnumDisplayValue(getCellValue(row, col.accessor), col)\n }}</span>\n }\n @else if (getCellValue(row, col.accessor) === true) {\n <c80-icon icon=\"check\" [size]=\".7\"></c80-icon>\n }\n @else if (getCellValue(row, col.accessor) === false) {\n <c80-icon icon=\"cancel\" [size]=\".7\"></c80-icon>\n }\n @else {\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{ getDisplayValue(getCellValue(row,\n col.accessor), col) }}</span>\n }\n }\n </td>\n }\n }\n }\n @if (hasAnyActions()) {\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (editing() === row['id']) {\n <!-- Modo edici\u00F3n: mostrar guardar y cancelar -->\n @if (hasCrudUpdate()) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveEdit(row)\" [size]=\".7\"></c80-icon>\n }\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelEdit()\" [size]=\".7\"></c80-icon>\n }\n @else {\n @for (action of customActions(); track action.name) {\n @if (shouldShowAction(action, row)) {\n <c80-icon button [icon]=\"action.icon\" [customColor]=\"action.color\" [color]=\"action.name === 'delete' ? 'warn' : 'primary'\" [title]=\"getActionTooltip(action)\" (iconClick)=\"onDynamicAction(action, row)\" [size]=\".7\"></c80-icon>\n }\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n @if (creating() && hasCrudCreate()) {\n <tr>\n @if (allowSelection() && data().length !== 0) {\n <td class=\"text-center selection-column\">\n <!-- Empty cell for alignment -->\n </td>\n }\n @for (col of columns(); track col) {\n @if (isColumnVisible(col)) {\n @if (col.type === 'boolean') {\n <td class=\"text-center\">\n @if (!col.readOnly) {\n <input type=\"checkbox\" [checked]=\"!!newRow()?.[col.accessor]\" (change)=\"onInput($event, col.accessor, col)\" [attr.aria-label]=\"col.label\" />\n }\n @else {\n <!-- ReadOnly boolean column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n } @else if (col.type === 'number' || col.type === 'integer') {\n <td class=\"text-center number-column\">\n @if (!col.readOnly) {\n <input class=\"form-control form-control-sm\" type=\"number\" [value]=\"newRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" [min]=\"col.min\" [max]=\"col.max\" [step]=\"col.type === 'integer' ? '1' : 'any'\"\n (input)=\"onInput($event, col.accessor, col)\" />\n }\n @else {\n <!-- ReadOnly number column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n } @else {\n <td>\n @if (!col.readOnly) {\n @if (col.type === 'enum') {\n <select class=\"form-control form-control-sm\" [value]=\"newRow()?.[col.accessor] ?? ''\" (change)=\"onInput($event, col.accessor, col)\">\n <option value=\"\">{{ col.label }}</option>\n @for (option of getEnumOptions(col); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <input class=\"form-control form-control-sm\" type=\"text\" [value]=\"newRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" (input)=\"onInput($event, col.accessor, col)\" />\n }\n }\n @else {\n <!-- ReadOnly column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n }\n }\n }\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (hasCrudCreate()) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveCreate()\" [size]=\".7\"></c80-icon>\n }\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelCreate()\" [size]=\".7\"></c80-icon>\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n @if (data().length === 0 && !creating()) {\n <div class=\"text-center text-muted py-3 small\">\n No hay datos para mostrar.\n </div>\n }\n</div>\n\n<c80-modal></c80-modal>", styles: ["@charset \"UTF-8\";input[type=checkbox]{width:1.3rem!important;height:1.3rem!important;accent-color:rgba(226,0,0,.7647058824);background:#fff;margin:0 .25rem;vertical-align:middle;cursor:pointer}.table-responsive{width:100%;overflow-x:auto}.table-responsive .search-container{margin-bottom:-.06rem}.table-responsive .search-container .search-input-wrapper .input-group .btn-borrar{border-bottom-right-radius:0;border-color:#dee2e6}.table-responsive .search-container .search-input-wrapper .input-group .input-group-text{background-color:#f8f9fa;border-color:#dee2e6;border-bottom-left-radius:0;color:#495057;width:56px}.table-responsive .search-container .search-input-wrapper .input-group .input-group-text c80-icon{display:flex;align-items:center;justify-content:center;padding-bottom:.2rem}.table-responsive .search-container .search-input-wrapper .input-group .search-input{border-color:#dee2e6;border-bottom-right-radius:0;font-size:.95rem;outline:none!important}.table-responsive .search-container .search-input-wrapper .input-group .search-input:focus{outline:none!important}.table-responsive .search-container .search-input-wrapper .input-group .search-input::placeholder{color:#999;font-style:italic}.table-responsive .table{min-width:0px;margin-bottom:.5rem}.table-responsive .table .sticky-header{position:sticky;top:0;z-index:10;background-color:#f8f9fa!important}.table-responsive .table .sticky-header .table-actions-header{display:table-cell;vertical-align:middle;padding:.2rem .6rem!important;background-color:#f8f9fa!important}.table-responsive .table .sticky-header .actions-wrapper{display:flex;align-items:center;justify-content:center;gap:.5rem;height:100%}.table-responsive .table .sticky-header th{max-height:31px!important;vertical-align:middle!important;padding:.2rem .6rem!important;font-size:small!important;background-color:#f8f9fa!important;border-bottom:2px solid #dee2e6}.table-responsive .table tbody td{height:35px!important;min-height:35px!important;max-height:35px!important;vertical-align:middle!important;padding:.2rem .8rem!important;font-size:small}.table-responsive .table tbody tr{height:35px!important;min-height:35px!important;max-height:35px!important;cursor:pointer}.table-responsive .table tbody tr:hover{background-color:#f5f5f5}.table-responsive .table tbody input{border:1px solid rgba(34,0,255,.37);height:100%!important;font-size:smaller!important}.table-responsive .table tbody input[type=text],.table-responsive .table tbody input:not([type]){width:100%!important}.table-responsive .table tbody input[type=number]{min-width:80px!important;width:80px!important;text-align:center}.table-responsive .table thead th.boolean-column,.table-responsive .table tbody td.boolean-column,.table-responsive .table thead th.selection-column,.table-responsive .table tbody td.selection-column,.table-responsive .table thead th.table-actions-header,.table-responsive .table tbody td.table-actions-header{width:1%;white-space:nowrap}.table-responsive .table thead th.number-column,.table-responsive .table tbody td.number-column{width:1%;white-space:nowrap;text-align:center}.table-responsive .table thead th.number-column input[type=number],.table-responsive .table tbody td.number-column input[type=number]{min-width:80px!important;width:80px!important;text-align:center}.table-responsive .table .actions-cell{white-space:nowrap;padding:0!important}.table-responsive .table .actions-container{display:flex;flex-direction:row;justify-content:center;align-items:center;width:100%;height:100%}\n"] }]
|
|
427
|
+
args: [{ selector: 'c80-table', standalone: true, imports: [C80IconComponent, C80ModalComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n<div class=\"table-responsive\" [style.max-height]=\"tableMaxHeight()\" [style.overflow-y]=\"size() > 0 ? 'auto' : 'visible'\">\n <!-- Search Bar -->\n @if (searchable()) {\n <div class=\"search-container\">\n <div class=\"search-input-wrapper\">\n <div class=\"input-group\">\n <span class=\"input-group-text\">\n <c80-icon icon=\"search\" [size]=\".65\" [button]=\"false\" color=\"dark\" />\n </span>\n <input type=\"text\" class=\"form-control search-input\" placeholder=\"Buscar...\" [value]=\"searchValue()\" (input)=\"onSearchInput($event)\" aria-label=\"Buscar en la tabla\" />\n @if (searchValue()) {\n <button class=\"btn btn-outline-secondary btn-borrar\" type=\"button\" (click)=\"clearSearch()\" title=\"Limpiar b\u00FAsqueda\">\n <c80-icon icon=\"cancel\" [size]=\".6\" color=\"dark\" />\n </button>\n }\n </div>\n </div>\n </div>\n }\n\n <table class=\"table table-bordered table-hover align-middle\">\n <thead class=\"thead table-light sticky-header\">\n <tr>\n @if (allowSelection() && data().length !== 0) {\n <th class=\"text-center selection-column\">\n @if (multiple()) {\n <input type=\"checkbox\" [checked]=\"selectAllChecked()\" [indeterminate]=\"selectAllIndeterminate()\" (change)=\"toggleSelectAll()\" aria-label=\"Seleccionar todo\" />\n }\n </th>\n }\n @for (col of columns(); track col) {\n @if (isColumnVisibleInHeader(col)) {\n @if (col.type === 'boolean') {\n <th class=\"text-center boolean-column\">{{ col.label }}</th>\n }\n @else if (col.type === 'number' || col.type === 'integer') {\n <th class=\"text-center number-column\">{{ col.label }}</th>\n }\n @else {\n <th>{{ col.label }}</th>\n }\n }\n }\n @if (hasAnyActions()) {\n <th class=\"table-actions-header\">\n <div class=\"actions-wrapper\">\n <span>Actions</span>\n @if (hasCrudCreate()) {\n <c80-icon button icon=\"add\" [disabled]=\"creating()\" title=\"Agregar\" [size]=\".6\" (iconClick)=\"startCreate()\" color=\"dark\" />\n }\n </div>\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of data(); track trackById(i, row); let i = $index) {\n <tr>\n @if (allowSelection() && data().length !== 0) {\n <td class=\"text-center selection-column\">\n <input type=\"checkbox\" [checked]=\"isItemSelected(row)\" (change)=\"toggleItemSelection(row)\" [attr.aria-label]=\"'Seleccionar fila ' + (i + 1)\" />\n </td>\n }\n @for (col of columns(); track col) {\n @if (isColumnVisibleForRow(col, row)) {\n @if (col.type === 'boolean') {\n <td class=\"text-center boolean-column\">\n @if (editing() === row['id'] && !col.readOnly) {\n <input type=\"checkbox\" [checked]=\"!!editRow()?.[col.accessor]\" (change)=\"onEditInput($event, col.accessor, col)\" [attr.aria-label]=\"col.label\" />\n }\n @else {\n @if (getCellValue(row, col.accessor) === true) {\n <c80-icon icon=\"check\" [size]=\".7\" color=\"dark\" />\n <br />\n }\n @else if (getCellValue(row, col.accessor) === false) {\n <c80-icon icon=\"cancel\" [size]=\".7\" color=\"dark\" />\n <br />\n }\n }\n </td>\n }\n @else if (col.type === 'number' || col.type === 'integer') {\n <td class=\"text-center number-column\">\n @if (editing() === row['id'] && !col.readOnly) {\n <input class=\"form-control form-control-sm\" type=\"number\" [value]=\"editRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" [min]=\"col.min\" [max]=\"col.max\" [step]=\"col.type === 'integer' ? '1' : 'any'\"\n (input)=\"onEditInput($event, col.accessor, col)\" />\n }\n @else {\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{ getDisplayValue(getCellValue(row,\n col.accessor), col) }}</span>\n }\n </td>\n }\n @else {\n <td>\n @if (editing() === row['id'] && !col.readOnly) {\n @if (col.type === 'enum') {\n <select class=\"form-control form-control-sm\" [value]=\"editRow()?.[col.accessor] ?? ''\" (change)=\"onEditInput($event, col.accessor, col)\">\n <option value=\"\">{{ col.label }}</option>\n @for (option of getEnumOptions(col); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <input class=\"form-control form-control-sm\" [type]=\"col.type === 'password' ? 'password' : 'text'\" [value]=\"editRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" (input)=\"onEditInput($event, col.accessor, col)\" />\n }\n }\n @else {\n @if (col.type === 'password') {\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">******</span>\n }\n @else if (col.type === 'enum') {\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{\n getEnumDisplayValue(getCellValue(row, col.accessor), col)\n }}</span>\n }\n @else if (getCellValue(row, col.accessor) === true) {\n <c80-icon icon=\"check\" [size]=\".7\" color=\"dark\" />\n }\n @else if (getCellValue(row, col.accessor) === false) {\n <c80-icon icon=\"cancel\" [size]=\".7\" color=\"dark\" />\n }\n @else {\n <!-- eslint-disable-next-line @angular-eslint/template/no-inline-styles -->\n <span [style.color]=\"getCellColor(getCellValue(row, col.accessor), col)\">{{ getDisplayValue(getCellValue(row,\n col.accessor), col) }}</span>\n }\n }\n </td>\n }\n }\n }\n @if (hasAnyActions()) {\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (editing() === row['id']) {\n <!-- Modo edici\u00F3n: mostrar guardar y cancelar -->\n @if (hasCrudUpdate()) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveEdit(row)\" [size]=\".7\" color=\"dark\" />\n }\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelEdit()\" [size]=\".7\" />\n }\n @else {\n @for (action of customActions(); track action.name) {\n @if (shouldShowAction(action, row)) {\n <c80-icon button [icon]=\"action.icon\" [customColor]=\"getActionColor(action)\" [color]=\"action.name === 'delete' ? 'warn' : 'primary'\" [title]=\"getActionTooltip(action)\" (iconClick)=\"onDynamicAction(action, row)\" [size]=\".7\" />\n }\n }\n }\n </div>\n </td>\n }\n </tr>\n }\n @if (creating() && hasCrudCreate()) {\n <tr>\n @if (allowSelection() && data().length !== 0) {\n <td class=\"text-center selection-column\">\n <!-- Empty cell for alignment -->\n </td>\n }\n @for (col of columns(); track col) {\n @if (isColumnVisible(col)) {\n @if (col.type === 'boolean') {\n <td class=\"text-center\">\n @if (!col.readOnly) {\n <input type=\"checkbox\" [checked]=\"!!newRow()?.[col.accessor]\" (change)=\"onInput($event, col.accessor, col)\" [attr.aria-label]=\"col.label\" />\n }\n @else {\n <!-- ReadOnly boolean column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n } @else if (col.type === 'number' || col.type === 'integer') {\n <td class=\"text-center number-column\">\n @if (!col.readOnly) {\n <input class=\"form-control form-control-sm\" type=\"number\" [value]=\"newRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" [min]=\"col.min\" [max]=\"col.max\" [step]=\"col.type === 'integer' ? '1' : 'any'\"\n (input)=\"onInput($event, col.accessor, col)\" />\n }\n @else {\n <!-- ReadOnly number column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n } @else {\n <td>\n @if (!col.readOnly) {\n @if (col.type === 'enum') {\n <select class=\"form-control form-control-sm\" [value]=\"newRow()?.[col.accessor] ?? ''\" (change)=\"onInput($event, col.accessor, col)\">\n <option value=\"\">{{ col.label }}</option>\n @for (option of getEnumOptions(col); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </select>\n }\n @else {\n <input class=\"form-control form-control-sm\" type=\"text\" [value]=\"newRow()?.[col.accessor] ?? ''\" [placeholder]=\"col.label\" (input)=\"onInput($event, col.accessor, col)\" />\n }\n }\n @else {\n <!-- ReadOnly column in create mode shows empty -->\n <span class=\"text-muted\">-</span>\n }\n </td>\n }\n }\n }\n <td class=\"text-center actions-cell\">\n <div class=\"actions-container\">\n @if (hasCrudCreate()) {\n <c80-icon button icon=\"check\" title=\"Guardar\" (iconClick)=\"saveCreate()\" [size]=\".7\" color=\"dark\" />\n }\n <c80-icon button icon=\"cancel\" color=\"warn\" title=\"Cancelar\" (iconClick)=\"cancelCreate()\" [size]=\".7\" />\n </div>\n </td>\n </tr>\n }\n </tbody>\n </table>\n @if (data().length === 0 && !creating()) {\n <div class=\"text-center text-muted py-3 small\">\n No hay datos para mostrar.\n </div>\n }\n</div>\n\n<c80-modal />", styles: ["@charset \"UTF-8\";input[type=checkbox]{width:1.3rem!important;height:1.3rem!important;accent-color:var(--color-icon-danger);background:var(--color-bg-primary);margin:0 .25rem;vertical-align:middle;cursor:pointer}.table-responsive{width:100%;overflow-x:auto}.table-responsive .search-container{margin-bottom:-.06rem}.table-responsive .search-container .search-input-wrapper .input-group .btn-borrar{border-bottom-right-radius:0;border-color:var(--color-border-default);height:32px}.table-responsive .search-container .search-input-wrapper .input-group .input-group-text{background-color:var(--color-bg-secondary);border-color:var(--color-border-default);border-bottom-left-radius:0;color:var(--color-text-secondary);width:56.1px;height:32px;padding:.25rem .5rem}.table-responsive .search-container .search-input-wrapper .input-group .input-group-text c80-icon{display:flex;align-items:center;justify-content:center}.table-responsive .search-container .search-input-wrapper .input-group .search-input{border-color:var(--color-border-default);border-bottom-right-radius:0;font-size:.75rem;height:32px;padding:.25rem .5rem;outline:none!important;background-color:var(--color-bg-primary);color:var(--color-text-primary)}.table-responsive .search-container .search-input-wrapper .input-group .search-input:focus{outline:none!important}.table-responsive .search-container .search-input-wrapper .input-group .search-input::placeholder{color:var(--color-text-muted);font-style:italic}.table-responsive .table{min-width:0px;margin-bottom:.5rem;background-color:var(--color-bg-primary);color:var(--color-text-primary);border-color:var(--color-border-default)}.table-responsive .table.table-bordered,.table-responsive .table.table-bordered th,.table-responsive .table.table-bordered td{border-color:var(--color-border-default)}.table-responsive .table.table-hover tbody tr:hover{background-color:var(--color-bg-hover)!important;color:var(--color-text-primary)}.table-responsive .table.table-hover tbody tr:hover td{background-color:var(--color-bg-hover)}.table-responsive .table .sticky-header{position:sticky;top:0;z-index:10;background-color:var(--color-bg-secondary)!important}.table-responsive .table .sticky-header .table-actions-header{display:table-cell;vertical-align:middle;padding:.2rem .6rem!important;background-color:var(--color-bg-secondary)!important}.table-responsive .table .sticky-header .actions-wrapper{display:flex;align-items:center;justify-content:center;gap:.5rem;height:100%}.table-responsive .table .sticky-header th{max-height:31px!important;vertical-align:middle!important;padding:.2rem .6rem!important;font-size:small!important;background-color:var(--color-bg-secondary)!important;border-bottom:2px solid var(--color-border-default);color:var(--color-text-primary)}.table-responsive .table tbody{background-color:var(--color-bg-primary)}.table-responsive .table tbody td{height:35px!important;min-height:35px!important;max-height:35px!important;vertical-align:middle!important;padding:.2rem .8rem!important;font-size:small;color:var(--color-text-primary);background-color:var(--color-bg-primary);border-color:var(--color-border-default)}.table-responsive .table tbody tr{height:35px!important;min-height:35px!important;max-height:35px!important;cursor:pointer;background-color:var(--color-bg-primary)}.table-responsive .table tbody tr:hover{background-color:var(--color-bg-hover)!important}.table-responsive .table tbody tr:hover td{background-color:var(--color-bg-hover)}.table-responsive .table tbody .text-muted{color:var(--color-text-muted)!important}.table-responsive .table tbody input,.table-responsive .table tbody select{border:1px solid var(--color-border-default);height:100%!important;font-size:smaller!important;background-color:var(--color-bg-primary);color:var(--color-text-primary)}.table-responsive .table tbody input:focus,.table-responsive .table tbody select:focus{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus)}.table-responsive .table tbody input::placeholder,.table-responsive .table tbody select::placeholder{color:var(--color-text-muted)}.table-responsive .table tbody input[type=text],.table-responsive .table tbody input:not([type]){width:100%!important}.table-responsive .table tbody input[type=number]{min-width:80px!important;width:80px!important;text-align:center}.table-responsive .table tbody select{width:100%!important;padding:.25rem .5rem}.table-responsive .table thead th.boolean-column,.table-responsive .table tbody td.boolean-column,.table-responsive .table thead th.selection-column,.table-responsive .table tbody td.selection-column,.table-responsive .table thead th.table-actions-header,.table-responsive .table tbody td.table-actions-header{width:1%;white-space:nowrap}.table-responsive .table thead th.number-column,.table-responsive .table tbody td.number-column{width:1%;white-space:nowrap;text-align:center}.table-responsive .table thead th.number-column input[type=number],.table-responsive .table tbody td.number-column input[type=number]{min-width:80px!important;width:80px!important;text-align:center}.table-responsive .table .actions-cell{white-space:nowrap;padding:0!important}.table-responsive .table .actions-container{display:flex;flex-direction:row;justify-content:center;align-items:center;width:100%;height:100%}.table-responsive .text-center.text-muted{color:var(--color-text-muted)!important}.table-responsive .btn-outline-secondary{background-color:var(--color-bg-primary);color:var(--color-text-primary);border-color:var(--color-border-default)}.table-responsive .btn-outline-secondary:hover{background-color:var(--color-bg-hover);border-color:var(--color-border-medium)}.table-responsive .btn-outline-secondary:focus{box-shadow:var(--shadow-focus)}\n"] }]
|
|
412
428
|
}], propDecorators: { data$: [{ type: i0.Input, args: [{ isSignal: true, alias: "data$", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], inputValues$: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputValues$", required: false }] }], customActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "customActions", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], allowSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowSelection", required: false }] }], noConfirm: [{ type: i0.Input, args: [{ isSignal: true, alias: "noConfirm", required: false }] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }], searchTerm: [{ type: i0.Output, args: ["searchTerm"] }], errorEvent: [{ type: i0.Output, args: ["errorEvent"] }], selectable: [{ type: i0.Output, args: ["selectable"] }] } });
|
|
413
429
|
//# sourceMappingURL=table.component.js.map
|