@solcre-org/core-ui 2.11.31 → 2.11.33

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { HostBinding, Directive, input, Component, inject, output, computed, signal, effect, Pipe, ViewChild, Injectable, ViewContainerRef, TemplateRef, InjectionToken, ContentChild, ChangeDetectionStrategy, ElementRef, Input, HostListener, viewChild, ChangeDetectorRef, importProvidersFrom } from '@angular/core';
2
+ import { HostBinding, Directive, input, Component, inject, output, computed, signal, effect, Pipe, Injectable, ViewChild, ViewContainerRef, TemplateRef, InjectionToken, ContentChild, ChangeDetectionStrategy, ElementRef, Input, HostListener, viewChild, ChangeDetectorRef, importProvidersFrom } from '@angular/core';
3
3
  import * as i2 from '@angular/common';
4
4
  import { CommonModule, DatePipe } from '@angular/common';
5
5
  import * as i3 from '@ngx-translate/core';
@@ -928,6 +928,62 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
928
928
  }]
929
929
  }] });
930
930
 
931
+ class ImageModalService {
932
+ isOpen = signal(false);
933
+ currentImage = signal(null);
934
+ isModalOpen = this.isOpen.asReadonly();
935
+ getCurrentImage = this.currentImage.asReadonly();
936
+ openImageModal(imageData) {
937
+ this.currentImage.set(imageData);
938
+ this.isOpen.set(true);
939
+ }
940
+ closeImageModal() {
941
+ this.isOpen.set(false);
942
+ setTimeout(() => {
943
+ this.currentImage.set(null);
944
+ }, 300);
945
+ }
946
+ toggleModal() {
947
+ if (this.isOpen()) {
948
+ this.closeImageModal();
949
+ }
950
+ }
951
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ImageModalService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
952
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ImageModalService, providedIn: 'root' });
953
+ }
954
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ImageModalService, decorators: [{
955
+ type: Injectable,
956
+ args: [{
957
+ providedIn: 'root'
958
+ }]
959
+ }] });
960
+
961
+ class ImagePreviewComponent {
962
+ imageModalService = inject(ImageModalService);
963
+ src = input.required();
964
+ alt = input('');
965
+ title = input('');
966
+ width = input('');
967
+ height = input('');
968
+ objectFit = input('cover');
969
+ borderRadius = input('4px');
970
+ cursor = input('pointer');
971
+ loading = input('lazy');
972
+ onImageClick() {
973
+ this.imageModalService.openImageModal({
974
+ src: this.src(),
975
+ alt: this.alt(),
976
+ title: this.title()
977
+ });
978
+ }
979
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ImagePreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
980
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.6", type: ImagePreviewComponent, isStandalone: true, selector: "core-image-preview", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: true, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, objectFit: { classPropertyName: "objectFit", publicName: "objectFit", isSignal: true, isRequired: false, transformFunction: null }, borderRadius: { classPropertyName: "borderRadius", publicName: "borderRadius", isSignal: true, isRequired: false, transformFunction: null }, cursor: { classPropertyName: "cursor", publicName: "cursor", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"c-img-preview\" \n [style.width]=\"width()\"\n [style.height]=\"height()\"\n (click)=\"onImageClick()\">\n <img \n [src]=\"src()\" \n [alt]=\"alt()\"\n [title]=\"title()\"\n [loading]=\"loading()\"\n [style.object-fit]=\"objectFit()\"\n [style.border-radius]=\"borderRadius()\"\n [style.cursor]=\"cursor()\">\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
981
+ }
982
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ImagePreviewComponent, decorators: [{
983
+ type: Component,
984
+ args: [{ selector: 'core-image-preview', standalone: true, imports: [CommonModule], template: "<div class=\"c-img-preview\" \n [style.width]=\"width()\"\n [style.height]=\"height()\"\n (click)=\"onImageClick()\">\n <img \n [src]=\"src()\" \n [alt]=\"alt()\"\n [title]=\"title()\"\n [loading]=\"loading()\"\n [style.object-fit]=\"objectFit()\"\n [style.border-radius]=\"borderRadius()\"\n [style.cursor]=\"cursor()\">\n</div>" }]
985
+ }] });
986
+
931
987
  class FileFieldComponent extends BaseFieldComponent {
932
988
  authService = inject(AuthService);
933
989
  selectedFiles = signal([]);
@@ -1173,11 +1229,11 @@ class FileFieldComponent extends BaseFieldComponent {
1173
1229
  this.onBlur();
1174
1230
  }
1175
1231
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: FileFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1176
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: FileFieldComponent, isStandalone: true, selector: "core-file-field", usesInheritance: true, hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "<label class=\"c-entry-item\" [class.c-entry-item--inline]=\"field().inline\">\n @if (field().label) {\n <span class=\"c-entry-text\">\n {{ field().label | translate }}\n @if (hasRequiredValidators()) {\n <span class=\"c-required\">*</span>\n }\n </span>\n }\n <div class=\"c-entry-file\" [class.has-error]=\"hasError()\">\n @if(fieldConfig().multiple || isEditMode() || allFiles().length === 0) {\n <label class=\"c-entry-file__label\">\n <span class=\"icon-upload c-entry-file__icon\"></span>\n <input\n type=\"file\"\n class=\"c-entry-file__input\"\n (change)=\"onFileSelected($event)\"\n [accept]=\"fieldConfig().accept\"\n [multiple]=\"fieldConfig().multiple\"\n (blur)=\"onBlurInput()\"\n [readonly]=\"isReadonly()\"\n >\n {{ fieldConfig().placeholder ?? fieldConfig().label | translate }}\n @if(fieldConfig().acceptString) {\n <br>\n <span class=\"c-entry-file__filename\" id=\"file-name\">{{ fieldConfig().acceptString }}</span>\n }\n </label>\n }\n\n @if (allFiles().length > 0) {\n <div class=\"c-attachments\">\n <p class=\"c-entry-text\">{{ 'files.attachedFiles' | translate }}</p>\n \n <ul class=\"c-attachments__list\">\n @for (file of allFiles(); track $index; let i = $index) {\n <li class=\"c-attachments__item\">\n <div class=\"c-bulleted-text\">\n @if(!isServerFile(file)) {\n <time>{{ getCurrentDate() }}</time>\n <span>{{ getCurrentUser() }}</span>\n }\n </div>\n \n <div class=\"c-attachments__holder\">\n @if(!isServerFile(file) && file.type.startsWith('image/') && fieldConfig().showPreview !== false) {\n <div class=\"c-attachments__content\">\n @if(getPreviewIndex(file) >= 0 && previewUrls()[getPreviewIndex(file)]) {\n <picture class=\"c-attachments__pic c-pic\">\n <img [src]=\"previewUrls()[getPreviewIndex(file)]\" [alt]=\"file.name\" loading=\"lazy\">\n </picture>\n }\n <div class=\"c-attachments__text\">\n <span class=\"c-attachments__name-file\">{{ file.name }}</span>\n <span class=\"c-attachments__file-size\">({{ formatFileSize(file.size) }})</span>\n </div>\n </div>\n } @else {\n <a class=\"c-attachments__content\">\n @if(isServerFile(file)) {\n <span class=\"icon-file\"></span>\n {{ file.filename }}\n } @else {\n <span [class]=\"getFileIcon(file)\"></span>\n <div class=\"c-attachments__text\">\n <span class=\"c-attachments__name-file\">{{ file.name }}</span>\n <span class=\"c-attachments__file-size\">({{ formatFileSize(file.size) }})</span>\n </div>\n }\n </a>\n }\n\n <div class=\"c-attachments__actions u-flex u-flex--wrap\">\n <button \n type=\"button\" \n class=\"c-link context:error\" \n (click)=\"removeFile(i)\"\n [title]=\"'files.remove' | translate\"\n >\n <span class=\"icon-delete\"></span>\n {{ 'files.remove' | translate }}\n </button>\n\n @if(fieldConfig().customActions) {\n @for(action of fieldConfig().customActions; track action.id) {\n <button \n type=\"button\"\n class=\"c-link c-link--underlined\" \n (click)=\"action.action(file)\"\n [title]=\"action.label | translate\"\n >\n {{ action.label | translate }}\n <span [ngClass]=\"action.icon | coreIconCompat\"></span>\n </button>\n }\n }\n </div>\n </div>\n </li>\n }\n </ul>\n </div>\n }\n </div>\n <core-field-errors [errors]=\"errors()\" />\n @if(displayErrorMessage()) {\n <span class=\"c-entry-error\">{{ displayErrorMessage()!.key | translate:displayErrorMessage()!.params }}</span>\n }\n</label>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FieldErrorsComponent, selector: "core-field-errors", inputs: ["errors"] }, { kind: "pipe", type: IconCompatPipe, name: "coreIconCompat" }] });
1232
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: FileFieldComponent, isStandalone: true, selector: "core-file-field", usesInheritance: true, hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "<label class=\"c-entry-item\" [class.c-entry-item--inline]=\"field().inline\">\n @if (field().label) {\n <span class=\"c-entry-text\">\n {{ field().label | translate }}\n @if (hasRequiredValidators()) {\n <span class=\"c-required\">*</span>\n }\n </span>\n }\n <div class=\"c-entry-file\" [class.has-error]=\"hasError()\">\n @if(fieldConfig().multiple || isEditMode() || allFiles().length === 0) {\n <label class=\"c-entry-file__label\">\n <span class=\"icon-upload c-entry-file__icon\"></span>\n <input\n type=\"file\"\n class=\"c-entry-file__input\"\n (change)=\"onFileSelected($event)\"\n [accept]=\"fieldConfig().accept\"\n [multiple]=\"fieldConfig().multiple\"\n (blur)=\"onBlurInput()\"\n [readonly]=\"isReadonly()\"\n >\n {{ fieldConfig().placeholder ?? fieldConfig().label | translate }}\n @if(fieldConfig().acceptString) {\n <br>\n <span class=\"c-entry-file__filename\" id=\"file-name\">{{ fieldConfig().acceptString }}</span>\n }\n </label>\n }\n\n @if (allFiles().length > 0) {\n <div class=\"c-attachments\">\n <p class=\"c-entry-text\">{{ 'files.attachedFiles' | translate }}</p>\n \n <ul class=\"c-attachments__list\">\n @for (file of allFiles(); track $index; let i = $index) {\n <li class=\"c-attachments__item\">\n <div class=\"c-bulleted-text\">\n @if(!isServerFile(file)) {\n <time>{{ getCurrentDate() }}</time>\n <span>{{ getCurrentUser() }}</span>\n }\n </div>\n \n <div class=\"c-attachments__holder\">\n @if(!isServerFile(file) && file.type.startsWith('image/') && fieldConfig().showPreview !== false) {\n <div class=\"c-attachments__content\">\n @if(getPreviewIndex(file) >= 0 && previewUrls()[getPreviewIndex(file)]) {\n <core-image-preview\n [src]=\"previewUrls()[getPreviewIndex(file)]\"\n [alt]=\"file.name\"\n ></core-image-preview>\n <!-- <picture class=\"c-attachments__pic c-pic\">\n <img [src]=\"previewUrls()[getPreviewIndex(file)]\" [alt]=\"file.name\" loading=\"lazy\">\n </picture> -->\n }\n <div class=\"c-attachments__text\">\n <span class=\"c-attachments__name-file\">{{ file.name }}</span>\n <span class=\"c-attachments__file-size\">({{ formatFileSize(file.size) }})</span>\n </div>\n </div>\n } @else {\n <a class=\"c-attachments__content\">\n @if(isServerFile(file)) {\n <span class=\"icon-file\"></span>\n {{ file.filename }}\n } @else {\n <span [class]=\"getFileIcon(file)\"></span>\n <div class=\"c-attachments__text\">\n <span class=\"c-attachments__name-file\">{{ file.name }}</span>\n <span class=\"c-attachments__file-size\">({{ formatFileSize(file.size) }})</span>\n </div>\n }\n </a>\n }\n\n <div class=\"c-attachments__actions u-flex u-flex--wrap\">\n <button \n type=\"button\" \n class=\"c-link context:error\" \n (click)=\"removeFile(i)\"\n [title]=\"'files.remove' | translate\"\n >\n <span class=\"icon-delete\"></span>\n {{ 'files.remove' | translate }}\n </button>\n\n @if(fieldConfig().customActions) {\n @for(action of fieldConfig().customActions; track action.id) {\n <button \n type=\"button\"\n class=\"c-link c-link--underlined\" \n (click)=\"action.action(file)\"\n [title]=\"action.label | translate\"\n >\n {{ action.label | translate }}\n <span [ngClass]=\"action.icon | coreIconCompat\"></span>\n </button>\n }\n }\n </div>\n </div>\n </li>\n }\n </ul>\n </div>\n }\n </div>\n <core-field-errors [errors]=\"errors()\" />\n @if(displayErrorMessage()) {\n <span class=\"c-entry-error\">{{ displayErrorMessage()!.key | translate:displayErrorMessage()!.params }}</span>\n }\n</label>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FieldErrorsComponent, selector: "core-field-errors", inputs: ["errors"] }, { kind: "pipe", type: IconCompatPipe, name: "coreIconCompat" }, { kind: "component", type: ImagePreviewComponent, selector: "core-image-preview", inputs: ["src", "alt", "title", "width", "height", "objectFit", "borderRadius", "cursor", "loading"] }] });
1177
1233
  }
