@solcre-org/core-ui 2.11.13 → 2.11.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7215,6 +7215,7 @@ class GenericTableComponent {
7215
7215
  fileUploadConfig = input(undefined);
7216
7216
  rowStyleConfigs = input([]);
7217
7217
  columnDisabledConfigs = input([]);
7218
+ rowVisibilityConfigs = input([]);
7218
7219
  headerOrder = input(undefined);
7219
7220
  showActiveFilters = input(false);
7220
7221
  activeFiltersConfig = input({});
@@ -7360,7 +7361,8 @@ class GenericTableComponent {
7360
7361
  if (this.currentSortColumn() === null && this.currentSortDirection() === null) {
7361
7362
  this.originalUnsortedData.set([...inputData]);
7362
7363
  }
7363
- this.displayedData.set([...inputData]);
7364
+ const visibleData = this.applyRowVisibilityFilter(inputData);
7365
+ this.displayedData.set([...visibleData]);
7364
7366
  this.loadingStates.mainData = false;
7365
7367
  this.loadingStates.filterData = false;
7366
7368
  this.checkAndHideLoader();
@@ -7506,11 +7508,12 @@ class GenericTableComponent {
7506
7508
  if (this.currentSortColumn() === null && this.currentSortDirection() === null) {
7507
7509
  this.originalUnsortedData.set([...data]);
7508
7510
  }
7511
+ const visibleData = this.applyRowVisibilityFilter(data);
7509
7512
  if (this.endpoint() && this.endpoint() !== '') {
7510
- this.displayedData.set([...data]);
7513
+ this.displayedData.set([...visibleData]);
7511
7514
  }
7512
7515
  else {
7513
- this.tableDataService.updateDisplayedData(data, this.enablePagination(), this.paginationService, this.tableId, this.itemsLoaded());
7516
+ this.tableDataService.updateDisplayedData(visibleData, this.enablePagination(), this.paginationService, this.tableId, this.itemsLoaded());
7514
7517
  const displayed = this.tableDataService.getDisplayedData();
7515
7518
  this.displayedData.set([...displayed]);
7516
7519
  }
@@ -7525,11 +7528,15 @@ class GenericTableComponent {
7525
7528
  }
7526
7529
  applyCustomFilters(filterValues) {
7527
7530
  this.filterService.setCustomFilters(filterValues);
7531
+ this.currentFilterValues.set(new Map(filterValues));
7528
7532
  if (this.endpoint()) {
7529
7533
  const transformedFilters = this.transformFiltersForPayload(filterValues);
7530
7534
  this.startLoaderTimeout(this.FILTER_LOADER_ID);
7531
7535
  this.tableDataService.updateFilters(transformedFilters, this.FILTER_LOADER_ID);
7532
7536
  }
7537
+ else {
7538
+ this.updateDisplayedDataFromServer(this.filterService.getFilteredData());
7539
+ }
7533
7540
  }
7534
7541
  sortData(column) {
7535
7542
  if (column.sortable === false)
@@ -7882,11 +7889,15 @@ class GenericTableComponent {
7882
7889
  handleFilterChange(filterValues) {
7883
7890
  this.onFilterChange.emit(filterValues);
7884
7891
  this.filterService.setCustomFilters(filterValues);
7892
+ this.currentFilterValues.set(new Map(filterValues));
7885
7893
  if (this.endpoint()) {
7886
7894
  const transformedFilters = this.transformFiltersForPayload(filterValues);
7887
7895
  this.startLoaderTimeout(this.FILTER_LOADER_ID);
7888
7896
  this.tableDataService.updateFilters(transformedFilters, this.FILTER_LOADER_ID);
7889
7897
  }
7898
+ else {
7899
+ this.updateDisplayedDataFromServer(this.filterService.getFilteredData());
7900
+ }
7890
7901
  }
7891
7902
  transformFiltersForPayload(filterValues) {
7892
7903
  const transformedFilters = new Map();
@@ -7899,11 +7910,16 @@ class GenericTableComponent {
7899
7910
  }
7900
7911
  handleClearFilters() {
7901
7912
  this.filterService.setCustomFilters(new Map());
7913
+ this.currentFilterValues.set(new Map());
7902
7914
  if (this.endpoint()) {
7903
7915
  this.startLoaderTimeout(this.FILTER_LOADER_ID);
7904
7916
  this.tableDataService.updateFilters(new Map(), this.FILTER_LOADER_ID);
7905
7917
  this.onClearFilters.emit();
7906
7918
  }
7919
+ else {
7920
+ this.updateDisplayedDataFromServer(this.filterService.getFilteredData());
7921
+ this.onClearFilters.emit();
7922
+ }
7907
7923
  }
7908
7924
  toggleSubmenu(rowId, event) {
7909
7925
  event.stopPropagation();
@@ -8005,6 +8021,32 @@ class GenericTableComponent {
8005
8021
  }
8006
8022
  return classes.join(' ');
8007
8023
  }
8024
+ isRowVisible(row) {
8025
+ const visibilityConfigs = this.rowVisibilityConfigs();
8026
+ if (!visibilityConfigs || visibilityConfigs.length === 0) {
8027
+ return true;
8028
+ }
8029
+ const activeFilters = this.currentFilterValues();
8030
+ const applicableConfigs = visibilityConfigs
8031
+ .filter(config => config.hideCondition(row))
8032
+ .sort((a, b) => (b.priority || 0) - (a.priority || 0));
8033
+ if (applicableConfigs.length === 0) {
8034
+ return true;
8035
+ }
8036
+ for (const config of applicableConfigs) {
8037
+ if (config.showWhenFiltered && config.showWhenFiltered(row, activeFilters)) {
8038
+ return true;
8039
+ }
8040
+ }
8041
+ return false;
8042
+ }
8043
+ applyRowVisibilityFilter(data) {
8044
+ const visibilityConfigs = this.rowVisibilityConfigs();
8045
+ if (!visibilityConfigs || visibilityConfigs.length === 0) {
8046
+ return data;
8047
+ }
8048
+ return data.filter(row => this.isRowVisible(row));
8049
+ }
8008
8050
  generateActiveFilters() {
8009
8051
  const activeFilters = [];
8010
8052
  const currentFilters = this.currentFilterValues();
@@ -8405,7 +8447,7 @@ class GenericTableComponent {
8405
8447
  this.tableDataService.updateRowData(rowId, updatedFields, updateFunction);
8406
8448
  }
8407
8449
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: GenericTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8408
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: GenericTableComponent, isStandalone: true, selector: "core-generic-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, modalFields: { classPropertyName: "modalFields", publicName: "modalFields", isSignal: true, isRequired: false, transformFunction: null }, modalTabs: { classPropertyName: "modalTabs", publicName: "modalTabs", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: true, transformFunction: null }, customActions: { classPropertyName: "customActions", publicName: "customActions", isSignal: true, isRequired: false, transformFunction: null }, globalActions: { classPropertyName: "globalActions", publicName: "globalActions", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, showFilter: { classPropertyName: "showFilter", publicName: "showFilter", isSignal: true, isRequired: false, transformFunction: null }, showSelection: { classPropertyName: "showSelection", publicName: "showSelection", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null }, showCreateButton: { classPropertyName: "showCreateButton", publicName: "showCreateButton", isSignal: true, isRequired: false, transformFunction: null }, filterButtonConfig: { classPropertyName: "filterButtonConfig", publicName: "filterButtonConfig", isSignal: true, isRequired: false, transformFunction: null }, createButtonConfig: { classPropertyName: "createButtonConfig", publicName: "createButtonConfig", isSignal: true, isRequired: false, transformFunction: null }, dataInput: { classPropertyName: "dataInput", publicName: "dataInput", isSignal: true, isRequired: false, transformFunction: null }, customFilters: { classPropertyName: "customFilters", publicName: "customFilters", isSignal: true, isRequired: false, transformFunction: null }, enablePagination: { classPropertyName: "enablePagination", publicName: "enablePagination", isSignal: true, isRequired: false, transformFunction: null }, modelFactory: { classPropertyName: "modelFactory", publicName: "modelFactory", isSignal: true, isRequired: false, transformFunction: null }, endpoint: { classPropertyName: "endpoint", publicName: "endpoint", isSignal: true, isRequired: false, transformFunction: null }, customParams: { classPropertyName: "customParams", publicName: "customParams", isSignal: true, isRequired: false, transformFunction: null }, customArrayKey: { classPropertyName: "customArrayKey", publicName: "customArrayKey", isSignal: true, isRequired: false, transformFunction: null }, listTitle: { classPropertyName: "listTitle", publicName: "listTitle", isSignal: true, isRequired: false, transformFunction: null }, moreData: { classPropertyName: "moreData", publicName: "moreData", isSignal: true, isRequired: false, transformFunction: null }, inModal: { classPropertyName: "inModal", publicName: "inModal", isSignal: true, isRequired: false, transformFunction: null }, expansionConfig: { classPropertyName: "expansionConfig", publicName: "expansionConfig", isSignal: true, isRequired: false, transformFunction: null }, fileUploadConfig: { classPropertyName: "fileUploadConfig", publicName: "fileUploadConfig", isSignal: true, isRequired: false, transformFunction: null }, rowStyleConfigs: { classPropertyName: "rowStyleConfigs", publicName: "rowStyleConfigs", isSignal: true, isRequired: false, transformFunction: null }, columnDisabledConfigs: { classPropertyName: "columnDisabledConfigs", publicName: "columnDisabledConfigs", isSignal: true, isRequired: false, transformFunction: null }, headerOrder: { classPropertyName: "headerOrder", publicName: "headerOrder", isSignal: true, isRequired: false, transformFunction: null }, showActiveFilters: { classPropertyName: "showActiveFilters", publicName: "showActiveFilters", isSignal: true, isRequired: false, transformFunction: null }, activeFiltersConfig: { classPropertyName: "activeFiltersConfig", publicName: "activeFiltersConfig", isSignal: true, isRequired: false, transformFunction: null }, customEdit: { classPropertyName: "customEdit", publicName: "customEdit", isSignal: true, isRequired: false, transformFunction: null }, customDelete: { classPropertyName: "customDelete", publicName: "customDelete", isSignal: true, isRequired: false, transformFunction: null }, customView: { classPropertyName: "customView", publicName: "customView", isSignal: true, isRequired: false, transformFunction: null }, customSave: { classPropertyName: "customSave", publicName: "customSave", isSignal: true, isRequired: false, transformFunction: null }, useCustomSave: { classPropertyName: "useCustomSave", publicName: "useCustomSave", isSignal: true, isRequired: false, transformFunction: null }, onApiError: { classPropertyName: "onApiError", publicName: "onApiError", isSignal: true, isRequired: false, transformFunction: null }, inlineEditConfig: { classPropertyName: "inlineEditConfig", publicName: "inlineEditConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionTriggered: "actionTriggered", selectionChanged: "selectionChanged", dataCreated: "dataCreated", dataUpdated: "dataUpdated", dataDeleted: "dataDeleted", onMoreDataLoaded: "onMoreDataLoaded", globalActionTriggered: "globalActionTriggered", modalData: "modalData", beforeSave: "beforeSave", onFilterChange: "onFilterChange", onClearFilters: "onClearFilters", activeFilterRemoved: "activeFilterRemoved", activeFiltersCleared: "activeFiltersCleared", inlineEditSave: "inlineEditSave", inlineEditModeChanged: "inlineEditModeChanged", inlineEditValidationError: "inlineEditValidationError" }, host: { listeners: { "document:click": "closeSubmenu()" } }, providers: [TableDataService, FilterService, PaginationService, ModelApiService, InlineEditService], viewQueries: [{ propertyName: "sentinel", first: true, predicate: ["sentinel"], descendants: true }, { propertyName: "dropdownTrigger", first: true, predicate: ["dropdownTrigger"], descendants: true }, { propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true }], hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "@if (showActiveFilters()) {\n <core-active-filters\n [activeFilters]=\"currentActiveFilters()\"\n [config]=\"activeFiltersConfig()\"\n (onFilterRemove)=\"onActiveFilterRemove($event)\"\n (onClearAll)=\"onActiveFiltersClear()\">\n </core-active-filters>\n}\n\n<div class=\"c-table\" [class.in-modal]=\"inModal()\" [class.inline-edit-mode]=\"inlineEditService.isInlineEditMode()\">\n <table>\n <thead>\n <tr>\n @if (showSelection()) {\n <!-- Todo: Tabla con row selection -->\n <th class=\"select-column\">\n <input type=\"checkbox\" [checked]=\"isAllSelected()\" (change)=\"masterToggle()\" />\n </th>\n }\n @for (column of columns(); track $index) {\n <th [ngClass]=\"column.align ? 'u-align-' + column.align : ''\">\n @if (column.sortable !== false) {\n <!-- \u2705 Solcre: Agregado [title] din\u00E1mico y capacidad de volver al estado sin selecci\u00F3n -->\n <button class=\"c-table-order\" tabindex=\"-1\"\n [class.is-asc]=\"currentSortColumn() === column.key && currentSortDirection() === 'asc'\"\n [class.is-desc]=\"currentSortColumn() === column.key && currentSortDirection() === 'desc'\"\n [title]=\"getSortTitle(column) | translate\" (click)=\"sortData(column)\">\n {{ column.label | translate }}\n <span class=\"c-table-order__controls\">\n <span class=\"c-table-order__arrow--desc icon-arrow-up\"></span>\n <span class=\"c-table-order__arrow--asc icon-arrow-down\"></span>\n </span>\n </button>\n <!-- <button \n class=\"c-table__order\" \n [class.is-asc]=\"currentSortColumn() === column.key && currentSortDirection() === 'asc'\" \n [class.is-desc]=\"currentSortColumn() === column.key && currentSortDirection() === 'desc'\"\n (click)=\"sortData(column)\">\n {{ column.label | translate }}\n <span class=\"icon-order-arrow\"></span>\n </button> -->\n } @else {\n {{ column.label | translate }}\n }\n </th>\n }\n @if (showActions() && (actions().length > 0 || customActions().length > 0)) {\n <th class=\"u-align-right\">{{ 'table.actions' | translate }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of displayedData(); track row.getId()) {\n <tr [ngClass]=\"getRowClasses(row)\" \n [class.is-editing-inline]=\"isRowInEditMode(row.getId())\"\n [class.is-disabled]=\"isRowDisabled(row)\">\n @if (showSelection()) {\n <!-- Todo: Tabla con row selection -->\n <td class=\"select-column\">\n <input type=\"checkbox\" [checked]=\"isRowSelected(row)\" (change)=\"toggleRow(row)\" />\n </td>\n }\n @for (column of columns(); track $index) {\n <td [attr.data-label]=\"column.label | translate\" \n [ngClass]=\"[\n column.align ? 'u-align-' + column.align : '',\n getCellDisabledClasses(row, column)\n ]\" \n [class.is-editing]=\"isColumnEditable(column, row)\"\n [class.is-column-disabled]=\"isColumnDisabledForRow(row, column)\">\n @if (column.template) {\n <!-- Todo: Ver qu\u00E9 es esto -->\n <ng-container *ngTemplateOutlet=\"column.template; context: { $implicit: row, column: column }\"></ng-container>\n } @else if (isColumnEditable(column, row)) {\n <!-- !Solcre: Modo de edici\u00F3n en l\u00EDnea usando DynamicField -->\n <div class=\"c-table__inline-edit\">\n <strong class=\"c-table__mobile-heading\">{{ column.label | translate }}:</strong>\n <div\n coreDynamicField\n [field]=\"getInlineEditableConfigWithState(row, column)!\"\n [value]=\"getEditingValue(row, column)\"\n [mode]=\"ModalMode.EDIT\"\n [errors]=\"getCellErrors(row, column)\"\n [rowData]=\"row\"\n (valueChange)=\"onCellValueChange(row, column, $event)\"\n (onBlurEvent)=\"onCellBlur(row, column)\"\n (onEnterEvent)=\"onCellEnter(row, column)\"\n ></div>\n </div>\n } @else {\n <div class=\"c-table__content\">\n <strong class=\"c-table__mobile-heading\">{{ column.label | translate }}:</strong> {{ getFormattedValue(row,\n column) }}\n </div>\n }\n </td>\n }\n\n <!-- Actions-->\n\n @if (showActions() && (actions().length > 0 || customActions().length > 0 || expansionConfig()?.enabled)) {\n\n <td class=\"u-align-right\">\n <div class=\"c-table__actions\">\n\n @for (actionConfig of regularDefaultActions(); track actionConfig.action) {\n @if (hasPermission(actionConfig)) {\n @if (actionConfig.action === TableAction.VIEW || actionConfig.action === TableAction.EDIT ||\n actionConfig.action === TableAction.DELETE) {\n <core-generic-button [config]=\"getActionButtonConfig(actionConfig.action, actionConfig)\"\n (buttonClick)=\"onButtonClick($event, actionConfig.action, row)\">\n </core-generic-button>\n }\n }\n }\n @for (customAction of getVisibleCustomActions(row, false); track customAction.label || $index) {\n @if (hasPermission(customAction)) {\n <core-generic-button [config]=\"getCustomActionButtonConfigForRow(customAction, row)\"\n (buttonClick)=\"onButtonClick($event, customAction, row)\">\n </core-generic-button>\n }\n }\n\n @if (hasExtraActionsForRow(row)) {\n <core-generic-button [config]=\"getMoreActionsButtonConfig(row.getId())\" [data]=\"row\"\n (buttonClick)=\"onMoreActionsClick($event, row.getId())\" #dropdownTrigger>\n </core-generic-button>\n <core-dropdown [rowId]=\"row.getId()\" [extraDefaultActions]=\"extraDefaultActions()\"\n [extraCustomActions]=\"getVisibleCustomActions(row, true)\" [row]=\"row\"\n [triggerElementId]=\"'dropdown-trigger-' + row.getId()\"\n (actionTriggered)=\"triggerAction($event.action, $event.row)\"\n (customActionTriggered)=\"triggerCustomAction($event.action, $event.row)\" #dropdown>\n </core-dropdown>\n }\n\n @if (expansionConfig()?.enabled) {\n <!-- \u2705 Solcre: Celda dedicada para expansi\u00F3n en su posici\u00F3n correcta -->\n <core-generic-button [config]=\"getExpandButtonConfig(row)\" (buttonClick)=\"onExpandButtonClick($event, row)\">\n </core-generic-button>\n }\n\n </div> <!-- .c-table__actions -->\n </td> <!-- td parent of .c-table__actions -->\n } <!-- @if (showActions() -->\n\n\n </tr>\n @if (expansionConfig()?.enabled && isRowExpanded(row)) {\n <!-- Todo: Ver que es esto -->\n <tr class=\"expansion-row\" [ngClass]=\"getRowClasses(row)\">\n <td [attr.colspan]=\"displayedColumns().length\" class=\"expansion-content\">\n <ng-container *ngTemplateOutlet=\"expansionConfig()!.template; context: { $implicit: row }\">\n </ng-container>\n </td>\n </tr>\n }\n } @empty {\n <tr>\n <!-- Todo: Estilo .no-data -->\n <td [attr.colspan]=\"displayedColumns().length\">\n <p class=\"c-placeholder\">{{ 'table.noData' | translate }}</p>\n </td>\n </tr>\n }\n </tbody>\n </table>\n</div> <!-- .c-table -->\n\n<!-- Todo: Todo lo que viene dsp de la tabla -->\n\n@if (!enablePagination()) {\n<!-- Todo: Ver qu\u00E9 onda esto -->\n<div #sentinel class=\"sentinel\"></div>\n}\n\n@if (enablePagination()) {\n<!-- Todo: Ver qu\u00E9 onda esto -->\n<core-generic-pagination [tableId]=\"tableId\"></core-generic-pagination>\n}\n\n<core-generic-modal [isOpen]=\"tableActionService.getIsModalOpen()\" [mode]=\"tableActionService.getModalMode()\"\n [data]=\"tableActionService.getModalData()\" [fields]=\"hasTabs() ? [] : tableActionService.getModalFieldsToShow()\"\n [tabs]=\"hasTabs() ? modalTabs() : []\" [title]=\"tableActionService.getModalTitle()\" [modelFactory]=\"modelFactory() || null\"\n (save)=\"onModalSave($event)\" (close)=\"tableActionService.closeModal()\" (modalData)=\"onModalData($event)\">\n</core-generic-modal>\n\n<core-filter-modal [isOpen]=\"isFilterModalOpen()\" [filters]=\"customFilters()\" [currentFilterValues]=\"currentFilterValues()\" (close)=\"closeFiltersPopup()\"\n (filterChange)=\"handleFilterChange($event)\" (globalFilterChange)=\"applyGlobalFilter($event)\"\n (clearFilters)=\"handleClearFilters()\">\n</core-filter-modal>", styles: [".in-modal .c-table thead th:last-child,.c-table tbody td:last-child{text-align:left}.c-table__order-btn--asc{transform:rotate(180deg)}.c-table__order-btn--desc{transform:rotate(0)}.c-table tr.is-editing-inline{background-color:#fff3cd;border-left:3px solid #ffc107}.c-table tr.is-editing-inline td{background-color:#fff3cd}.c-table tr.is-editing-inline:hover td{background-color:#ffecb5}.expansion-row .expansion-content{padding:16px;background-color:#f8f9fa;border-top:1px solid #dee2e6}.expansion-row td{border-bottom:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "component", type: GenericModalComponent, selector: "core-generic-modal", inputs: ["isOpen", "mode", "data", "fields", "tabs", "title", "isMultiple", "customTemplate", "customViewTemplate", "buttonConfig", "modelFactory", "errors", "validators"], outputs: ["save", "close", "modalData"] }, { kind: "component", type: GenericPaginationComponent, selector: "core-generic-pagination", inputs: ["tableId", "isServerSide"] }, { kind: "component", type: DropdownComponent, selector: "core-dropdown", inputs: ["rowId", "triggerElementId", "extraDefaultActions", "extraCustomActions", "row"], outputs: ["actionTriggered", "customActionTriggered"] }, { kind: "component", type: FilterModalComponent, selector: "core-filter-modal", inputs: ["isOpen", "filters", "currentFilterValues"], outputs: ["close", "filterChange", "clearFilters", "globalFilterChange"] }, { kind: "component", type: GenericButtonComponent, selector: "core-generic-button", inputs: ["config", "data"], outputs: ["buttonClick"] }, { kind: "directive", type: DynamicFieldDirective, selector: "[coreDynamicField]", inputs: ["field", "value", "mode", "errors", "rowData", "formValue"], outputs: ["valueChange", "onBlurEvent", "onEnterEvent", "selectionChange"] }, { kind: "component", type: ActiveFiltersComponent, selector: "core-active-filters", inputs: ["activeFilters", "config"], outputs: ["onFilterRemove", "onClearAll"] }] });
8450
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: GenericTableComponent, isStandalone: true, selector: "core-generic-table", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, modalFields: { classPropertyName: "modalFields", publicName: "modalFields", isSignal: true, isRequired: false, transformFunction: null }, modalTabs: { classPropertyName: "modalTabs", publicName: "modalTabs", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: true, transformFunction: null }, customActions: { classPropertyName: "customActions", publicName: "customActions", isSignal: true, isRequired: false, transformFunction: null }, globalActions: { classPropertyName: "globalActions", publicName: "globalActions", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, showFilter: { classPropertyName: "showFilter", publicName: "showFilter", isSignal: true, isRequired: false, transformFunction: null }, showSelection: { classPropertyName: "showSelection", publicName: "showSelection", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null }, showCreateButton: { classPropertyName: "showCreateButton", publicName: "showCreateButton", isSignal: true, isRequired: false, transformFunction: null }, filterButtonConfig: { classPropertyName: "filterButtonConfig", publicName: "filterButtonConfig", isSignal: true, isRequired: false, transformFunction: null }, createButtonConfig: { classPropertyName: "createButtonConfig", publicName: "createButtonConfig", isSignal: true, isRequired: false, transformFunction: null }, dataInput: { classPropertyName: "dataInput", publicName: "dataInput", isSignal: true, isRequired: false, transformFunction: null }, customFilters: { classPropertyName: "customFilters", publicName: "customFilters", isSignal: true, isRequired: false, transformFunction: null }, enablePagination: { classPropertyName: "enablePagination", publicName: "enablePagination", isSignal: true, isRequired: false, transformFunction: null }, modelFactory: { classPropertyName: "modelFactory", publicName: "modelFactory", isSignal: true, isRequired: false, transformFunction: null }, endpoint: { classPropertyName: "endpoint", publicName: "endpoint", isSignal: true, isRequired: false, transformFunction: null }, customParams: { classPropertyName: "customParams", publicName: "customParams", isSignal: true, isRequired: false, transformFunction: null }, customArrayKey: { classPropertyName: "customArrayKey", publicName: "customArrayKey", isSignal: true, isRequired: false, transformFunction: null }, listTitle: { classPropertyName: "listTitle", publicName: "listTitle", isSignal: true, isRequired: false, transformFunction: null }, moreData: { classPropertyName: "moreData", publicName: "moreData", isSignal: true, isRequired: false, transformFunction: null }, inModal: { classPropertyName: "inModal", publicName: "inModal", isSignal: true, isRequired: false, transformFunction: null }, expansionConfig: { classPropertyName: "expansionConfig", publicName: "expansionConfig", isSignal: true, isRequired: false, transformFunction: null }, fileUploadConfig: { classPropertyName: "fileUploadConfig", publicName: "fileUploadConfig", isSignal: true, isRequired: false, transformFunction: null }, rowStyleConfigs: { classPropertyName: "rowStyleConfigs", publicName: "rowStyleConfigs", isSignal: true, isRequired: false, transformFunction: null }, columnDisabledConfigs: { classPropertyName: "columnDisabledConfigs", publicName: "columnDisabledConfigs", isSignal: true, isRequired: false, transformFunction: null }, rowVisibilityConfigs: { classPropertyName: "rowVisibilityConfigs", publicName: "rowVisibilityConfigs", isSignal: true, isRequired: false, transformFunction: null }, headerOrder: { classPropertyName: "headerOrder", publicName: "headerOrder", isSignal: true, isRequired: false, transformFunction: null }, showActiveFilters: { classPropertyName: "showActiveFilters", publicName: "showActiveFilters", isSignal: true, isRequired: false, transformFunction: null }, activeFiltersConfig: { classPropertyName: "activeFiltersConfig", publicName: "activeFiltersConfig", isSignal: true, isRequired: false, transformFunction: null }, customEdit: { classPropertyName: "customEdit", publicName: "customEdit", isSignal: true, isRequired: false, transformFunction: null }, customDelete: { classPropertyName: "customDelete", publicName: "customDelete", isSignal: true, isRequired: false, transformFunction: null }, customView: { classPropertyName: "customView", publicName: "customView", isSignal: true, isRequired: false, transformFunction: null }, customSave: { classPropertyName: "customSave", publicName: "customSave", isSignal: true, isRequired: false, transformFunction: null }, useCustomSave: { classPropertyName: "useCustomSave", publicName: "useCustomSave", isSignal: true, isRequired: false, transformFunction: null }, onApiError: { classPropertyName: "onApiError", publicName: "onApiError", isSignal: true, isRequired: false, transformFunction: null }, inlineEditConfig: { classPropertyName: "inlineEditConfig", publicName: "inlineEditConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionTriggered: "actionTriggered", selectionChanged: "selectionChanged", dataCreated: "dataCreated", dataUpdated: "dataUpdated", dataDeleted: "dataDeleted", onMoreDataLoaded: "onMoreDataLoaded", globalActionTriggered: "globalActionTriggered", modalData: "modalData", beforeSave: "beforeSave", onFilterChange: "onFilterChange", onClearFilters: "onClearFilters", activeFilterRemoved: "activeFilterRemoved", activeFiltersCleared: "activeFiltersCleared", inlineEditSave: "inlineEditSave", inlineEditModeChanged: "inlineEditModeChanged", inlineEditValidationError: "inlineEditValidationError" }, host: { listeners: { "document:click": "closeSubmenu()" } }, providers: [TableDataService, FilterService, PaginationService, ModelApiService, InlineEditService], viewQueries: [{ propertyName: "sentinel", first: true, predicate: ["sentinel"], descendants: true }, { propertyName: "dropdownTrigger", first: true, predicate: ["dropdownTrigger"], descendants: true }, { propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true }], hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "@if (showActiveFilters()) {\n <core-active-filters\n [activeFilters]=\"currentActiveFilters()\"\n [config]=\"activeFiltersConfig()\"\n (onFilterRemove)=\"onActiveFilterRemove($event)\"\n (onClearAll)=\"onActiveFiltersClear()\">\n </core-active-filters>\n}\n\n<div class=\"c-table\" [class.in-modal]=\"inModal()\" [class.inline-edit-mode]=\"inlineEditService.isInlineEditMode()\">\n <table>\n <thead>\n <tr>\n @if (showSelection()) {\n <!-- Todo: Tabla con row selection -->\n <th class=\"select-column\">\n <input type=\"checkbox\" [checked]=\"isAllSelected()\" (change)=\"masterToggle()\" />\n </th>\n }\n @for (column of columns(); track $index) {\n <th [ngClass]=\"column.align ? 'u-align-' + column.align : ''\">\n @if (column.sortable !== false) {\n <!-- \u2705 Solcre: Agregado [title] din\u00E1mico y capacidad de volver al estado sin selecci\u00F3n -->\n <button class=\"c-table-order\" tabindex=\"-1\"\n [class.is-asc]=\"currentSortColumn() === column.key && currentSortDirection() === 'asc'\"\n [class.is-desc]=\"currentSortColumn() === column.key && currentSortDirection() === 'desc'\"\n [title]=\"getSortTitle(column) | translate\" (click)=\"sortData(column)\">\n {{ column.label | translate }}\n <span class=\"c-table-order__controls\">\n <span class=\"c-table-order__arrow--desc icon-arrow-up\"></span>\n <span class=\"c-table-order__arrow--asc icon-arrow-down\"></span>\n </span>\n </button>\n <!-- <button \n class=\"c-table__order\" \n [class.is-asc]=\"currentSortColumn() === column.key && currentSortDirection() === 'asc'\" \n [class.is-desc]=\"currentSortColumn() === column.key && currentSortDirection() === 'desc'\"\n (click)=\"sortData(column)\">\n {{ column.label | translate }}\n <span class=\"icon-order-arrow\"></span>\n </button> -->\n } @else {\n {{ column.label | translate }}\n }\n </th>\n }\n @if (showActions() && (actions().length > 0 || customActions().length > 0)) {\n <th class=\"u-align-right\">{{ 'table.actions' | translate }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of displayedData(); track row.getId()) {\n <tr [ngClass]=\"getRowClasses(row)\" \n [class.is-editing-inline]=\"isRowInEditMode(row.getId())\"\n [class.is-disabled]=\"isRowDisabled(row)\">\n @if (showSelection()) {\n <!-- Todo: Tabla con row selection -->\n <td class=\"select-column\">\n <input type=\"checkbox\" [checked]=\"isRowSelected(row)\" (change)=\"toggleRow(row)\" />\n </td>\n }\n @for (column of columns(); track $index) {\n <td [attr.data-label]=\"column.label | translate\" \n [ngClass]=\"[\n column.align ? 'u-align-' + column.align : '',\n getCellDisabledClasses(row, column)\n ]\" \n [class.is-editing]=\"isColumnEditable(column, row)\"\n [class.is-column-disabled]=\"isColumnDisabledForRow(row, column)\">\n @if (column.template) {\n <!-- Todo: Ver qu\u00E9 es esto -->\n <ng-container *ngTemplateOutlet=\"column.template; context: { $implicit: row, column: column }\"></ng-container>\n } @else if (isColumnEditable(column, row)) {\n <!-- !Solcre: Modo de edici\u00F3n en l\u00EDnea usando DynamicField -->\n <div class=\"c-table__inline-edit\">\n <strong class=\"c-table__mobile-heading\">{{ column.label | translate }}:</strong>\n <div\n coreDynamicField\n [field]=\"getInlineEditableConfigWithState(row, column)!\"\n [value]=\"getEditingValue(row, column)\"\n [mode]=\"ModalMode.EDIT\"\n [errors]=\"getCellErrors(row, column)\"\n [rowData]=\"row\"\n (valueChange)=\"onCellValueChange(row, column, $event)\"\n (onBlurEvent)=\"onCellBlur(row, column)\"\n (onEnterEvent)=\"onCellEnter(row, column)\"\n ></div>\n </div>\n } @else {\n <div class=\"c-table__content\">\n <strong class=\"c-table__mobile-heading\">{{ column.label | translate }}:</strong> {{ getFormattedValue(row,\n column) }}\n </div>\n }\n </td>\n }\n\n <!-- Actions-->\n\n @if (showActions() && (actions().length > 0 || customActions().length > 0 || expansionConfig()?.enabled)) {\n\n <td class=\"u-align-right\">\n <div class=\"c-table__actions\">\n\n @for (actionConfig of regularDefaultActions(); track actionConfig.action) {\n @if (hasPermission(actionConfig)) {\n @if (actionConfig.action === TableAction.VIEW || actionConfig.action === TableAction.EDIT ||\n actionConfig.action === TableAction.DELETE) {\n <core-generic-button [config]=\"getActionButtonConfig(actionConfig.action, actionConfig)\"\n (buttonClick)=\"onButtonClick($event, actionConfig.action, row)\">\n </core-generic-button>\n }\n }\n }\n @for (customAction of getVisibleCustomActions(row, false); track customAction.label || $index) {\n @if (hasPermission(customAction)) {\n <core-generic-button [config]=\"getCustomActionButtonConfigForRow(customAction, row)\"\n (buttonClick)=\"onButtonClick($event, customAction, row)\">\n </core-generic-button>\n }\n }\n\n @if (hasExtraActionsForRow(row)) {\n <core-generic-button [config]=\"getMoreActionsButtonConfig(row.getId())\" [data]=\"row\"\n (buttonClick)=\"onMoreActionsClick($event, row.getId())\" #dropdownTrigger>\n </core-generic-button>\n <core-dropdown [rowId]=\"row.getId()\" [extraDefaultActions]=\"extraDefaultActions()\"\n [extraCustomActions]=\"getVisibleCustomActions(row, true)\" [row]=\"row\"\n [triggerElementId]=\"'dropdown-trigger-' + row.getId()\"\n (actionTriggered)=\"triggerAction($event.action, $event.row)\"\n (customActionTriggered)=\"triggerCustomAction($event.action, $event.row)\" #dropdown>\n </core-dropdown>\n }\n\n @if (expansionConfig()?.enabled) {\n <!-- \u2705 Solcre: Celda dedicada para expansi\u00F3n en su posici\u00F3n correcta -->\n <core-generic-button [config]=\"getExpandButtonConfig(row)\" (buttonClick)=\"onExpandButtonClick($event, row)\">\n </core-generic-button>\n }\n\n </div> <!-- .c-table__actions -->\n </td> <!-- td parent of .c-table__actions -->\n } <!-- @if (showActions() -->\n\n\n </tr>\n @if (expansionConfig()?.enabled && isRowExpanded(row)) {\n <!-- Todo: Ver que es esto -->\n <tr class=\"expansion-row\" [ngClass]=\"getRowClasses(row)\">\n <td [attr.colspan]=\"displayedColumns().length\" class=\"expansion-content\">\n <ng-container *ngTemplateOutlet=\"expansionConfig()!.template; context: { $implicit: row }\">\n </ng-container>\n </td>\n </tr>\n }\n } @empty {\n <tr>\n <!-- Todo: Estilo .no-data -->\n <td [attr.colspan]=\"displayedColumns().length\">\n <p class=\"c-placeholder\">{{ 'table.noData' | translate }}</p>\n </td>\n </tr>\n }\n </tbody>\n </table>\n</div> <!-- .c-table -->\n\n<!-- Todo: Todo lo que viene dsp de la tabla -->\n\n@if (!enablePagination()) {\n<!-- Todo: Ver qu\u00E9 onda esto -->\n<div #sentinel class=\"sentinel\"></div>\n}\n\n@if (enablePagination()) {\n<!-- Todo: Ver qu\u00E9 onda esto -->\n<core-generic-pagination [tableId]=\"tableId\"></core-generic-pagination>\n}\n\n<core-generic-modal [isOpen]=\"tableActionService.getIsModalOpen()\" [mode]=\"tableActionService.getModalMode()\"\n [data]=\"tableActionService.getModalData()\" [fields]=\"hasTabs() ? [] : tableActionService.getModalFieldsToShow()\"\n [tabs]=\"hasTabs() ? modalTabs() : []\" [title]=\"tableActionService.getModalTitle()\" [modelFactory]=\"modelFactory() || null\"\n (save)=\"onModalSave($event)\" (close)=\"tableActionService.closeModal()\" (modalData)=\"onModalData($event)\">\n</core-generic-modal>\n\n<core-filter-modal [isOpen]=\"isFilterModalOpen()\" [filters]=\"customFilters()\" [currentFilterValues]=\"currentFilterValues()\" (close)=\"closeFiltersPopup()\"\n (filterChange)=\"handleFilterChange($event)\" (globalFilterChange)=\"applyGlobalFilter($event)\"\n (clearFilters)=\"handleClearFilters()\">\n</core-filter-modal>", styles: [".in-modal .c-table thead th:last-child,.c-table tbody td:last-child{text-align:left}.c-table__order-btn--asc{transform:rotate(180deg)}.c-table__order-btn--desc{transform:rotate(0)}.c-table tr.is-editing-inline{background-color:#fff3cd;border-left:3px solid #ffc107}.c-table tr.is-editing-inline td{background-color:#fff3cd}.c-table tr.is-editing-inline:hover td{background-color:#ffecb5}.expansion-row .expansion-content{padding:16px;background-color:#f8f9fa;border-top:1px solid #dee2e6}.expansion-row td{border-bottom:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "component", type: GenericModalComponent, selector: "core-generic-modal", inputs: ["isOpen", "mode", "data", "fields", "tabs", "title", "isMultiple", "customTemplate", "customViewTemplate", "buttonConfig", "modelFactory", "errors", "validators"], outputs: ["save", "close", "modalData"] }, { kind: "component", type: GenericPaginationComponent, selector: "core-generic-pagination", inputs: ["tableId", "isServerSide"] }, { kind: "component", type: DropdownComponent, selector: "core-dropdown", inputs: ["rowId", "triggerElementId", "extraDefaultActions", "extraCustomActions", "row"], outputs: ["actionTriggered", "customActionTriggered"] }, { kind: "component", type: FilterModalComponent, selector: "core-filter-modal", inputs: ["isOpen", "filters", "currentFilterValues"], outputs: ["close", "filterChange", "clearFilters", "globalFilterChange"] }, { kind: "component", type: GenericButtonComponent, selector: "core-generic-button", inputs: ["config", "data"], outputs: ["buttonClick"] }, { kind: "directive", type: DynamicFieldDirective, selector: "[coreDynamicField]", inputs: ["field", "value", "mode", "errors", "rowData", "formValue"], outputs: ["valueChange", "onBlurEvent", "onEnterEvent", "selectionChange"] }, { kind: "component", type: ActiveFiltersComponent, selector: "core-active-filters", inputs: ["activeFilters", "config"], outputs: ["onFilterRemove", "onClearAll"] }] });
8409
8451
  }
8410
8452
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: GenericTableComponent, decorators: [{
8411
8453
  type: Component,
@@ -8949,6 +8991,105 @@ class SidebarCustomModalService {
8949
8991
  currentConfig = signal(null);
8950
8992
  componentRef = null;
8951
8993
  viewContainerRef = null;
8994
+ componentRegistry = new Map();
8995
+ async openComponent(componentPath, data, customClass, onClose) {
8996
+ try {
8997
+ if (componentPath.startsWith('./') || componentPath.startsWith('../')) {
8998
+ const module = await this.loadComponentByPath(componentPath);
8999
+ return this.createModalFromModule(module, data, customClass, onClose);
9000
+ }
9001
+ if (this.componentRegistry.has(componentPath)) {
9002
+ return this.openRegisteredComponent(componentPath, data, customClass, onClose);
9003
+ }
9004
+ return this.loadComponentByConvention(componentPath, data, customClass, onClose);
9005
+ }
9006
+ catch (error) {
9007
+ console.error('Error opening component:', componentPath, error);
9008
+ throw new Error(`Failed to load component: ${componentPath}`);
9009
+ }
9010
+ }
9011
+ async loadComponentByConvention(componentName, data, customClass, onClose) {
9012
+ const conventions = [
9013
+ `./components/${componentName}/${componentName}.component`,
9014
+ `./components/${componentName}-modal/${componentName}-modal.component`,
9015
+ `./modals/${componentName}/${componentName}.component`,
9016
+ `./components/${componentName}.component`,
9017
+ ];
9018
+ for (const convention of conventions) {
9019
+ try {
9020
+ const module = await this.loadComponentByPath(convention);
9021
+ return this.createModalFromModule(module, data, customClass, onClose);
9022
+ }
9023
+ catch (error) {
9024
+ continue;
9025
+ }
9026
+ }
9027
+ throw new Error(`Component '${componentName}' not found using any convention. Tried: ${conventions.join(', ')}`);
9028
+ }
9029
+ async loadComponentByPath(path) {
9030
+ return import(/* @vite-ignore */ path);
9031
+ }
9032
+ createModalFromModule(module, data, customClass, onClose) {
9033
+ const componentKey = Object.keys(module).find(key => key.endsWith('Component') &&
9034
+ (key.includes('Modal') || key.includes('Dialog') || Object.keys(module).length === 1)) || Object.keys(module)[0];
9035
+ if (!componentKey) {
9036
+ throw new Error('No component found in module');
9037
+ }
9038
+ const Component = module[componentKey];
9039
+ this.openComponentModal(Component, data, {
9040
+ customClass,
9041
+ onClose
9042
+ });
9043
+ }
9044
+ openModal(componentPath, data, options) {
9045
+ return this.openComponent(componentPath, data, options?.customClass, options?.onClose);
9046
+ }
9047
+ openLazyModal(lazyImport, data, options) {
9048
+ return lazyImport()
9049
+ .then(module => this.createModalFromModule(module, data, options?.customClass, options?.onClose))
9050
+ .catch(error => {
9051
+ console.error('Error loading lazy modal:', error);
9052
+ throw new Error(`Failed to load lazy modal: ${error.message}`);
9053
+ });
9054
+ }
9055
+ openDirectModal(component, data, options) {
9056
+ this.openComponentModal(component, data, {
9057
+ customClass: options?.customClass,
9058
+ onClose: options?.onClose
9059
+ });
9060
+ }
9061
+ registerComponent(name, loader) {
9062
+ this.componentRegistry.set(name, loader);
9063
+ }
9064
+ openRegisteredComponent(componentName, data, customClass, onClose) {
9065
+ const loader = this.componentRegistry.get(componentName);
9066
+ if (!loader) {
9067
+ throw new Error(`Component '${componentName}' not registered. Use registerComponent() first.`);
9068
+ }
9069
+ return loader()
9070
+ .then((module) => {
9071
+ const componentKey = Object.keys(module).find(key => key.endsWith('Component') || key === componentName);
9072
+ if (!componentKey) {
9073
+ throw new Error(`No component found in module for '${componentName}'`);
9074
+ }
9075
+ const Component = module[componentKey];
9076
+ this.openComponentModal(Component, data, {
9077
+ customClass,
9078
+ onClose
9079
+ });
9080
+ })
9081
+ .catch(error => {
9082
+ console.error('Error loading registered component:', componentName, error);
9083
+ throw new Error(`Failed to load component '${componentName}': ${error.message}`);
9084
+ });
9085
+ }
9086
+ getRegisteredComponents() {
9087
+ return Array.from(this.componentRegistry.keys());
9088
+ }
9089
+ registerAndOpenComponent(name, importPath, data, customClass, onClose) {
9090
+ this.registerComponent(name, () => import(/* @vite-ignore */ importPath));
9091
+ return this.openRegisteredComponent(name, data, customClass, onClose);
9092
+ }
8952
9093
  getIsOpen() {
8953
9094
  return this.isOpen;
8954
9095
  }
@@ -8958,6 +9099,9 @@ class SidebarCustomModalService {
8958
9099
  setViewContainerRef(vcr) {
8959
9100
  this.viewContainerRef = vcr;
8960
9101
  }
9102
+ resetViewContainerRef() {
9103
+ this.viewContainerRef = null;
9104
+ }
8961
9105
  openComponentModal(component, data, config) {
8962
9106
  this.closeModal();
8963
9107
  const modalConfig = {
@@ -8969,14 +9113,29 @@ class SidebarCustomModalService {
8969
9113
  };
8970
9114
  this.currentConfig.set(modalConfig);
8971
9115
  this.isOpen.set(true);
9116
+ this.createComponentWhenReady(component, data);
9117
+ }
9118
+ createComponentWhenReady(component, data) {
9119
+ if (this.viewContainerRef) {
9120
+ this.createComponentInstance(component, data);
9121
+ }
9122
+ else {
9123
+ setTimeout(() => this.createComponentWhenReady(component, data), 10);
9124
+ }
9125
+ }
9126
+ createComponentInstance(component, data) {
9127
+ if (this.componentRef) {
9128
+ return;
9129
+ }
8972
9130
  if (this.viewContainerRef && component) {
8973
9131
  this.componentRef = this.viewContainerRef.createComponent(component);
8974
9132
  if (data) {
8975
9133
  Object.keys(data).forEach(key => {
8976
- if (this.componentRef?.instance.hasOwnProperty(key)) {
9134
+ if (key in this.componentRef.instance) {
8977
9135
  this.componentRef.instance[key] = data[key];
8978
9136
  }
8979
9137
  });
9138
+ this.componentRef.changeDetectorRef.detectChanges();
8980
9139
  }
8981
9140
  if (this.componentRef.instance.modalClosed) {
8982
9141
  this.componentRef.instance.modalClosed.subscribe(() => {
@@ -9002,6 +9161,7 @@ class SidebarCustomModalService {
9002
9161
  this.componentRef.destroy();
9003
9162
  this.componentRef = null;
9004
9163
  }
9164
+ this.resetViewContainerRef();
9005
9165
  const config = this.currentConfig();
9006
9166
  if (config?.onClose) {
9007
9167
  config.onClose();
@@ -9009,6 +9169,20 @@ class SidebarCustomModalService {
9009
9169
  this.isOpen.set(false);
9010
9170
  this.currentConfig.set(null);
9011
9171
  }
9172
+ openDynamicComponentModal(importPath, componentName, data, config) {
9173
+ return import(/* @vite-ignore */ importPath)
9174
+ .then((module) => {
9175
+ const Component = module[componentName];
9176
+ if (!Component) {
9177
+ throw new Error(`Component ${componentName} not found in module ${importPath}`);
9178
+ }
9179
+ this.openComponentModal(Component, data, config);
9180
+ })
9181
+ .catch(error => {
9182
+ console.error('Error loading dynamic component:', componentName, 'from:', importPath, error);
9183
+ throw new Error(`Failed to load component ${componentName} from ${importPath}`);
9184
+ });
9185
+ }
9012
9186
  onBackdropClick() {
9013
9187
  const config = this.currentConfig();
9014
9188
  if (config?.closeOnBackdrop !== false) {
@@ -9271,12 +9445,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
9271
9445
 
9272
9446
  class SidebarCustomModalComponent {
9273
9447
  modalService = inject(SidebarCustomModalService);
9448
+ cdr = inject(ChangeDetectorRef);
9274
9449
  dynamicComponent;
9275
- ngOnInit() {
9276
- setTimeout(() => {
9277
- this.modalService.setViewContainerRef(this.dynamicComponent);
9450
+ hasInitializedViewContainerRef = false;
9451
+ currentModalState = false;
9452
+ constructor() {
9453
+ effect(() => {
9454
+ const isOpen = this.modalService.getIsOpen()();
9455
+ if (this.currentModalState && !isOpen) {
9456
+ this.hasInitializedViewContainerRef = false;
9457
+ this.modalService['viewContainerRef'] = null;
9458
+ }
9459
+ this.currentModalState = isOpen;
9278
9460
  });
9279
9461
  }
9462
+ ngAfterViewInit() {
9463
+ this.setupViewContainerRefIfAvailable();
9464
+ }
9465
+ ngAfterViewChecked() {
9466
+ this.setupViewContainerRefIfAvailable();
9467
+ }
9468
+ setupViewContainerRefIfAvailable() {
9469
+ if (!this.modalService.getIsOpen()() || !this.dynamicComponent) {
9470
+ return;
9471
+ }
9472
+ const hasViewContainerRef = !!this.modalService['viewContainerRef'];
9473
+ const hasComponentRef = !!this.modalService['componentRef'];
9474
+ if (!hasViewContainerRef || !this.hasInitializedViewContainerRef) {
9475
+ this.modalService.setViewContainerRef(this.dynamicComponent);
9476
+ this.hasInitializedViewContainerRef = true;
9477
+ setTimeout(() => this.cdr.detectChanges(), 0);
9478
+ const config = this.modalService.getCurrentConfig()();
9479
+ if (config?.component && !hasComponentRef) {
9480
+ setTimeout(() => {
9481
+ this.modalService.createComponentInstance(config.component, config.data);
9482
+ this.cdr.detectChanges();
9483
+ }, 0);
9484
+ }
9485
+ }
9486
+ }
9280
9487
  ngOnDestroy() {
9281
9488
  this.modalService.closeModal();
9282
9489
  }
@@ -9298,12 +9505,12 @@ class SidebarCustomModalComponent {
9298
9505
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: SidebarCustomModalComponent, isStandalone: true, selector: "core-sidebar-custom-modal", viewQueries: [{ propertyName: "dynamicComponent", first: true, predicate: ["dynamicComponent"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: `
9299
9506
  @if(modalService.getIsOpen()()) {
9300
9507
  <ng-container #dynamicComponent></ng-container>
9301
-
9302
- @if(getCurrentConfig()?.template) {
9508
+
9509
+ @if(getCurrentConfig()?.template) {
9303
9510
  <ng-container
9304
9511
  *ngTemplateOutlet="getCurrentConfig()!.template!; context: { $implicit: getCurrentConfig()?.data }">
9305
9512
  </ng-container>
9306
- }
9513
+ }
9307
9514
  }
9308
9515
  `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
9309
9516
  }
@@ -9316,18 +9523,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
9316
9523
  template: `
9317
9524
  @if(modalService.getIsOpen()()) {
9318
9525
  <ng-container #dynamicComponent></ng-container>
9319
-
9320
- @if(getCurrentConfig()?.template) {
9526
+
9527
+ @if(getCurrentConfig()?.template) {
9321
9528
  <ng-container
9322
9529
  *ngTemplateOutlet="getCurrentConfig()!.template!; context: { $implicit: getCurrentConfig()?.data }">
9323
9530
  </ng-container>
9324
- }
9531
+ }
9325
9532
  }
9326
9533
  `,
9327
9534
  }]
9328
- }], propDecorators: { dynamicComponent: [{
9535
+ }], ctorParameters: () => [], propDecorators: { dynamicComponent: [{
9329
9536
  type: ViewChild,
9330
- args: ['dynamicComponent', { read: ViewContainerRef }]
9537
+ args: ['dynamicComponent', { read: ViewContainerRef, static: false }]
9331
9538
  }] } });
9332
9539
 
9333
9540
  var TimelineStatus;
@@ -9787,11 +9994,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
9787
9994
  // Este archivo es generado automáticamente por scripts/update-version.js
9788
9995
  // No edites manualmente este archivo
9789
9996
  const VERSION = {
9790
- full: '2.11.13',
9997
+ full: '2.11.15',
9791
9998
  major: 2,
9792
9999
  minor: 11,
9793
- patch: 13,
9794
- timestamp: '2025-08-22T09:27:21.226Z',
10000
+ patch: 15,
10001
+ timestamp: '2025-08-22T11:27:30.822Z',
9795
10002
  buildDate: '22/8/2025'
9796
10003
  };
9797
10004