1178
1234
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: FileFieldComponent, decorators: [{
1179
1235
  type: Component,
1180
- args: [{ selector: 'core-file-field', standalone: true, imports: [CommonModule, FormsModule, TranslateModule, ReactiveFormsModule, FieldErrorsComponent, IconCompatPipe], hostDirectives: [CoreHostDirective], template: "<label class=\"c-entry-item\" [class.c-entry-item--inline]=\"field().inline\">\n @if (field().label) {\n <span class=\"c-entry-text\">\n {{ field().label | translate }}\n @if (hasRequiredValidators()) {\n <span class=\"c-required\">*</span>\n }\n </span>\n }\n <div class=\"c-entry-file\" [class.has-error]=\"hasError()\">\n @if(fieldConfig().multiple || isEditMode() || allFiles().length === 0) {\n <label class=\"c-entry-file__label\">\n <span class=\"icon-upload c-entry-file__icon\"></span>\n <input\n type=\"file\"\n class=\"c-entry-file__input\"\n (change)=\"onFileSelected($event)\"\n [accept]=\"fieldConfig().accept\"\n [multiple]=\"fieldConfig().multiple\"\n (blur)=\"onBlurInput()\"\n [readonly]=\"isReadonly()\"\n >\n {{ fieldConfig().placeholder ?? fieldConfig().label | translate }}\n @if(fieldConfig().acceptString) {\n <br>\n <span class=\"c-entry-file__filename\" id=\"file-name\">{{ fieldConfig().acceptString }}</span>\n }\n </label>\n }\n\n @if (allFiles().length > 0) {\n <div class=\"c-attachments\">\n <p class=\"c-entry-text\">{{ 'files.attachedFiles' | translate }}</p>\n \n <ul class=\"c-attachments__list\">\n @for (file of allFiles(); track $index; let i = $index) {\n <li class=\"c-attachments__item\">\n <div class=\"c-bulleted-text\">\n @if(!isServerFile(file)) {\n <time>{{ getCurrentDate() }}</time>\n <span>{{ getCurrentUser() }}</span>\n }\n </div>\n \n <div class=\"c-attachments__holder\">\n @if(!isServerFile(file) && file.type.startsWith('image/') && fieldConfig().showPreview !== false) {\n <div class=\"c-attachments__content\">\n @if(getPreviewIndex(file) >= 0 && previewUrls()[getPreviewIndex(file)]) {\n <picture class=\"c-attachments__pic c-pic\">\n <img [src]=\"previewUrls()[getPreviewIndex(file)]\" [alt]=\"file.name\" loading=\"lazy\">\n </picture>\n }\n <div class=\"c-attachments__text\">\n <span class=\"c-attachments__name-file\">{{ file.name }}</span>\n <span class=\"c-attachments__file-size\">({{ formatFileSize(file.size) }})</span>\n </div>\n </div>\n } @else {\n <a class=\"c-attachments__content\">\n @if(isServerFile(file)) {\n <span class=\"icon-file\"></span>\n {{ file.filename }}\n } @else {\n <span [class]=\"getFileIcon(file)\"></span>\n <div class=\"c-attachments__text\">\n <span class=\"c-attachments__name-file\">{{ file.name }}</span>\n <span class=\"c-attachments__file-size\">({{ formatFileSize(file.size) }})</span>\n </div>\n }\n </a>\n }\n\n <div class=\"c-attachments__actions u-flex u-flex--wrap\">\n <button \n type=\"button\" \n class=\"c-link context:error\" \n (click)=\"removeFile(i)\"\n [title]=\"'files.remove' | translate\"\n >\n <span class=\"icon-delete\"></span>\n {{ 'files.remove' | translate }}\n </button>\n\n @if(fieldConfig().customActions) {\n @for(action of fieldConfig().customActions; track action.id) {\n <button \n type=\"button\"\n class=\"c-link c-link--underlined\" \n (click)=\"action.action(file)\"\n [title]=\"action.label | translate\"\n >\n {{ action.label | translate }}\n <span [ngClass]=\"action.icon | coreIconCompat\"></span>\n </button>\n }\n }\n </div>\n </div>\n </li>\n }\n </ul>\n </div>\n }\n </div>\n <core-field-errors [errors]=\"errors()\" />\n @if(displayErrorMessage()) {\n <span class=\"c-entry-error\">{{ displayErrorMessage()!.key | translate:displayErrorMessage()!.params }}</span>\n }\n</label>\n" }]
1236
+ args: [{ selector: 'core-file-field', standalone: true, imports: [CommonModule, FormsModule, TranslateModule, ReactiveFormsModule, FieldErrorsComponent, IconCompatPipe, ImagePreviewComponent], hostDirectives: [CoreHostDirective], template: "<label class=\"c-entry-item\" [class.c-entry-item--inline]=\"field().inline\">\n @if (field().label) {\n <span class=\"c-entry-text\">\n {{ field().label | translate }}\n @if (hasRequiredValidators()) {\n <span class=\"c-required\">*</span>\n }\n </span>\n }\n <div class=\"c-entry-file\" [class.has-error]=\"hasError()\">\n @if(fieldConfig().multiple || isEditMode() || allFiles().length === 0) {\n <label class=\"c-entry-file__label\">\n <span class=\"icon-upload c-entry-file__icon\"></span>\n <input\n type=\"file\"\n class=\"c-entry-file__input\"\n (change)=\"onFileSelected($event)\"\n [accept]=\"fieldConfig().accept\"\n [multiple]=\"fieldConfig().multiple\"\n (blur)=\"onBlurInput()\"\n [readonly]=\"isReadonly()\"\n >\n {{ fieldConfig().placeholder ?? fieldConfig().label | translate }}\n @if(fieldConfig().acceptString) {\n <br>\n <span class=\"c-entry-file__filename\" id=\"file-name\">{{ fieldConfig().acceptString }}</span>\n }\n </label>\n }\n\n @if (allFiles().length > 0) {\n <div class=\"c-attachments\">\n <p class=\"c-entry-text\">{{ 'files.attachedFiles' | translate }}</p>\n \n <ul class=\"c-attachments__list\">\n @for (file of allFiles(); track $index; let i = $index) {\n <li class=\"c-attachments__item\">\n <div class=\"c-bulleted-text\">\n @if(!isServerFile(file)) {\n <time>{{ getCurrentDate() }}</time>\n <span>{{ getCurrentUser() }}</span>\n }\n </div>\n \n <div class=\"c-attachments__holder\">\n @if(!isServerFile(file) && file.type.startsWith('image/') && fieldConfig().showPreview !== false) {\n <div class=\"c-attachments__content\">\n @if(getPreviewIndex(file) >= 0 && previewUrls()[getPreviewIndex(file)]) {\n <core-image-preview\n [src]=\"previewUrls()[getPreviewIndex(file)]\"\n [alt]=\"file.name\"\n ></core-image-preview>\n <!-- <picture class=\"c-attachments__pic c-pic\">\n <img [src]=\"previewUrls()[getPreviewIndex(file)]\" [alt]=\"file.name\" loading=\"lazy\">\n </picture> -->\n }\n <div class=\"c-attachments__text\">\n <span class=\"c-attachments__name-file\">{{ file.name }}</span>\n <span class=\"c-attachments__file-size\">({{ formatFileSize(file.size) }})</span>\n </div>\n </div>\n } @else {\n <a class=\"c-attachments__content\">\n @if(isServerFile(file)) {\n <span class=\"icon-file\"></span>\n {{ file.filename }}\n } @else {\n <span [class]=\"getFileIcon(file)\"></span>\n <div class=\"c-attachments__text\">\n <span class=\"c-attachments__name-file\">{{ file.name }}</span>\n <span class=\"c-attachments__file-size\">({{ formatFileSize(file.size) }})</span>\n </div>\n }\n </a>\n }\n\n <div class=\"c-attachments__actions u-flex u-flex--wrap\">\n <button \n type=\"button\" \n class=\"c-link context:error\" \n (click)=\"removeFile(i)\"\n [title]=\"'files.remove' | translate\"\n >\n <span class=\"icon-delete\"></span>\n {{ 'files.remove' | translate }}\n </button>\n\n @if(fieldConfig().customActions) {\n @for(action of fieldConfig().customActions; track action.id) {\n <button \n type=\"button\"\n class=\"c-link c-link--underlined\" \n (click)=\"action.action(file)\"\n [title]=\"action.label | translate\"\n >\n {{ action.label | translate }}\n <span [ngClass]=\"action.icon | coreIconCompat\"></span>\n </button>\n }\n }\n </div>\n </div>\n </li>\n }\n </ul>\n </div>\n }\n </div>\n <core-field-errors [errors]=\"errors()\" />\n @if(displayErrorMessage()) {\n <span class=\"c-entry-error\">{{ displayErrorMessage()!.key | translate:displayErrorMessage()!.params }}</span>\n }\n</label>\n" }]
1181
1237
  }] });
1182
1238
 
1183
1239
  var NumberFieldConfigType;
@@ -3903,6 +3959,20 @@ class GenericModalComponent {
3903
3959
  formGroup[fieldKey] = [newInstance[fieldKey], validators];
3904
3960
  });
3905
3961
  this.form.set(this.formBuilder.group(formGroup));
3962
+ this.allFields().forEach(field => {
3963
+ const fieldKey = field.key;
3964
+ const payloadKey = (field.keyToPayload ?? field.key);
3965
+ if ('dynamicValue' in field && typeof field.dynamicValue === 'function') {
3966
+ const dynamicVal = field.dynamicValue(newInstance);
3967
+ if (dynamicVal !== undefined) {
3968
+ newInstance[payloadKey] = dynamicVal;
3969
+ const control = this.form().get(fieldKey);
3970
+ if (control) {
3971
+ control.setValue(dynamicVal, { emitEvent: false });
3972
+ }
3973
+ }
3974
+ }
3975
+ });
3906
3976
  setTimeout(() => {
3907
3977
  Object.values(this.form().controls).forEach(control => {
3908
3978
  control.markAsUntouched();
@@ -8970,7 +9040,7 @@ class GenericTableComponent {
8970
9040
  this.tableDataService.updateRowData(rowId, updatedFields, updateFunction);
8971
9041
  }
8972
9042
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: GenericTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8973
- 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", dataFetched: "dataFetched", onMoreDataLoaded: "onMoreDataLoaded", globalActionTriggered: "globalActionTriggered", modalData: "modalData", beforeSave: "beforeSave", onFilterChange: "onFilterChange", onClearFilters: "onClearFilters", activeFilterRemoved: "activeFilterRemoved", activeFiltersCleared: "activeFiltersCleared", inlineEditSave: "inlineEditSave", inlineEditModeChanged: "inlineEditModeChanged", inlineEditValidationError: "inlineEditValidationError" }, host: { listeners: { "window:beforeunload": "onBeforeUnload($event)", "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"] }] });
9043
+ 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", dataFetched: "dataFetched", onMoreDataLoaded: "onMoreDataLoaded", globalActionTriggered: "globalActionTriggered", modalData: "modalData", beforeSave: "beforeSave", onFilterChange: "onFilterChange", onClearFilters: "onClearFilters", activeFilterRemoved: "activeFilterRemoved", activeFiltersCleared: "activeFiltersCleared", inlineEditSave: "inlineEditSave", inlineEditModeChanged: "inlineEditModeChanged", inlineEditValidationError: "inlineEditValidationError" }, host: { listeners: { "window:beforeunload": "onBeforeUnload($event)", "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 <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 @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 }\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"] }] });
8974
9044
  }
8975
9045
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: GenericTableComponent, decorators: [{
8976
9046
  type: Component,
@@ -8984,7 +9054,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
8984
9054
  GenericButtonComponent,
8985
9055
  DynamicFieldDirective,
8986
9056
  ActiveFiltersComponent,
8987
- ], hostDirectives: [CoreHostDirective], providers: [TableDataService, FilterService, PaginationService, ModelApiService, InlineEditService], 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"] }]
9057
+ ], hostDirectives: [CoreHostDirective], providers: [TableDataService, FilterService, PaginationService, ModelApiService, InlineEditService], 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 <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 @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 }\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"] }]
8988
9058
  }], ctorParameters: () => [], propDecorators: { sentinel: [{
8989
9059
  type: ViewChild,
8990
9060
  args: ['sentinel', { static: false }]
@@ -10520,11 +10590,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
10520
10590
  // Este archivo es generado automáticamente por scripts/update-version.js
10521
10591
  // No edites manualmente este archivo
10522
10592
  const VERSION = {
10523
- full: '2.11.31',
10593
+ full: '2.11.33',
10524
10594
  major: 2,
10525
10595
  minor: 11,
10526
- patch: 31,
10527
- timestamp: '2025-09-01T11:31:01.284Z',
10596
+ patch: 33,
10597
+ timestamp: '2025-09-01T16:54:48.798Z',
10528
10598
  buildDate: '1/9/2025'
10529
10599
  };
10530
10600
 
@@ -10869,6 +10939,237 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
10869
10939
  }]
10870
10940
  }], ctorParameters: () => [] });
10871
10941
 
10942
+ class ImageModalComponent {
10943
+ modalImage;
10944
+ imageContainer;
10945
+ imageModalService = inject(ImageModalService);
10946
+ isVisible = this.imageModalService.isModalOpen;
10947
+ currentImage = this.imageModalService.getCurrentImage;
10948
+ modalClosed = output();
10949
+ zoomLevel = signal(1);
10950
+ isDragging = signal(false);
10951
+ lastMouseX = signal(0);
10952
+ lastMouseY = signal(0);
10953
+ translateX = signal(0);
10954
+ translateY = signal(0);
10955
+ minZoom = 1;
10956
+ maxZoom = 3;
10957
+ zoomStep = 0.2;
10958
+ targetTranslateX = 0;
10959
+ targetTranslateY = 0;
10960
+ velocityX = 0;
10961
+ velocityY = 0;
10962
+ friction = 0.9;
10963
+ animationId = null;
10964
+ constructor() {
10965
+ effect(() => {
10966
+ if (this.isVisible()) {
10967
+ document.body.style.overflow = 'hidden';
10968
+ this.resetZoom();
10969
+ }
10970
+ else {
10971
+ document.body.style.overflow = '';
10972
+ this.resetZoom();
10973
+ this.stopAnimation();
10974
+ }
10975
+ });
10976
+ }
10977
+ startAnimation() {
10978
+ if (this.animationId)
10979
+ return;
10980
+ const animate = () => {
10981
+ if (!this.isDragging()) {
10982
+ const currentX = this.translateX();
10983
+ const currentY = this.translateY();
10984
+ const newX = currentX + this.velocityX;
10985
+ const newY = currentY + this.velocityY;
10986
+ this.translateX.set(newX);
10987
+ this.translateY.set(newY);
10988
+ this.velocityX *= this.friction;
10989
+ this.velocityY *= this.friction;
10990
+ if (Math.abs(this.velocityX) < 0.1 && Math.abs(this.velocityY) < 0.1) {
10991
+ this.velocityX = 0;
10992
+ this.velocityY = 0;
10993
+ this.animationId = null;
10994
+ return;
10995
+ }
10996
+ this.animationId = requestAnimationFrame(animate);
10997
+ }
10998
+ else {
10999
+ this.animationId = null;
11000
+ }
11001
+ };
11002
+ this.animationId = requestAnimationFrame(animate);
11003
+ }
11004
+ stopAnimation() {
11005
+ if (this.animationId) {
11006
+ cancelAnimationFrame(this.animationId);
11007
+ this.animationId = null;
11008
+ }
11009
+ this.velocityX = 0;
11010
+ this.velocityY = 0;
11011
+ }
11012
+ resetZoom() {
11013
+ this.zoomLevel.set(1);
11014
+ this.translateX.set(0);
11015
+ this.translateY.set(0);
11016
+ this.isDragging.set(false);
11017
+ this.velocityX = 0;
11018
+ this.velocityY = 0;
11019
+ this.stopAnimation();
11020
+ }
11021
+ closeModal() {
11022
+ this.resetZoom();
11023
+ this.imageModalService.closeImageModal();
11024
+ this.modalClosed.emit();
11025
+ }
11026
+ onWheel(event) {
11027
+ if (!this.isVisible())
11028
+ return;
11029
+ event.preventDefault();
11030
+ event.stopPropagation();
11031
+ const delta = event.deltaY > 0 ? -this.zoomStep : this.zoomStep;
11032
+ const newZoom = Math.min(Math.max(this.zoomLevel() + delta, this.minZoom), this.maxZoom);
11033
+ if (newZoom !== this.zoomLevel()) {
11034
+ this.zoomLevel.set(newZoom);
11035
+ if (newZoom === 1) {
11036
+ this.translateX.set(0);
11037
+ this.translateY.set(0);
11038
+ this.velocityX = 0;
11039
+ this.velocityY = 0;
11040
+ }
11041
+ }
11042
+ }
11043
+ onMouseDown(event) {
11044
+ if (!this.isVisible() || this.zoomLevel() <= 1)
11045
+ return;
11046
+ event.preventDefault();
11047
+ this.isDragging.set(true);
11048
+ this.lastMouseX.set(event.clientX);
11049
+ this.lastMouseY.set(event.clientY);
11050
+ this.velocityX = 0;
11051
+ this.velocityY = 0;
11052
+ }
11053
+ onMouseMove(event) {
11054
+ if (!this.isDragging() || !this.isVisible())
11055
+ return;
11056
+ event.preventDefault();
11057
+ const deltaX = event.clientX - this.lastMouseX();
11058
+ const deltaY = event.clientY - this.lastMouseY();
11059
+ const newX = this.translateX() + deltaX;
11060
+ const newY = this.translateY() + deltaY;
11061
+ this.translateX.set(newX);
11062
+ this.translateY.set(newY);
11063
+ this.velocityX = deltaX * 0.5;
11064
+ this.velocityY = deltaY * 0.5;
11065
+ this.lastMouseX.set(event.clientX);
11066
+ this.lastMouseY.set(event.clientY);
11067
+ }
11068
+ onMouseUp() {
11069
+ if (this.isDragging()) {
11070
+ this.isDragging.set(false);
11071
+ if (Math.abs(this.velocityX) > 1 || Math.abs(this.velocityY) > 1) {
11072
+ this.startAnimation();
11073
+ }
11074
+ }
11075
+ }
11076
+ onDoubleClick() {
11077
+ if (!this.isVisible())
11078
+ return;
11079
+ if (this.zoomLevel() > 1) {
11080
+ this.resetZoom();
11081
+ }
11082
+ else {
11083
+ this.zoomLevel.set(2);
11084
+ this.translateX.set(0);
11085
+ this.translateY.set(0);
11086
+ this.velocityX = 0;
11087
+ this.velocityY = 0;
11088
+ this.stopAnimation();
11089
+ }
11090
+ }
11091
+ getHolderTransform() {
11092
+ return `scale(${this.zoomLevel()}) translate(${this.translateX()}px, ${this.translateY()}px)`;
11093
+ }
11094
+ getCursor() {
11095
+ if (this.zoomLevel() > 1) {
11096
+ return this.isDragging() ? 'grabbing' : 'grab';
11097
+ }
11098
+ return 'zoom-in';
11099
+ }
11100
+ handleKeydown(event) {
11101
+ if (event.key === 'Escape' && this.isVisible()) {
11102
+ this.closeModal();
11103
+ }
11104
+ }
11105
+ onDocumentMouseMove(event) {
11106
+ this.onMouseMove(event);
11107
+ }
11108
+ onDocumentMouseUp() {
11109
+ this.onMouseUp();
11110
+ }
11111
+ onTouchStart(event) {
11112
+ if (!this.isVisible() || this.zoomLevel() <= 1)
11113
+ return;
11114
+ event.preventDefault();
11115
+ const touch = event.touches[0];
11116
+ this.isDragging.set(true);
11117
+ this.lastMouseX.set(touch.clientX);
11118
+ this.lastMouseY.set(touch.clientY);
11119
+ this.velocityX = 0;
11120
+ this.velocityY = 0;
11121
+ }
11122
+ onTouchMove(event) {
11123
+ if (!this.isDragging() || !this.isVisible())
11124
+ return;
11125
+ event.preventDefault();
11126
+ const touch = event.touches[0];
11127
+ const deltaX = touch.clientX - this.lastMouseX();
11128
+ const deltaY = touch.clientY - this.lastMouseY();
11129
+ const newX = this.translateX() + deltaX;
11130
+ const newY = this.translateY() + deltaY;
11131
+ this.translateX.set(newX);
11132
+ this.translateY.set(newY);
11133
+ this.velocityX = deltaX * 0.5;
11134
+ this.velocityY = deltaY * 0.5;
11135
+ this.lastMouseX.set(touch.clientX);
11136
+ this.lastMouseY.set(touch.clientY);
11137
+ }
11138
+ onTouchEnd() {
11139
+ if (this.isDragging()) {
11140
+ this.isDragging.set(false);
11141
+ if (Math.abs(this.velocityX) > 1 || Math.abs(this.velocityY) > 1) {
11142
+ this.startAnimation();
11143
+ }
11144
+ }
11145
+ }
11146
+ ngOnDestroy() {
11147
+ this.stopAnimation();
11148
+ document.body.style.overflow = '';
11149
+ }
11150
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ImageModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11151
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.0.6", type: ImageModalComponent, isStandalone: true, selector: "core-image-modal", outputs: { modalClosed: "modalClosed" }, host: { listeners: { "document:keydown": "handleKeydown($event)", "document:mousemove": "onDocumentMouseMove($event)", "document:mouseup": "onDocumentMouseUp()" } }, viewQueries: [{ propertyName: "modalImage", first: true, predicate: ["modalImage"], descendants: true }, { propertyName: "imageContainer", first: true, predicate: ["imageContainer"], descendants: true }], hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "<div class=\"c-img-modal js-img-modal\" [class.is-visible]=\"isVisible()\">\n <span class=\"c-img-modal__close icon-cross-thin js-gallery-modal-close\" (click)=\"closeModal()\"></span>\n <div class=\"c-img-modal__overlay js-img-modal-close\" (click)=\"closeModal()\"></div>\n <div \n class=\"c-img-modal__holder\" \n #imageContainer\n [style.transform]=\"getHolderTransform()\"\n [style.cursor]=\"getCursor()\"\n (mousedown)=\"onMouseDown($event)\"\n (wheel)=\"onWheel($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd()\"\n (dblclick)=\"onDoubleClick()\">\n <img \n #modalImage\n [src]=\"currentImage()?.src || ''\" \n [alt]=\"currentImage()?.alt || 'Imagen ampliada'\" \n [title]=\"currentImage()?.title || ''\"\n class=\"js-img-modal-img\"\n draggable=\"false\">\n </div>\n</div>\n", styles: [".c-img-modal__holder{transform-origin:center center;overflow:visible;will-change:transform}.c-img-modal__holder img{transform-origin:center center;-webkit-user-select:none;user-select:none;-webkit-user-drag:none;-moz-user-select:none;-ms-user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}.c-img-modal__holder[style*=transform]{backface-visibility:hidden;perspective:1000px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
11152
+ }
11153
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ImageModalComponent, decorators: [{
11154
+ type: Component,
11155
+ args: [{ selector: 'core-image-modal', standalone: true, imports: [CommonModule], hostDirectives: [CoreHostDirective], template: "<div class=\"c-img-modal js-img-modal\" [class.is-visible]=\"isVisible()\">\n <span class=\"c-img-modal__close icon-cross-thin js-gallery-modal-close\" (click)=\"closeModal()\"></span>\n <div class=\"c-img-modal__overlay js-img-modal-close\" (click)=\"closeModal()\"></div>\n <div \n class=\"c-img-modal__holder\" \n #imageContainer\n [style.transform]=\"getHolderTransform()\"\n [style.cursor]=\"getCursor()\"\n (mousedown)=\"onMouseDown($event)\"\n (wheel)=\"onWheel($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd()\"\n (dblclick)=\"onDoubleClick()\">\n <img \n #modalImage\n [src]=\"currentImage()?.src || ''\" \n [alt]=\"currentImage()?.alt || 'Imagen ampliada'\" \n [title]=\"currentImage()?.title || ''\"\n class=\"js-img-modal-img\"\n draggable=\"false\">\n </div>\n</div>\n", styles: [".c-img-modal__holder{transform-origin:center center;overflow:visible;will-change:transform}.c-img-modal__holder img{transform-origin:center center;-webkit-user-select:none;user-select:none;-webkit-user-drag:none;-moz-user-select:none;-ms-user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}.c-img-modal__holder[style*=transform]{backface-visibility:hidden;perspective:1000px}\n"] }]
11156
+ }], ctorParameters: () => [], propDecorators: { modalImage: [{
11157
+ type: ViewChild,
11158
+ args: ['modalImage', { static: false }]
11159
+ }], imageContainer: [{
11160
+ type: ViewChild,
11161
+ args: ['imageContainer', { static: false }]
11162
+ }], handleKeydown: [{
11163
+ type: HostListener,
11164
+ args: ['document:keydown', ['$event']]
11165
+ }], onDocumentMouseMove: [{
11166
+ type: HostListener,
11167
+ args: ['document:mousemove', ['$event']]
11168
+ }], onDocumentMouseUp: [{
11169
+ type: HostListener,
11170
+ args: ['document:mouseup']
11171
+ }] } });
11172
+
10872
11173
  class LayoutComponent {
10873
11174
  navItems = input([]);
10874
11175
  bottomNavItems = input([]);
@@ -11039,7 +11340,7 @@ class LayoutComponent {
11039
11340
  this.onLogout.emit();
11040
11341
  }
11041
11342
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: LayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11042
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: LayoutComponent, isStandalone: true, selector: "core-layout", inputs: { navItems: { classPropertyName: "navItems", publicName: "navItems", isSignal: true, isRequired: false, transformFunction: null }, bottomNavItems: { classPropertyName: "bottomNavItems", publicName: "bottomNavItems", isSignal: true, isRequired: false, transformFunction: null }, collapsedLogo: { classPropertyName: "collapsedLogo", publicName: "collapsedLogo", isSignal: true, isRequired: false, transformFunction: null }, expandedLogo: { classPropertyName: "expandedLogo", publicName: "expandedLogo", isSignal: true, isRequired: false, transformFunction: null }, logoImagesConfig: { classPropertyName: "logoImagesConfig", publicName: "logoImagesConfig", isSignal: true, isRequired: false, transformFunction: null }, navConfig: { classPropertyName: "navConfig", publicName: "navConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onLogout: "onLogout" }, host: { listeners: { "window:resize": "onResize($event)" } }, hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "<div class=\"o-layout\" \n [attr.data-layout]=\"layoutService.dataAttributes()['data-layout']\"\n [attr.data-sidebar-left]=\"getEffectiveLeftSidebarVisibility()\"\n [attr.data-sidebar-left-w]=\"getEffectiveLeftSidebarWidth()\"\n [attr.data-sidebar-left-h]=\"getEffectiveLeftSidebarHeight()\"\n [attr.data-sidebar-right]=\"getEffectiveRightSidebarVisibility()\"\n [attr.data-sidebar-right-w]=\"getEffectiveRightSidebarWidth()\"\n [attr.data-sidebar-right-h]=\"getEffectiveRightSidebarHeight()\"\n >\n\n <!-- Nav -->\n <core-main-nav class=\"o-layout__nav\" \n (toggleSidebar)=\"toggleSidebar()\"\n [navItems]=\"navItems()\"\n [navConfig]=\"navConfig()\"\n [bottomNavItems]=\"bottomNavItems()\"\n [logoImagesConfig]=\"logoImagesConfig()\"\n [collapsedLogo]=\"collapsedLogo()\"\n [expandedLogo]=\"expandedLogo()\"\n (onLogout)=\"logout()\"\n >\n </core-main-nav>\n\n <!-- Main -->\n <div class=\"o-layout__body\">\n \n @if(layoutStateService.isHeaderVisible$() | async) {\n <core-header\n class=\"o-layout__header\"\n (filterRequested)=\"onFilterRequested()\"\n (createRequested)=\"onCreateRequested()\"\n (globalActionTriggered)=\"onGlobalActionTriggered($event)\">\n </core-header>\n }\n\n @if(layoutService.sidebarLeft().visibility === SidebarVisibility.SHOW && leftSidebarConfig && shouldRenderLeftSidebar()) {\n <core-generic-sidebar \n class=\"o-layout__sidebar--left\"\n [config]=\"leftSidebarConfig\">\n </core-generic-sidebar>\n }\n\n <ng-content></ng-content>\n\n @if(layoutService.sidebarRight().visibility === SidebarVisibility.SHOW && rightSidebarConfig && shouldRenderRightSidebar()) {\n <core-generic-sidebar \n class=\"o-layout__sidebar--right\"\n [config]=\"rightSidebarConfig\">\n </core-generic-sidebar>\n }\n\n\n @if(dialogService.isOpen$()) {\n <core-confirmation-dialog\n [isOpen]=\"dialogService.isOpen$()\"\n [config]=\"dialogService.config$()\"\n (confirm)=\"dialogService.confirm($event)\"\n (cancel)=\"dialogService.cancel()\"\n ></core-confirmation-dialog>\n }\n\n @if(sidebarMobileModalService.isOpen()) {\n <core-generic-modal\n [isOpen]=\"sidebarMobileModalService.isOpen()\"\n [mode]=\"ModalMode.CREATE\"\n [title]=\"getSidebarModalTitle()\"\n [customTemplate]=\"sidebarModalContentTemplate\"\n (close)=\"sidebarMobileModalService.closeModal()\"\n [buttonConfig]=\"getSidebarModalButtons()\">\n </core-generic-modal>\n }\n\n </div> <!-- .o-layout__body -->\n</div> <!-- .o-layout -->\n\n<!-- Sidebar Custom Modal Global -->\n<core-sidebar-custom-modal></core-sidebar-custom-modal>\n\n<!-- ! Refactor: End -->", dependencies: [{ kind: "component", type: MainNavComponent, selector: "core-main-nav", inputs: ["navConfig", "appVersion", "navItems", "bottomNavItems", "isProduction", "logoImagesConfig", "collapsedLogo", "expandedLogo"], outputs: ["onLogout"] }, { kind: "component", type: HeaderComponent, selector: "core-header", outputs: ["filterRequested", "createRequested", "globalActionTriggered"] }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "component", type: ConfirmationDialogComponent, selector: "core-confirmation-dialog", inputs: ["isOpen", "config"], outputs: ["confirm", "cancel"] }, { kind: "component", type: GenericSidebarComponent, selector: "core-generic-sidebar", inputs: ["config", "position", "customTemplate"], outputs: ["itemClicked", "subItemClicked"] }, { 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: SidebarCustomModalComponent, selector: "core-sidebar-custom-modal" }] });
11343
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: LayoutComponent, isStandalone: true, selector: "core-layout", inputs: { navItems: { classPropertyName: "navItems", publicName: "navItems", isSignal: true, isRequired: false, transformFunction: null }, bottomNavItems: { classPropertyName: "bottomNavItems", publicName: "bottomNavItems", isSignal: true, isRequired: false, transformFunction: null }, collapsedLogo: { classPropertyName: "collapsedLogo", publicName: "collapsedLogo", isSignal: true, isRequired: false, transformFunction: null }, expandedLogo: { classPropertyName: "expandedLogo", publicName: "expandedLogo", isSignal: true, isRequired: false, transformFunction: null }, logoImagesConfig: { classPropertyName: "logoImagesConfig", publicName: "logoImagesConfig", isSignal: true, isRequired: false, transformFunction: null }, navConfig: { classPropertyName: "navConfig", publicName: "navConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onLogout: "onLogout" }, host: { listeners: { "window:resize": "onResize($event)" } }, hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "<div class=\"o-layout\" \n [attr.data-layout]=\"layoutService.dataAttributes()['data-layout']\"\n [attr.data-sidebar-left]=\"getEffectiveLeftSidebarVisibility()\"\n [attr.data-sidebar-left-w]=\"getEffectiveLeftSidebarWidth()\"\n [attr.data-sidebar-left-h]=\"getEffectiveLeftSidebarHeight()\"\n [attr.data-sidebar-right]=\"getEffectiveRightSidebarVisibility()\"\n [attr.data-sidebar-right-w]=\"getEffectiveRightSidebarWidth()\"\n [attr.data-sidebar-right-h]=\"getEffectiveRightSidebarHeight()\"\n >\n\n <!-- Nav -->\n <core-main-nav class=\"o-layout__nav\" \n (toggleSidebar)=\"toggleSidebar()\"\n [navItems]=\"navItems()\"\n [navConfig]=\"navConfig()\"\n [bottomNavItems]=\"bottomNavItems()\"\n [logoImagesConfig]=\"logoImagesConfig()\"\n [collapsedLogo]=\"collapsedLogo()\"\n [expandedLogo]=\"expandedLogo()\"\n (onLogout)=\"logout()\"\n >\n </core-main-nav>\n\n <!-- Main -->\n <div class=\"o-layout__body\">\n \n @if(layoutStateService.isHeaderVisible$() | async) {\n <core-header\n class=\"o-layout__header\"\n (filterRequested)=\"onFilterRequested()\"\n (createRequested)=\"onCreateRequested()\"\n (globalActionTriggered)=\"onGlobalActionTriggered($event)\">\n </core-header>\n }\n\n @if(layoutService.sidebarLeft().visibility === SidebarVisibility.SHOW && leftSidebarConfig && shouldRenderLeftSidebar()) {\n <core-generic-sidebar \n class=\"o-layout__sidebar--left\"\n [config]=\"leftSidebarConfig\">\n </core-generic-sidebar>\n }\n\n <ng-content></ng-content>\n\n @if(layoutService.sidebarRight().visibility === SidebarVisibility.SHOW && rightSidebarConfig && shouldRenderRightSidebar()) {\n <core-generic-sidebar \n class=\"o-layout__sidebar--right\"\n [config]=\"rightSidebarConfig\">\n </core-generic-sidebar>\n }\n\n\n @if(dialogService.isOpen$()) {\n <core-confirmation-dialog\n [isOpen]=\"dialogService.isOpen$()\"\n [config]=\"dialogService.config$()\"\n (confirm)=\"dialogService.confirm($event)\"\n (cancel)=\"dialogService.cancel()\"\n ></core-confirmation-dialog>\n }\n\n @if(sidebarMobileModalService.isOpen()) {\n <core-generic-modal\n [isOpen]=\"sidebarMobileModalService.isOpen()\"\n [mode]=\"ModalMode.CREATE\"\n [title]=\"getSidebarModalTitle()\"\n [customTemplate]=\"sidebarModalContentTemplate\"\n (close)=\"sidebarMobileModalService.closeModal()\"\n [buttonConfig]=\"getSidebarModalButtons()\">\n </core-generic-modal>\n }\n\n </div> <!-- .o-layout__body -->\n</div> <!-- .o-layout -->\n\n<!-- Sidebar Custom Modal Global -->\n<core-sidebar-custom-modal></core-sidebar-custom-modal>\n\n<!-- Image Modal Global -->\n<core-image-modal></core-image-modal>\n\n<!-- ! Refactor: End -->", dependencies: [{ kind: "component", type: MainNavComponent, selector: "core-main-nav", inputs: ["navConfig", "appVersion", "navItems", "bottomNavItems", "isProduction", "logoImagesConfig", "collapsedLogo", "expandedLogo"], outputs: ["onLogout"] }, { kind: "component", type: HeaderComponent, selector: "core-header", outputs: ["filterRequested", "createRequested", "globalActionTriggered"] }, { kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "component", type: ConfirmationDialogComponent, selector: "core-confirmation-dialog", inputs: ["isOpen", "config"], outputs: ["confirm", "cancel"] }, { kind: "component", type: GenericSidebarComponent, selector: "core-generic-sidebar", inputs: ["config", "position", "customTemplate"], outputs: ["itemClicked", "subItemClicked"] }, { 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: ImageModalComponent, selector: "core-image-modal", outputs: ["modalClosed"] }, { kind: "component", type: SidebarCustomModalComponent, selector: "core-sidebar-custom-modal" }] });
11043
11344
  }
11044
11345
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: LayoutComponent, decorators: [{
11045
11346
  type: Component,
@@ -11050,8 +11351,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
11050
11351
  ConfirmationDialogComponent,
11051
11352
  GenericSidebarComponent,
11052
11353
  GenericModalComponent,
11354
+ ImageModalComponent,
11053
11355
  SidebarCustomModalComponent
11054
- ], hostDirectives: [CoreHostDirective], template: "<div class=\"o-layout\" \n [attr.data-layout]=\"layoutService.dataAttributes()['data-layout']\"\n [attr.data-sidebar-left]=\"getEffectiveLeftSidebarVisibility()\"\n [attr.data-sidebar-left-w]=\"getEffectiveLeftSidebarWidth()\"\n [attr.data-sidebar-left-h]=\"getEffectiveLeftSidebarHeight()\"\n [attr.data-sidebar-right]=\"getEffectiveRightSidebarVisibility()\"\n [attr.data-sidebar-right-w]=\"getEffectiveRightSidebarWidth()\"\n [attr.data-sidebar-right-h]=\"getEffectiveRightSidebarHeight()\"\n >\n\n <!-- Nav -->\n <core-main-nav class=\"o-layout__nav\" \n (toggleSidebar)=\"toggleSidebar()\"\n [navItems]=\"navItems()\"\n [navConfig]=\"navConfig()\"\n [bottomNavItems]=\"bottomNavItems()\"\n [logoImagesConfig]=\"logoImagesConfig()\"\n [collapsedLogo]=\"collapsedLogo()\"\n [expandedLogo]=\"expandedLogo()\"\n (onLogout)=\"logout()\"\n >\n </core-main-nav>\n\n <!-- Main -->\n <div class=\"o-layout__body\">\n \n @if(layoutStateService.isHeaderVisible$() | async) {\n <core-header\n class=\"o-layout__header\"\n (filterRequested)=\"onFilterRequested()\"\n (createRequested)=\"onCreateRequested()\"\n (globalActionTriggered)=\"onGlobalActionTriggered($event)\">\n </core-header>\n }\n\n @if(layoutService.sidebarLeft().visibility === SidebarVisibility.SHOW && leftSidebarConfig && shouldRenderLeftSidebar()) {\n <core-generic-sidebar \n class=\"o-layout__sidebar--left\"\n [config]=\"leftSidebarConfig\">\n </core-generic-sidebar>\n }\n\n <ng-content></ng-content>\n\n @if(layoutService.sidebarRight().visibility === SidebarVisibility.SHOW && rightSidebarConfig && shouldRenderRightSidebar()) {\n <core-generic-sidebar \n class=\"o-layout__sidebar--right\"\n [config]=\"rightSidebarConfig\">\n </core-generic-sidebar>\n }\n\n\n @if(dialogService.isOpen$()) {\n <core-confirmation-dialog\n [isOpen]=\"dialogService.isOpen$()\"\n [config]=\"dialogService.config$()\"\n (confirm)=\"dialogService.confirm($event)\"\n (cancel)=\"dialogService.cancel()\"\n ></core-confirmation-dialog>\n }\n\n @if(sidebarMobileModalService.isOpen()) {\n <core-generic-modal\n [isOpen]=\"sidebarMobileModalService.isOpen()\"\n [mode]=\"ModalMode.CREATE\"\n [title]=\"getSidebarModalTitle()\"\n [customTemplate]=\"sidebarModalContentTemplate\"\n (close)=\"sidebarMobileModalService.closeModal()\"\n [buttonConfig]=\"getSidebarModalButtons()\">\n </core-generic-modal>\n }\n\n </div> <!-- .o-layout__body -->\n</div> <!-- .o-layout -->\n\n<!-- Sidebar Custom Modal Global -->\n<core-sidebar-custom-modal></core-sidebar-custom-modal>\n\n<!-- ! Refactor: End -->" }]
11356
+ ], hostDirectives: [CoreHostDirective], template: "<div class=\"o-layout\" \n [attr.data-layout]=\"layoutService.dataAttributes()['data-layout']\"\n [attr.data-sidebar-left]=\"getEffectiveLeftSidebarVisibility()\"\n [attr.data-sidebar-left-w]=\"getEffectiveLeftSidebarWidth()\"\n [attr.data-sidebar-left-h]=\"getEffectiveLeftSidebarHeight()\"\n [attr.data-sidebar-right]=\"getEffectiveRightSidebarVisibility()\"\n [attr.data-sidebar-right-w]=\"getEffectiveRightSidebarWidth()\"\n [attr.data-sidebar-right-h]=\"getEffectiveRightSidebarHeight()\"\n >\n\n <!-- Nav -->\n <core-main-nav class=\"o-layout__nav\" \n (toggleSidebar)=\"toggleSidebar()\"\n [navItems]=\"navItems()\"\n [navConfig]=\"navConfig()\"\n [bottomNavItems]=\"bottomNavItems()\"\n [logoImagesConfig]=\"logoImagesConfig()\"\n [collapsedLogo]=\"collapsedLogo()\"\n [expandedLogo]=\"expandedLogo()\"\n (onLogout)=\"logout()\"\n >\n </core-main-nav>\n\n <!-- Main -->\n <div class=\"o-layout__body\">\n \n @if(layoutStateService.isHeaderVisible$() | async) {\n <core-header\n class=\"o-layout__header\"\n (filterRequested)=\"onFilterRequested()\"\n (createRequested)=\"onCreateRequested()\"\n (globalActionTriggered)=\"onGlobalActionTriggered($event)\">\n </core-header>\n }\n\n @if(layoutService.sidebarLeft().visibility === SidebarVisibility.SHOW && leftSidebarConfig && shouldRenderLeftSidebar()) {\n <core-generic-sidebar \n class=\"o-layout__sidebar--left\"\n [config]=\"leftSidebarConfig\">\n </core-generic-sidebar>\n }\n\n <ng-content></ng-content>\n\n @if(layoutService.sidebarRight().visibility === SidebarVisibility.SHOW && rightSidebarConfig && shouldRenderRightSidebar()) {\n <core-generic-sidebar \n class=\"o-layout__sidebar--right\"\n [config]=\"rightSidebarConfig\">\n </core-generic-sidebar>\n }\n\n\n @if(dialogService.isOpen$()) {\n <core-confirmation-dialog\n [isOpen]=\"dialogService.isOpen$()\"\n [config]=\"dialogService.config$()\"\n (confirm)=\"dialogService.confirm($event)\"\n (cancel)=\"dialogService.cancel()\"\n ></core-confirmation-dialog>\n }\n\n @if(sidebarMobileModalService.isOpen()) {\n <core-generic-modal\n [isOpen]=\"sidebarMobileModalService.isOpen()\"\n [mode]=\"ModalMode.CREATE\"\n [title]=\"getSidebarModalTitle()\"\n [customTemplate]=\"sidebarModalContentTemplate\"\n (close)=\"sidebarMobileModalService.closeModal()\"\n [buttonConfig]=\"getSidebarModalButtons()\">\n </core-generic-modal>\n }\n\n </div> <!-- .o-layout__body -->\n</div> <!-- .o-layout -->\n\n<!-- Sidebar Custom Modal Global -->\n<core-sidebar-custom-modal></core-sidebar-custom-modal>\n\n<!-- Image Modal Global -->\n<core-image-modal></core-image-modal>\n\n<!-- ! Refactor: End -->" }]
11055
11357
  }], propDecorators: { onResize: [{
11056
11358
  type: HostListener,
11057
11359
  args: ['window:resize', ['$event']]
@@ -11733,236 +12035,460 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
11733
12035
  }]
11734
12036
  }] });
11735
12037
 
11736
- class ImageModalComponent {
11737
- modalImage;
11738
- imageContainer;
11739
- isVisible = input(false);
11740
- imageSrc = input('');
11741
- imageAlt = input('Imagen Ampliada');
11742
- modalClosed = output();
11743
- zoomLevel = signal(1);
12038
+ var SliderActionType;
12039
+ (function (SliderActionType) {
12040
+ SliderActionType["CLICK"] = "click";
12041
+ SliderActionType["CHANGE"] = "change";
12042
+ SliderActionType["BEFORE_CHANGE"] = "beforeChange";
12043
+ SliderActionType["AFTER_CHANGE"] = "afterChange";
12044
+ SliderActionType["EDGE"] = "edge";
12045
+ SliderActionType["SWIPE"] = "swipe";
12046
+ })(SliderActionType || (SliderActionType = {}));
12047
+
12048
+ class SliderService {
12049
+ currentIndex = signal(0);
12050
+ items = signal([]);
12051
+ config = signal({});
12052
+ getCurrentIndex = computed(() => this.currentIndex());
12053
+ getItems = computed(() => this.items());
12054
+ getConfig = computed(() => this.config());
12055
+ getTotalItems = computed(() => this.items().length);
12056
+ getNavigation = computed(() => {
12057
+ const current = this.currentIndex();
12058
+ const total = this.items().length;
12059
+ const infinite = this.config().infinite ?? false;
12060
+ return {
12061
+ currentIndex: current,
12062
+ totalItems: total,
12063
+ canGoPrev: infinite || current > 0,
12064
+ canGoNext: infinite || current < total - 1
12065
+ };
12066
+ });
12067
+ getCurrentItem = computed(() => {
12068
+ const items = this.items();
12069
+ const index = this.currentIndex();
12070
+ return items[index] || null;
12071
+ });
12072
+ setItems(items) {
12073
+ this.items.set(items);
12074
+ if (this.currentIndex() >= items.length) {
12075
+ this.currentIndex.set(Math.max(0, items.length - 1));
12076
+ }
12077
+ }
12078
+ setConfig(config) {
12079
+ this.config.set(config);
12080
+ }
12081
+ goToSlide(index) {
12082
+ const items = this.items();
12083
+ if (index >= 0 && index < items.length) {
12084
+ this.currentIndex.set(index);
12085
+ }
12086
+ }
12087
+ nextSlide() {
12088
+ const current = this.currentIndex();
12089
+ const total = this.items().length;
12090
+ const infinite = this.config().infinite ?? false;
12091
+ if (infinite) {
12092
+ this.currentIndex.set((current + 1) % total);
12093
+ }
12094
+ else if (current < total - 1) {
12095
+ this.currentIndex.set(current + 1);
12096
+ }
12097
+ }
12098
+ prevSlide() {
12099
+ const current = this.currentIndex();
12100
+ const total = this.items().length;
12101
+ const infinite = this.config().infinite ?? false;
12102
+ if (infinite) {
12103
+ this.currentIndex.set(current === 0 ? total - 1 : current - 1);
12104
+ }
12105
+ else if (current > 0) {
12106
+ this.currentIndex.set(current - 1);
12107
+ }
12108
+ }
12109
+ reset() {
12110
+ this.currentIndex.set(0);
12111
+ }
12112
+ getSlidesByConfig() {
12113
+ const items = this.items();
12114
+ const slidesToShow = this.config().slidesToShow ?? 1;
12115
+ const currentIndex = this.currentIndex();
12116
+ if (slidesToShow === 1) {
12117
+ return [items[currentIndex]].filter(Boolean);
12118
+ }
12119
+ const result = [];
12120
+ for (let i = 0; i < slidesToShow; i++) {
12121
+ const index = (currentIndex + i) % items.length;
12122
+ if (items[index]) {
12123
+ result.push(items[index]);
12124
+ }
12125
+ }
12126
+ return result;
12127
+ }
12128
+ getThumbnails() {
12129
+ return this.items().map(item => ({
12130
+ ...item,
12131
+ imageUrl: item.thumbnailUrl || item.imageUrl
12132
+ }));
12133
+ }
12134
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SliderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
12135
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SliderService, providedIn: 'root' });
12136
+ }
12137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: SliderService, decorators: [{
12138
+ type: Injectable,
12139
+ args: [{
12140
+ providedIn: 'root'
12141
+ }]
12142
+ }] });
12143
+
12144
+ class GenericSliderComponent {
12145
+ sliderService = inject(SliderService);
12146
+ autoPlayInterval = null;
12147
+ items = input([]);
12148
+ config = input({
12149
+ autoPlay: false,
12150
+ autoPlayInterval: 3000,
12151
+ showDots: true,
12152
+ showArrows: true,
12153
+ showThumbnails: false,
12154
+ infinite: true,
12155
+ slidesToShow: 1,
12156
+ slidesToScroll: 1,
12157
+ centerMode: false,
12158
+ height: '400px',
12159
+ thumbnailHeight: '80px',
12160
+ showPreview: true,
12161
+ enableKeyboard: true,
12162
+ swipeToSlide: true,
12163
+ pauseOnHover: true,
12164
+ showCounter: false,
12165
+ lazyLoad: true,
12166
+ fadeEffect: false,
12167
+ verticalThumbnails: false
12168
+ });
12169
+ actionTriggered = output();
12170
+ slideChanged = output();
12171
+ isHovered = signal(false);
11744
12172
  isDragging = signal(false);
11745
- lastMouseX = signal(0);
11746
- lastMouseY = signal(0);
11747
- translateX = signal(0);
11748
- translateY = signal(0);
11749
- minZoom = 1;
11750
- maxZoom = 3;
11751
- zoomStep = 0.2;
11752
- targetTranslateX = 0;
11753
- targetTranslateY = 0;
11754
- velocityX = 0;
11755
- velocityY = 0;
11756
- friction = 0.9;
11757
- animationId = null;
12173
+ startX = signal(0);
12174
+ currentX = signal(0);
12175
+ currentIndex = computed(() => this.sliderService.getCurrentIndex());
12176
+ totalItems = computed(() => this.sliderService.getTotalItems());
12177
+ currentItem = computed(() => this.sliderService.getCurrentItem());
12178
+ navigation = computed(() => this.sliderService.getNavigation());
12179
+ visibleSlides = computed(() => this.sliderService.getSlidesByConfig());
12180
+ thumbnails = computed(() => this.sliderService.getThumbnails());
12181
+ mergedConfig = computed(() => ({
12182
+ ...this.config(),
12183
+ ...this.sliderService.getConfig()
12184
+ }));
12185
+ canAutoPlay = computed(() => {
12186
+ const config = this.mergedConfig();
12187
+ return config.autoPlay && !this.isHovered() && !this.isDragging();
12188
+ });
12189
+ showDots = computed(() => this.mergedConfig().showDots && this.totalItems() > 1);
12190
+ showArrows = computed(() => this.mergedConfig().showArrows && this.totalItems() > 1);
12191
+ showThumbnails = computed(() => this.mergedConfig().showThumbnails && this.totalItems() > 1);
12192
+ showCounter = computed(() => this.mergedConfig().showCounter && this.totalItems() > 1);
12193
+ containerStyles = computed(() => ({
12194
+ height: this.mergedConfig().height || '400px',
12195
+ position: 'relative',
12196
+ overflow: 'hidden'
12197
+ }));
12198
+ slideStyles = computed(() => {
12199
+ const config = this.mergedConfig();
12200
+ const slidesToShow = config.slidesToShow || 1;
12201
+ const currentIndex = this.currentIndex();
12202
+ const totalItems = this.totalItems();
12203
+ const totalWidth = (totalItems / slidesToShow) * 100;
12204
+ const slideWidth = 100 / slidesToShow;
12205
+ const translateX = -(currentIndex * slideWidth);
12206
+ return {
12207
+ transform: `translateX(${translateX}%)`,
12208
+ transition: this.isDragging() ? 'none' : 'transform 0.3s ease-in-out',
12209
+ display: 'flex',
12210
+ width: `${totalWidth}%`
12211
+ };
12212
+ });
12213
+ prevButtonConfig = computed(() => ({
12214
+ type: ButtonType.PRIMARY,
12215
+ context: ButtonContext.DEFAULT,
12216
+ size: ButtonSize.SMALL,
12217
+ text: '',
12218
+ icon: 'icon-arrow-left',
12219
+ disabled: !this.navigation().canGoPrev,
12220
+ ariaLabel: 'slider.previous'
12221
+ }));
12222
+ nextButtonConfig = computed(() => ({
12223
+ type: ButtonType.PRIMARY,
12224
+ context: ButtonContext.DEFAULT,
12225
+ size: ButtonSize.SMALL,
12226
+ text: '',
12227
+ icon: 'icon-arrow-right',
12228
+ disabled: !this.navigation().canGoNext,
12229
+ ariaLabel: 'slider.next'
12230
+ }));
11758
12231
  constructor() {
11759
12232
  effect(() => {
11760
- if (this.isVisible()) {
11761
- document.body.style.overflow = 'hidden';
11762
- this.resetZoom();
11763
- }
11764
- else {
11765
- document.body.style.overflow = '';
11766
- this.resetZoom();
11767
- this.stopAnimation();
12233
+ this.sliderService.setItems(this.items());
12234
+ });
12235
+ effect(() => {
12236
+ this.sliderService.setConfig(this.config());
12237
+ });
12238
+ effect(() => {
12239
+ const currentIndex = this.currentIndex();
12240
+ const currentItem = this.currentItem();
12241
+ if (currentItem) {
12242
+ this.slideChanged.emit({ currentIndex, currentItem });
11768
12243
  }
11769
12244
  });
11770
- }
11771
- startAnimation() {
11772
- if (this.animationId)
11773
- return;
11774
- const animate = () => {
11775
- if (!this.isDragging()) {
11776
- const currentX = this.translateX();
11777
- const currentY = this.translateY();
11778
- const newX = currentX + this.velocityX;
11779
- const newY = currentY + this.velocityY;
11780
- this.translateX.set(newX);
11781
- this.translateY.set(newY);
11782
- this.velocityX *= this.friction;
11783
- this.velocityY *= this.friction;
11784
- if (Math.abs(this.velocityX) < 0.1 && Math.abs(this.velocityY) < 0.1) {
11785
- this.velocityX = 0;
11786
- this.velocityY = 0;
11787
- this.animationId = null;
11788
- return;
11789
- }
11790
- this.animationId = requestAnimationFrame(animate);
12245
+ effect(() => {
12246
+ if (this.canAutoPlay()) {
12247
+ this.startAutoPlay();
11791
12248
  }
11792
12249
  else {
11793
- this.animationId = null;
12250
+ this.stopAutoPlay();
11794
12251
  }
11795
- };
11796
- this.animationId = requestAnimationFrame(animate);
11797
- }
11798
- stopAnimation() {
11799
- if (this.animationId) {
11800
- cancelAnimationFrame(this.animationId);
11801
- this.animationId = null;
11802
- }
11803
- this.velocityX = 0;
11804
- this.velocityY = 0;
12252
+ });
11805
12253
  }
11806
- resetZoom() {
11807
- this.zoomLevel.set(1);
11808
- this.translateX.set(0);
11809
- this.translateY.set(0);
11810
- this.isDragging.set(false);
11811
- this.velocityX = 0;
11812
- this.velocityY = 0;
11813
- this.stopAnimation();
12254
+ ngOnInit() {
12255
+ this.setupAutoPlay();
11814
12256
  }
11815
- closeModal() {
11816
- this.resetZoom();
11817
- this.modalClosed.emit();
12257
+ ngOnDestroy() {
12258
+ this.stopAutoPlay();
11818
12259
  }
11819
- onWheel(event) {
11820
- if (!this.isVisible())
12260
+ onKeydown(event) {
12261
+ if (!this.mergedConfig().enableKeyboard)
11821
12262
  return;
11822
- event.preventDefault();
11823
- event.stopPropagation();
11824
- const delta = event.deltaY > 0 ? -this.zoomStep : this.zoomStep;
11825
- const newZoom = Math.min(Math.max(this.zoomLevel() + delta, this.minZoom), this.maxZoom);
11826
- if (newZoom !== this.zoomLevel()) {
11827
- this.zoomLevel.set(newZoom);
11828
- if (newZoom === 1) {
11829
- this.translateX.set(0);
11830
- this.translateY.set(0);
11831
- this.velocityX = 0;
11832
- this.velocityY = 0;
11833
- }
12263
+ switch (event.key) {
12264
+ case 'ArrowLeft':
12265
+ event.preventDefault();
12266
+ this.goToPrevious();
12267
+ break;
12268
+ case 'ArrowRight':
12269
+ event.preventDefault();
12270
+ this.goToNext();
12271
+ break;
12272
+ case ' ':
12273
+ event.preventDefault();
12274
+ this.toggleAutoPlay();
12275
+ break;
12276
+ case 'Home':
12277
+ event.preventDefault();
12278
+ this.goToSlide(0);
12279
+ break;
12280
+ case 'End':
12281
+ event.preventDefault();
12282
+ this.goToSlide(this.totalItems() - 1);
12283
+ break;
11834
12284
  }
11835
12285
  }
11836
- onMouseDown(event) {
11837
- if (!this.isVisible() || this.zoomLevel() <= 1)
11838
- return;
11839
- event.preventDefault();
11840
- this.isDragging.set(true);
11841
- this.lastMouseX.set(event.clientX);
11842
- this.lastMouseY.set(event.clientY);
11843
- this.velocityX = 0;
11844
- this.velocityY = 0;
11845
- }
11846
- onMouseMove(event) {
11847
- if (!this.isDragging() || !this.isVisible())
11848
- return;
11849
- event.preventDefault();
11850
- const deltaX = event.clientX - this.lastMouseX();
11851
- const deltaY = event.clientY - this.lastMouseY();
11852
- const newX = this.translateX() + deltaX;
11853
- const newY = this.translateY() + deltaY;
11854
- this.translateX.set(newX);
11855
- this.translateY.set(newY);
11856
- this.velocityX = deltaX * 0.5;
11857
- this.velocityY = deltaY * 0.5;
11858
- this.lastMouseX.set(event.clientX);
11859
- this.lastMouseY.set(event.clientY);
12286
+ goToSlide(index) {
12287
+ const previousIndex = this.currentIndex();
12288
+ this.sliderService.goToSlide(index);
12289
+ this.emitAction(SliderActionType.CHANGE, this.currentItem(), index);
12290
+ if (previousIndex !== index) {
12291
+ this.emitAction(SliderActionType.AFTER_CHANGE, this.currentItem(), index);
12292
+ }
11860
12293
  }
11861
- onMouseUp() {
11862
- if (this.isDragging()) {
11863
- this.isDragging.set(false);
11864
- if (Math.abs(this.velocityX) > 1 || Math.abs(this.velocityY) > 1) {
11865
- this.startAnimation();
11866
- }
12294
+ goToNext() {
12295
+ const config = this.mergedConfig();
12296
+ const current = this.currentIndex();
12297
+ const total = this.totalItems();
12298
+ const slidesToShow = config.slidesToShow || 1;
12299
+ const slidesToScroll = config.slidesToScroll || 1;
12300
+ let nextIndex;
12301
+ if (config.infinite) {
12302
+ nextIndex = (current + slidesToScroll) % total;
12303
+ }
12304
+ else {
12305
+ const maxIndex = Math.max(0, total - slidesToShow);
12306
+ nextIndex = Math.min(current + slidesToScroll, maxIndex);
11867
12307
  }
12308
+ this.goToSlide(nextIndex);
11868
12309
  }
11869
- onDoubleClick() {
11870
- if (!this.isVisible())
11871
- return;
11872
- if (this.zoomLevel() > 1) {
11873
- this.resetZoom();
12310
+ goToPrevious() {
12311
+ const config = this.mergedConfig();
12312
+ const current = this.currentIndex();
12313
+ const total = this.totalItems();
12314
+ const slidesToScroll = config.slidesToScroll || 1;
12315
+ let prevIndex;
12316
+ if (config.infinite) {
12317
+ prevIndex = current - slidesToScroll < 0 ? total - slidesToScroll : current - slidesToScroll;
11874
12318
  }
11875
12319
  else {
11876
- this.zoomLevel.set(2);
11877
- this.translateX.set(0);
11878
- this.translateY.set(0);
11879
- this.velocityX = 0;
11880
- this.velocityY = 0;
11881
- this.stopAnimation();
12320
+ prevIndex = Math.max(current - slidesToScroll, 0);
11882
12321
  }
12322
+ this.goToSlide(prevIndex);
11883
12323
  }
11884
- getHolderTransform() {
11885
- return `scale(${this.zoomLevel()}) translate(${this.translateX()}px, ${this.translateY()}px)`;
12324
+ setupAutoPlay() {
12325
+ if (this.mergedConfig().autoPlay) {
12326
+ this.startAutoPlay();
12327
+ }
11886
12328
  }
11887
- getCursor() {
11888
- if (this.zoomLevel() > 1) {
11889
- return this.isDragging() ? 'grabbing' : 'grab';
12329
+ startAutoPlay() {
12330
+ this.stopAutoPlay();
12331
+ if (this.canAutoPlay()) {
12332
+ this.autoPlayInterval = setInterval(() => {
12333
+ if (this.canAutoPlay()) {
12334
+ this.goToNext();
12335
+ }
12336
+ }, this.mergedConfig().autoPlayInterval || 3000);
11890
12337
  }
11891
- return 'zoom-in';
11892
12338
  }
11893
- handleKeydown(event) {
11894
- if (event.key === 'Escape' && this.isVisible()) {
11895
- this.closeModal();
12339
+ stopAutoPlay() {
12340
+ if (this.autoPlayInterval) {
12341
+ clearInterval(this.autoPlayInterval);
12342
+ this.autoPlayInterval = null;
11896
12343
  }
11897
12344
  }
11898
- onDocumentMouseMove(event) {
11899
- this.onMouseMove(event);
12345
+ toggleAutoPlay() {
12346
+ if (this.canAutoPlay()) {
12347
+ this.stopAutoPlay();
12348
+ }
12349
+ else {
12350
+ this.startAutoPlay();
12351
+ }
11900
12352
  }
11901
- onDocumentMouseUp() {
11902
- this.onMouseUp();
12353
+ onMouseEnter() {
12354
+ if (this.mergedConfig().pauseOnHover) {
12355
+ this.isHovered.set(true);
12356
+ }
12357
+ }
12358
+ onMouseLeave() {
12359
+ if (this.mergedConfig().pauseOnHover) {
12360
+ this.isHovered.set(false);
12361
+ }
11903
12362
  }
11904
12363
  onTouchStart(event) {
11905
- if (!this.isVisible() || this.zoomLevel() <= 1)
12364
+ if (!this.mergedConfig().swipeToSlide)
11906
12365
  return;
11907
- event.preventDefault();
11908
- const touch = event.touches[0];
11909
12366
  this.isDragging.set(true);
11910
- this.lastMouseX.set(touch.clientX);
11911
- this.lastMouseY.set(touch.clientY);
11912
- this.velocityX = 0;
11913
- this.velocityY = 0;
12367
+ this.startX.set(event.touches[0].clientX);
11914
12368
  }
11915
12369
  onTouchMove(event) {
11916
- if (!this.isDragging() || !this.isVisible())
12370
+ if (!this.isDragging() || !this.mergedConfig().swipeToSlide)
11917
12371
  return;
12372
+ this.currentX.set(event.touches[0].clientX);
11918
12373
  event.preventDefault();
11919
- const touch = event.touches[0];
11920
- const deltaX = touch.clientX - this.lastMouseX();
11921
- const deltaY = touch.clientY - this.lastMouseY();
11922
- const newX = this.translateX() + deltaX;
11923
- const newY = this.translateY() + deltaY;
11924
- this.translateX.set(newX);
11925
- this.translateY.set(newY);
11926
- this.velocityX = deltaX * 0.5;
11927
- this.velocityY = deltaY * 0.5;
11928
- this.lastMouseX.set(touch.clientX);
11929
- this.lastMouseY.set(touch.clientY);
11930
12374
  }
11931
12375
  onTouchEnd() {
11932
- if (this.isDragging()) {
11933
- this.isDragging.set(false);
11934
- if (Math.abs(this.velocityX) > 1 || Math.abs(this.velocityY) > 1) {
11935
- this.startAnimation();
12376
+ if (!this.isDragging() || !this.mergedConfig().swipeToSlide)
12377
+ return;
12378
+ const diffX = this.startX() - this.currentX();
12379
+ const threshold = 50;
12380
+ if (Math.abs(diffX) > threshold) {
12381
+ if (diffX > 0) {
12382
+ this.goToNext();
11936
12383
  }
12384
+ else {
12385
+ this.goToPrevious();
12386
+ }
12387
+ this.emitAction(SliderActionType.SWIPE, this.currentItem(), this.currentIndex());
11937
12388
  }
12389
+ this.isDragging.set(false);
12390
+ this.startX.set(0);
12391
+ this.currentX.set(0);
11938
12392
  }
11939
- ngOnDestroy() {
11940
- this.stopAnimation();
11941
- document.body.style.overflow = '';
12393
+ onSlideClick(item, index) {
12394
+ this.emitAction(SliderActionType.CLICK, item, index);
11942
12395
  }
11943
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ImageModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
11944
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.0.6", type: ImageModalComponent, isStandalone: true, selector: "core-image-modal", inputs: { isVisible: { classPropertyName: "isVisible", publicName: "isVisible", isSignal: true, isRequired: false, transformFunction: null }, imageSrc: { classPropertyName: "imageSrc", publicName: "imageSrc", isSignal: true, isRequired: false, transformFunction: null }, imageAlt: { classPropertyName: "imageAlt", publicName: "imageAlt", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modalClosed: "modalClosed" }, host: { listeners: { "document:keydown": "handleKeydown($event)", "document:mousemove": "onDocumentMouseMove($event)", "document:mouseup": "onDocumentMouseUp()" } }, viewQueries: [{ propertyName: "modalImage", first: true, predicate: ["modalImage"], descendants: true }, { propertyName: "imageContainer", first: true, predicate: ["imageContainer"], descendants: true }], hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "<div class=\"c-img-modal js-img-modal\" [class.is-visible]=\"isVisible()\">\n <span class=\"c-img-modal__close icon-cross-thin js-gallery-modal-close\" (click)=\"closeModal()\"></span>\n <div class=\"c-img-modal__overlay js-img-modal-close\" (click)=\"closeModal()\"></div>\n <div \n class=\"c-img-modal__holder\" \n #imageContainer\n [style.transform]=\"getHolderTransform()\"\n [style.cursor]=\"getCursor()\"\n (mousedown)=\"onMouseDown($event)\"\n (wheel)=\"onWheel($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd()\"\n (dblclick)=\"onDoubleClick()\">\n <img \n #modalImage\n [src]=\"imageSrc()\" \n [alt]=\"imageAlt()\" \n class=\"js-img-modal-img\"\n draggable=\"false\">\n </div>\n</div>\n", styles: [".c-img-modal__holder{transform-origin:center center;overflow:visible;will-change:transform}.c-img-modal__holder img{transform-origin:center center;-webkit-user-select:none;user-select:none;-webkit-user-drag:none;-moz-user-select:none;-ms-user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}.c-img-modal__holder[style*=transform]{backface-visibility:hidden;perspective:1000px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
12396
+ onDotClick(index) {
12397
+ this.goToSlide(index);
12398
+ }
12399
+ onThumbnailClick(index) {
12400
+ this.goToSlide(index);
12401
+ }
12402
+ emitAction(type, item, index) {
12403
+ this.actionTriggered.emit({ type, item, index });
12404
+ }
12405
+ getSlideImage(item) {
12406
+ return item.imageUrl || '';
12407
+ }
12408
+ getSlideAlt(item) {
12409
+ return item.alt || item.title || `Slide ${this.currentIndex() + 1}`;
12410
+ }
12411
+ isActiveSlide(index) {
12412
+ const config = this.mergedConfig();
12413
+ const current = this.currentIndex();
12414
+ const slidesToShow = config.slidesToShow || 1;
12415
+ if (slidesToShow === 1) {
12416
+ return index === current;
12417
+ }
12418
+ else {
12419
+ return index >= current && index < current + slidesToShow;
12420
+ }
12421
+ }
12422
+ isActiveDot(index) {
12423
+ return index === this.currentIndex();
12424
+ }
12425
+ isActiveThumbnail(index) {
12426
+ return index === this.currentIndex();
12427
+ }
12428
+ getCounterText() {
12429
+ return `${this.currentIndex() + 1} / ${this.totalItems()}`;
12430
+ }
12431
+ getSlideWidth() {
12432
+ const config = this.mergedConfig();
12433
+ const slidesToShow = config.slidesToShow || 1;
12434
+ const totalItems = this.totalItems();
12435
+ const widthPercentage = (100 / totalItems);
12436
+ return `${widthPercentage}%`;
12437
+ }
12438
+ getFileTypeIcon(fileType) {
12439
+ const typeMap = {
12440
+ 'pdf': 'icon-file-pdf',
12441
+ 'doc': 'icon-file-word',
12442
+ 'docx': 'icon-file-word',
12443
+ 'xls': 'icon-file-excel',
12444
+ 'xlsx': 'icon-file-excel',
12445
+ 'ppt': 'icon-file-powerpoint',
12446
+ 'pptx': 'icon-file-powerpoint',
12447
+ 'txt': 'icon-file-text',
12448
+ 'zip': 'icon-file-zip',
12449
+ 'rar': 'icon-file-zip',
12450
+ 'jpg': 'icon-file-image',
12451
+ 'jpeg': 'icon-file-image',
12452
+ 'png': 'icon-file-image',
12453
+ 'gif': 'icon-file-image',
12454
+ 'mp4': 'icon-file-video',
12455
+ 'avi': 'icon-file-video',
12456
+ 'mov': 'icon-file-video',
12457
+ 'mp3': 'icon-file-audio',
12458
+ 'wav': 'icon-file-audio'
12459
+ };
12460
+ return typeMap[fileType.toLowerCase()] || 'icon-file';
12461
+ }
12462
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: GenericSliderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12463
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: GenericSliderComponent, isStandalone: true, selector: "core-generic-slider", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { actionTriggered: "actionTriggered", slideChanged: "slideChanged" }, host: { listeners: { "keydown": "onKeydown($event)" } }, ngImport: i0, template: "<div class=\"c-slider\" \n [style]=\"containerStyles()\"\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd()\">\n \n <!-- Main slider container -->\n <div class=\"c-slider__container\">\n \n <!-- Previous arrow -->\n @if (showArrows()) {\n <div class=\"c-slider__arrow c-slider__arrow--prev\">\n <core-generic-button\n [config]=\"prevButtonConfig()\"\n (buttonClick)=\"goToPrevious()\">\n </core-generic-button>\n </div>\n }\n\n <!-- Slides wrapper -->\n <div class=\"c-slider__wrapper\">\n <div class=\"c-slider__track\" [style]=\"slideStyles()\">\n @for (slide of items(); track slide.id; let i = $index) {\n <div class=\"c-slider__slide\" \n [class.c-slider__slide--active]=\"isActiveSlide(i)\"\n [style.width]=\"getSlideWidth()\"\n (click)=\"onSlideClick(slide, i)\">\n \n <!-- Image -->\n <div class=\"c-slider__image-container\">\n @if (mergedConfig().lazyLoad) {\n <img [src]=\"getSlideImage(slide)\" \n [alt]=\"getSlideAlt(slide)\"\n class=\"c-slider__image\"\n loading=\"lazy\">\n } @else {\n <img [src]=\"getSlideImage(slide)\" \n [alt]=\"getSlideAlt(slide)\"\n class=\"c-slider__image\">\n }\n \n <!-- File Preview Icon -->\n @if (mergedConfig().showFilePreview && slide.filePreview) {\n <div class=\"c-slider__file-preview\">\n <div class=\"c-slider__file-icon\">\n <span class=\"icon-file\" [ngClass]=\"getFileTypeIcon(slide.filePreview.fileType)\"></span>\n </div>\n <div class=\"c-slider__file-info\">\n <span class=\"c-slider__file-name\">{{ slide.filePreview.fileName }}</span>\n @if (slide.filePreview.fileSize) {\n <span class=\"c-slider__file-size\">{{ slide.filePreview.fileSize }}</span>\n }\n </div>\n </div>\n }\n \n <!-- Overlay content -->\n @if (slide.title || slide.description) {\n <div class=\"c-slider__overlay\">\n @if (slide.title) {\n <h3 class=\"c-slider__title\">{{ slide.title }}</h3>\n }\n @if (slide.description) {\n <p class=\"c-slider__description\">{{ slide.description }}</p>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Next arrow -->\n @if (showArrows()) {\n <div class=\"c-slider__arrow c-slider__arrow--next\">\n <core-generic-button\n [config]=\"nextButtonConfig()\"\n (buttonClick)=\"goToNext()\">\n </core-generic-button>\n </div>\n }\n </div>\n\n <!-- Counter -->\n @if (showCounter()) {\n <div class=\"c-slider__counter\">\n <span class=\"c-slider__counter-text\">{{ getCounterText() }}</span>\n </div>\n }\n\n <!-- Dots navigation -->\n @if (showDots()) {\n <div class=\"c-slider__dots\">\n @for (item of items(); track item.id; let i = $index) {\n <button type=\"button\"\n class=\"c-slider__dot\"\n [class.c-slider__dot--active]=\"isActiveDot(i)\"\n [attr.aria-label]=\"'slider.go-to-slide' | translate: {number: i + 1}\"\n (click)=\"onDotClick(i)\">\n </button>\n }\n </div>\n }\n\n <!-- Thumbnails -->\n @if (showThumbnails()) {\n <div class=\"c-slider__thumbnails\" \n [class.c-slider__thumbnails--vertical]=\"mergedConfig().verticalThumbnails\">\n @for (thumbnail of thumbnails(); track thumbnail.id; let i = $index) {\n <button type=\"button\"\n class=\"c-slider__thumbnail\"\n [class.c-slider__thumbnail--active]=\"isActiveThumbnail(i)\"\n [style.height]=\"mergedConfig().thumbnailHeight\"\n (click)=\"onThumbnailClick(i)\">\n <img [src]=\"thumbnail.imageUrl\" \n [alt]=\"thumbnail.alt || thumbnail.title\"\n class=\"c-slider__thumbnail-image\">\n @if (thumbnail.title) {\n <span class=\"c-slider__thumbnail-title\">{{ thumbnail.title }}</span>\n }\n </button>\n }\n </div>\n }\n\n <!-- Empty state -->\n @if (totalItems() === 0) {\n <div class=\"c-slider__empty\">\n <div class=\"c-slider__empty-icon\">\n <i class=\"icon-image\" aria-hidden=\"true\"></i>\n </div>\n <p class=\"c-slider__empty-text\">{{ 'slider.no-items' | translate }}</p>\n </div>\n }\n\n <!-- Loading state -->\n @if (isDragging()) {\n <div class=\"c-slider__loading\">\n <div class=\"c-slider__loading-spinner\"></div>\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "component", type: GenericButtonComponent, selector: "core-generic-button", inputs: ["config", "data"], outputs: ["buttonClick"] }] });
11945
12464
  }
11946
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ImageModalComponent, decorators: [{
12465
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: GenericSliderComponent, decorators: [{
11947
12466
  type: Component,
11948
- args: [{ selector: 'core-image-modal', standalone: true, imports: [CommonModule], hostDirectives: [CoreHostDirective], template: "<div class=\"c-img-modal js-img-modal\" [class.is-visible]=\"isVisible()\">\n <span class=\"c-img-modal__close icon-cross-thin js-gallery-modal-close\" (click)=\"closeModal()\"></span>\n <div class=\"c-img-modal__overlay js-img-modal-close\" (click)=\"closeModal()\"></div>\n <div \n class=\"c-img-modal__holder\" \n #imageContainer\n [style.transform]=\"getHolderTransform()\"\n [style.cursor]=\"getCursor()\"\n (mousedown)=\"onMouseDown($event)\"\n (wheel)=\"onWheel($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd()\"\n (dblclick)=\"onDoubleClick()\">\n <img \n #modalImage\n [src]=\"imageSrc()\" \n [alt]=\"imageAlt()\" \n class=\"js-img-modal-img\"\n draggable=\"false\">\n </div>\n</div>\n", styles: [".c-img-modal__holder{transform-origin:center center;overflow:visible;will-change:transform}.c-img-modal__holder img{transform-origin:center center;-webkit-user-select:none;user-select:none;-webkit-user-drag:none;-moz-user-select:none;-ms-user-select:none;-webkit-touch-callout:none;-webkit-tap-highlight-color:transparent}.c-img-modal__holder[style*=transform]{backface-visibility:hidden;perspective:1000px}\n"] }]
11949
- }], ctorParameters: () => [], propDecorators: { modalImage: [{
11950
- type: ViewChild,
11951
- args: ['modalImage', { static: false }]
11952
- }], imageContainer: [{
11953
- type: ViewChild,
11954
- args: ['imageContainer', { static: false }]
11955
- }], handleKeydown: [{
12467
+ args: [{ selector: 'core-generic-slider', standalone: true, imports: [CommonModule, TranslateModule, GenericButtonComponent], template: "<div class=\"c-slider\" \n [style]=\"containerStyles()\"\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n (touchstart)=\"onTouchStart($event)\"\n (touchmove)=\"onTouchMove($event)\"\n (touchend)=\"onTouchEnd()\">\n \n <!-- Main slider container -->\n <div class=\"c-slider__container\">\n \n <!-- Previous arrow -->\n @if (showArrows()) {\n <div class=\"c-slider__arrow c-slider__arrow--prev\">\n <core-generic-button\n [config]=\"prevButtonConfig()\"\n (buttonClick)=\"goToPrevious()\">\n </core-generic-button>\n </div>\n }\n\n <!-- Slides wrapper -->\n <div class=\"c-slider__wrapper\">\n <div class=\"c-slider__track\" [style]=\"slideStyles()\">\n @for (slide of items(); track slide.id; let i = $index) {\n <div class=\"c-slider__slide\" \n [class.c-slider__slide--active]=\"isActiveSlide(i)\"\n [style.width]=\"getSlideWidth()\"\n (click)=\"onSlideClick(slide, i)\">\n \n <!-- Image -->\n <div class=\"c-slider__image-container\">\n @if (mergedConfig().lazyLoad) {\n <img [src]=\"getSlideImage(slide)\" \n [alt]=\"getSlideAlt(slide)\"\n class=\"c-slider__image\"\n loading=\"lazy\">\n } @else {\n <img [src]=\"getSlideImage(slide)\" \n [alt]=\"getSlideAlt(slide)\"\n class=\"c-slider__image\">\n }\n \n <!-- File Preview Icon -->\n @if (mergedConfig().showFilePreview && slide.filePreview) {\n <div class=\"c-slider__file-preview\">\n <div class=\"c-slider__file-icon\">\n <span class=\"icon-file\" [ngClass]=\"getFileTypeIcon(slide.filePreview.fileType)\"></span>\n </div>\n <div class=\"c-slider__file-info\">\n <span class=\"c-slider__file-name\">{{ slide.filePreview.fileName }}</span>\n @if (slide.filePreview.fileSize) {\n <span class=\"c-slider__file-size\">{{ slide.filePreview.fileSize }}</span>\n }\n </div>\n </div>\n }\n \n <!-- Overlay content -->\n @if (slide.title || slide.description) {\n <div class=\"c-slider__overlay\">\n @if (slide.title) {\n <h3 class=\"c-slider__title\">{{ slide.title }}</h3>\n }\n @if (slide.description) {\n <p class=\"c-slider__description\">{{ slide.description }}</p>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Next arrow -->\n @if (showArrows()) {\n <div class=\"c-slider__arrow c-slider__arrow--next\">\n <core-generic-button\n [config]=\"nextButtonConfig()\"\n (buttonClick)=\"goToNext()\">\n </core-generic-button>\n </div>\n }\n </div>\n\n <!-- Counter -->\n @if (showCounter()) {\n <div class=\"c-slider__counter\">\n <span class=\"c-slider__counter-text\">{{ getCounterText() }}</span>\n </div>\n }\n\n <!-- Dots navigation -->\n @if (showDots()) {\n <div class=\"c-slider__dots\">\n @for (item of items(); track item.id; let i = $index) {\n <button type=\"button\"\n class=\"c-slider__dot\"\n [class.c-slider__dot--active]=\"isActiveDot(i)\"\n [attr.aria-label]=\"'slider.go-to-slide' | translate: {number: i + 1}\"\n (click)=\"onDotClick(i)\">\n </button>\n }\n </div>\n }\n\n <!-- Thumbnails -->\n @if (showThumbnails()) {\n <div class=\"c-slider__thumbnails\" \n [class.c-slider__thumbnails--vertical]=\"mergedConfig().verticalThumbnails\">\n @for (thumbnail of thumbnails(); track thumbnail.id; let i = $index) {\n <button type=\"button\"\n class=\"c-slider__thumbnail\"\n [class.c-slider__thumbnail--active]=\"isActiveThumbnail(i)\"\n [style.height]=\"mergedConfig().thumbnailHeight\"\n (click)=\"onThumbnailClick(i)\">\n <img [src]=\"thumbnail.imageUrl\" \n [alt]=\"thumbnail.alt || thumbnail.title\"\n class=\"c-slider__thumbnail-image\">\n @if (thumbnail.title) {\n <span class=\"c-slider__thumbnail-title\">{{ thumbnail.title }}</span>\n }\n </button>\n }\n </div>\n }\n\n <!-- Empty state -->\n @if (totalItems() === 0) {\n <div class=\"c-slider__empty\">\n <div class=\"c-slider__empty-icon\">\n <i class=\"icon-image\" aria-hidden=\"true\"></i>\n </div>\n <p class=\"c-slider__empty-text\">{{ 'slider.no-items' | translate }}</p>\n </div>\n }\n\n <!-- Loading state -->\n @if (isDragging()) {\n <div class=\"c-slider__loading\">\n <div class=\"c-slider__loading-spinner\"></div>\n </div>\n }\n</div>\n" }]
12468
+ }], ctorParameters: () => [], propDecorators: { onKeydown: [{
11956
12469
  type: HostListener,
11957
- args: ['document:keydown', ['$event']]
11958
- }], onDocumentMouseMove: [{
11959
- type: HostListener,
11960
- args: ['document:mousemove', ['$event']]
11961
- }], onDocumentMouseUp: [{
11962
- type: HostListener,
11963
- args: ['document:mouseup']
12470
+ args: ['keydown', ['$event']]
11964
12471
  }] } });
11965
12472
 
12473
+ var SliderDirection;
12474
+ (function (SliderDirection) {
12475
+ SliderDirection["HORIZONTAL"] = "horizontal";
12476
+ SliderDirection["VERTICAL"] = "vertical";
12477
+ })(SliderDirection || (SliderDirection = {}));
12478
+ var SliderTransition;
12479
+ (function (SliderTransition) {
12480
+ SliderTransition["SLIDE"] = "slide";
12481
+ SliderTransition["FADE"] = "fade";
12482
+ SliderTransition["SCALE"] = "scale";
12483
+ })(SliderTransition || (SliderTransition = {}));
12484
+ var SliderNavigationType;
12485
+ (function (SliderNavigationType) {
12486
+ SliderNavigationType["DOTS"] = "dots";
12487
+ SliderNavigationType["ARROWS"] = "arrows";
12488
+ SliderNavigationType["THUMBNAILS"] = "thumbnails";
12489
+ SliderNavigationType["COUNTER"] = "counter";
12490
+ })(SliderNavigationType || (SliderNavigationType = {}));
12491
+
11966
12492
  class CacheBustingInterceptor {
11967
12493
  intercept(req, next) {
11968
12494
  if (req.url.includes('/assets/i18n/') && req.url.endsWith('.json')) {
@@ -12290,5 +12816,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
12290
12816
  * Generated bundle index. Do not edit.
12291
12817
  */
12292
12818
 
12293
- export { ActiveFiltersComponent, AlertComponent, AlertContainerComponent, AlertService, AlertType, ApiConfigurationProvider, BaseFieldComponent, ButtonContext, ButtonSize, ButtonType, CacheBustingInterceptor, CardComponent, CheckboxFieldComponent, ConfigurationModel, ConfirmationDialogComponent, ConfirmationDialogService, CoreHostDirective, CoreUiHttpLoaderFactory, CoreUiTranslateLoader, CoreUiTranslateService, DataListComponent, DataListItemComponent, DateFieldComponent, DateUtility, DatetimeFieldComponent, DialogActions, DocumentAction, DocumentDisplayMode, DropdownComponent, DropdownDirection, DropdownService, DynamicFieldDirective, FieldErrorsComponent, FieldType, FileFieldComponent, FileModel, FileTemplateModel, FileTemplateType, FileType, FileTypeModel, FileUploadService, FilterModalComponent, FilterService, FilterType, GenericButtonComponent, GenericDocumentationComponent, GenericModalComponent, GenericPaginationComponent, GenericRatingComponent, GenericSidebarComponent, GenericStepsComponent, GenericTableComponent, GenericTabsComponent, GenericTimelineComponent, GlobalApiConfigService, HeaderComponent, HeaderConfigurationService, HeaderElementType, HeaderService, HttpLoaderFactory, ImageModalComponent, LayoutAuth, LayoutBreakpoint, LayoutComponent, LayoutService, LayoutStateService, LayoutType, LoaderComponent, LoaderService, MainNavComponent, MainNavService, ModalMode, ModelApiService, MultiEntryFieldComponent, MultiEntryOutputFormat, NumberFieldComponent, NumberFieldConfigType, NumberFieldType, NumberRange, PERMISSION_ACTIONS_PROVIDER, PERMISSION_PROVIDER, PERMISSION_RESOURCES_PROVIDER, PaginationService, PasswordFieldComponent, PermissionEnumsService, PermissionModel, PermissionService, PermissionWrapperService, PermissionsActions, PermissionsInterceptor, PermissionsResources, ProgressBarComponent, ProgressBarSize, RatingService, RatingSize, RatingType, ResetPasswordModel, RoleModel, SelectFieldComponent, ServerSelectFieldComponent, ServerSelectService, SidebarCustomModalComponent, SidebarCustomModalService, SidebarHeight, SidebarMobileModalService, SidebarMobileType, SidebarPosition, SidebarService, SidebarState, SidebarTemplateRegistryService, SidebarVisibility, SidebarWidth, SmartFieldComponent, StepSize, StepStatus, StepType, StepsService, SwitchFieldComponent, TableAction, TableActionService, TableDataService, TextAreaFieldComponent, TextFieldComponent, TimeFieldComponent, TimeInterval, TimelineService, TimelineStatus, TimelineType, TranslationMergeService, UsersModel, VERSION, equalToValidator, isSameDate, provideCoreUiTranslateLoader, providePermissionActions, providePermissionEnums, providePermissionResources, providePermissionService, providePermissionServiceFactory, provideTranslateLoader };
12819
+ export { ActiveFiltersComponent, AlertComponent, AlertContainerComponent, AlertService, AlertType, ApiConfigurationProvider, BaseFieldComponent, ButtonContext, ButtonSize, ButtonType, CacheBustingInterceptor, CardComponent, CheckboxFieldComponent, ConfigurationModel, ConfirmationDialogComponent, ConfirmationDialogService, CoreHostDirective, CoreUiHttpLoaderFactory, CoreUiTranslateLoader, CoreUiTranslateService, DataListComponent, DataListItemComponent, DateFieldComponent, DateUtility, DatetimeFieldComponent, DialogActions, DocumentAction, DocumentDisplayMode, DropdownComponent, DropdownDirection, DropdownService, DynamicFieldDirective, FieldErrorsComponent, FieldType, FileFieldComponent, FileModel, FileTemplateModel, FileTemplateType, FileType, FileTypeModel, FileUploadService, FilterModalComponent, FilterService, FilterType, GenericButtonComponent, GenericDocumentationComponent, GenericModalComponent, GenericPaginationComponent, GenericRatingComponent, GenericSidebarComponent, GenericSliderComponent, GenericStepsComponent, GenericTableComponent, GenericTabsComponent, GenericTimelineComponent, GlobalApiConfigService, HeaderComponent, HeaderConfigurationService, HeaderElementType, HeaderService, HttpLoaderFactory, ImageModalComponent, ImageModalService, ImagePreviewComponent, LayoutAuth, LayoutBreakpoint, LayoutComponent, LayoutService, LayoutStateService, LayoutType, LoaderComponent, LoaderService, MainNavComponent, MainNavService, ModalMode, ModelApiService, MultiEntryFieldComponent, MultiEntryOutputFormat, NumberFieldComponent, NumberFieldConfigType, NumberFieldType, NumberRange, PERMISSION_ACTIONS_PROVIDER, PERMISSION_PROVIDER, PERMISSION_RESOURCES_PROVIDER, PaginationService, PasswordFieldComponent, PermissionEnumsService, PermissionModel, PermissionService, PermissionWrapperService, PermissionsActions, PermissionsInterceptor, PermissionsResources, ProgressBarComponent, ProgressBarSize, RatingService, RatingSize, RatingType, ResetPasswordModel, RoleModel, SelectFieldComponent, ServerSelectFieldComponent, ServerSelectService, SidebarCustomModalComponent, SidebarCustomModalService, SidebarHeight, SidebarMobileModalService, SidebarMobileType, SidebarPosition, SidebarService, SidebarState, SidebarTemplateRegistryService, SidebarVisibility, SidebarWidth, SliderActionType, SliderDirection, SliderNavigationType, SliderService, SliderTransition, SmartFieldComponent, StepSize, StepStatus, StepType, StepsService, SwitchFieldComponent, TableAction, TableActionService, TableDataService, TextAreaFieldComponent, TextFieldComponent, TimeFieldComponent, TimeInterval, TimelineService, TimelineStatus, TimelineType, TranslationMergeService, UsersModel, VERSION, equalToValidator, isSameDate, provideCoreUiTranslateLoader, providePermissionActions, providePermissionEnums, providePermissionResources, providePermissionService, providePermissionServiceFactory, provideTranslateLoader };
12294
12820
  //# sourceMappingURL=solcre-org-core-ui.mjs.map