@solcre-org/core-ui 2.17.0 → 2.17.1
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.
|
@@ -578,6 +578,95 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
|
|
|
578
578
|
args: [{ selector: 'core-checkbox-field', standalone: true, imports: [CommonModule, FormsModule, ReactiveFormsModule, TranslateModule, FieldErrorsComponent], hostDirectives: [CoreHostDirective], template: "<!-- Clase para layout inline cuando hay m\u00FAltiples opciones -->\n<div class=\"c-entry-toggle-holder\" [class.hasSeparatedOptions]=\"hasSeparatedOptions()\" [class.multiple-inline]=\"hasMultipleOptions()\">\n\n <span class=\"c-entry-text\"\n *ngIf=\"field().label\">\n {{ field().label | translate }}\n @if (hasRequiredIndicator()) {\n <span class=\"c-required\">*</span>\n }\n </span>\n \n @if (hasMultipleOptions()) {\n @for (option of options(); track option.value) {\n\n <!-- ! Solcre: Este .c-entry-toggle deber\u00EDa ser un componente en s\u00ED mismo. -->\n <!-- ! Solcre: El cannot-deselect no est\u00E1 over-engineered. Deber\u00EDa ser un Radio. -->\n <label class=\"c-entry-toggle\"\n [class.is-invalid]=\"hasError()\"\n [class.is-disabled]=\"isDisabled()\"\n [class.cannot-deselect]=\"cannotDeselect(option)\">\n\n <!-- onBlurInput() maneja validaciones y marca el campo como touched para mostrar errores -->\n @if (!allowMultiple() && isRequired()) {\n <!-- Cuando allowMultiple: false y required: true, usar radio buttons para todas las opciones -->\n <input\n type=\"radio\"\n [attr.id]=\"field().key.toString() + '_' + option.value\"\n [attr.name]=\"field().key.toString()\"\n [checked]=\"isOptionSelected(option)\"\n (change)=\"handleOptionChange(option, $event)\"\n (blur)=\"onBlurInput()\"\n />\n } @else if (cannotDeselect(option)) {\n <!-- Usar radio cuando no se puede deseleccionar (modo m\u00FAltiple con una sola opci\u00F3n) -->\n <input\n type=\"radio\"\n [attr.id]=\"field().key.toString() + '_' + option.value\"\n [attr.name]=\"field().key.toString()\"\n [checked]=\"isOptionSelected(option)\"\n (change)=\"handleOptionChange(option, $event)\"\n (blur)=\"onBlurInput()\"\n />\n } @else {\n <!-- Usar checkbox normal cuando se puede deseleccionar -->\n <input\n type=\"checkbox\"\n [attr.id]=\"field().key.toString() + '_' + option.value\"\n [attr.name]=\"allowMultiple() ? field().key.toString() + '[]' : field().key.toString()\"\n [checked]=\"isOptionSelected(option)\"\n (change)=\"handleOptionChange(option, $event)\"\n (blur)=\"onBlurInput()\"\n />\n }\n <span class=\"c-entry-toggle__toggle\"></span>\n\n <span class=\"c-entry-toggle__text\">\n {{ option.label | translate }}\n @if(option.externalLink) {\n <!-- Link externo funcional implementado -->\n <a class=\"icon-external-link-thin\" [href]=\"option.externalLink\" target=\"_blank\"></a>\n }\n </span>\n @if(option.detail) {\n <!-- Texto de detalle funcional implementado -->\n <span class=\"c-form-checkbox__detail\">{{ option.detail }}</span>\n }\n </label>\n\n }\n } @else {\n <!-- ! Solcre: Este .c-entry-toggle deber\u00EDa ser un componente en s\u00ED mismo. -->\n <!-- ! Solcre: El cannot-deselect no est\u00E1 over-engineered. Deber\u00EDa ser un Radio. -->\n <label class=\"c-entry-toggle\"\n [class.is-invalid]=\"hasError()\"\n [class.is-disabled]=\"isDisabled()\"\n [class.cannot-deselect]=\"isRequired() && !!formControl().value\">\n\n <!-- onBlurInput() maneja validaciones y marca el campo como touched para mostrar errores -->\n @if (isRequired() && !!formControl().value) {\n <!-- Usar radio cuando es requerido y tiene valor (cannot-deselect) -->\n <input\n type=\"radio\"\n [attr.id]=\"field().key.toString()\"\n [attr.name]=\"field().key.toString()\"\n [checked]=\"!!formControl().value\"\n (change)=\"onRadioChange($event)\"\n (blur)=\"onBlurInput()\"\n />\n } @else {\n <!-- Usar checkbox normal cuando se puede deseleccionar -->\n <input\n type=\"checkbox\"\n [attr.id]=\"field().key.toString()\"\n [attr.name]=\"field().key.toString()\"\n [formControl]=\"formControl()\"\n (blur)=\"onBlurInput()\"\n />\n }\n <span class=\"c-entry-toggle__toggle\"></span>\n <span class=\"c-entry-toggle__text\">\n {{ field().label | translate }}\n @if (hasRequiredIndicator()) {\n <span class=\"c-required\">*</span>\n }\n @if(externalLink()) {\n <!-- Link externo funcional implementado -->\n <a class=\"icon-external-link-thin\" [href]=\"externalLink()\" target=\"_blank\"></a>\n }\n </span>\n @if(detail()) {\n <!-- Texto de detalle funcional implementado -->\n <span class=\"c-form-checkbox__detail\">{{ detail() }}</span>\n }\n </label>\n }\n\n <core-field-errors [errors]=\"errors()\" />\n</div> \n ", styles: [".cannot-deselect{pointer-events:none;cursor:not-allowed}.c-entry-text+.c-entry-toggle-holder.hasSeparatedOptions{margin-top:calc(var(--_entry-group-gap) * .8)}.c-entry-toggle-holder.hasSeparatedOptions{display:grid;grid-template-columns:1fr 1fr;gap:calc(var(--_entry-group-gap) * .8)}.c-entry-toggle-holder.hasSeparatedOptions .c-entry-text{grid-column:span 2;margin-top:1em}\n"] }]
|
|
579
579
|
}], ctorParameters: () => [] });
|
|
580
580
|
|
|
581
|
+
const DEFAULT_COLORS = [
|
|
582
|
+
'#4285f4', '#ea4335', '#34a853', '#fbbc04',
|
|
583
|
+
'#9c27b0', '#00bcd4', '#ff5722', '#795548',
|
|
584
|
+
'#607d8b', '#e91e63', '#3f51b5', '#009688',
|
|
585
|
+
'#ff9800', '#673ab7', '#2196f3', '#4caf50'
|
|
586
|
+
];
|
|
587
|
+
class ColorPickerFieldComponent extends BaseFieldComponent {
|
|
588
|
+
isPickerOpen = signal(false);
|
|
589
|
+
presetColors = signal(DEFAULT_COLORS);
|
|
590
|
+
constructor() {
|
|
591
|
+
super();
|
|
592
|
+
effect(() => {
|
|
593
|
+
const shouldDisable = this.mode() === ModalMode.VIEW || this.evaluateReadonly();
|
|
594
|
+
const control = this.formControl();
|
|
595
|
+
if (shouldDisable && control.enabled) {
|
|
596
|
+
control.disable();
|
|
597
|
+
}
|
|
598
|
+
else if (!shouldDisable && control.disabled) {
|
|
599
|
+
control.enable();
|
|
600
|
+
}
|
|
601
|
+
});
|
|
602
|
+
effect(() => {
|
|
603
|
+
const fieldConfig = this.field();
|
|
604
|
+
if (fieldConfig.presetColors && Array.isArray(fieldConfig.presetColors)) {
|
|
605
|
+
this.presetColors.set(fieldConfig.presetColors);
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
isDisabled() {
|
|
610
|
+
return this.mode() === ModalMode.VIEW || this.evaluateReadonly();
|
|
611
|
+
}
|
|
612
|
+
togglePicker() {
|
|
613
|
+
if (!this.isDisabled()) {
|
|
614
|
+
this.isPickerOpen.update(open => !open);
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
closePicker() {
|
|
618
|
+
this.isPickerOpen.set(false);
|
|
619
|
+
}
|
|
620
|
+
selectColor(color) {
|
|
621
|
+
if (!this.isDisabled()) {
|
|
622
|
+
this.formControl().setValue(color);
|
|
623
|
+
this.valueChange.emit(color);
|
|
624
|
+
this.closePicker();
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
onColorInputChange(event) {
|
|
628
|
+
const input = event.target;
|
|
629
|
+
const color = input.value;
|
|
630
|
+
this.formControl().setValue(color);
|
|
631
|
+
this.valueChange.emit(color);
|
|
632
|
+
}
|
|
633
|
+
onTextInputChange(event) {
|
|
634
|
+
const input = event.target;
|
|
635
|
+
let color = input.value;
|
|
636
|
+
if (color && !color.startsWith('#')) {
|
|
637
|
+
color = '#' + color;
|
|
638
|
+
}
|
|
639
|
+
if (this.isValidHexColor(color)) {
|
|
640
|
+
this.formControl().setValue(color);
|
|
641
|
+
this.valueChange.emit(color);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
isValidHexColor(color) {
|
|
645
|
+
return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color);
|
|
646
|
+
}
|
|
647
|
+
getCurrentColor() {
|
|
648
|
+
const value = this.formControl().value;
|
|
649
|
+
return value && this.isValidHexColor(value) ? value : '#4783E1';
|
|
650
|
+
}
|
|
651
|
+
onBlurInput(event) {
|
|
652
|
+
setTimeout(() => {
|
|
653
|
+
if (!this.isPickerOpen()) {
|
|
654
|
+
this.onBlur(event);
|
|
655
|
+
}
|
|
656
|
+
}, 200);
|
|
657
|
+
}
|
|
658
|
+
handleEnterKey(event) {
|
|
659
|
+
const keyboardEvent = event;
|
|
660
|
+
this.onEnterInput(keyboardEvent);
|
|
661
|
+
}
|
|
662
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ColorPickerFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
663
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: ColorPickerFieldComponent, isStandalone: true, selector: "core-color-picker-field", usesInheritance: true, hostDirectives: [{ directive: CoreHostDirective }], ngImport: i0, template: "<label class=\"c-entry-item\" [class.c-entry-item--inline]=\"field().inline\">\n <span class=\"c-entry-text\" *ngIf=\"field().label\">\n {{ field().label | translate }}\n @if (hasRequiredValidators()) {\n <span class=\"c-required\">*</span>\n }\n </span>\n\n <div class=\"c-entry-input c-entry-input--color\"\n [class.is-readonly]=\"isReadonly()\"\n [class.is-disabled]=\"isDisabled()\">\n <div class=\"c-color-picker\">\n <div class=\"c-color-picker__preview-wrapper\">\n <div \n class=\"c-color-picker__preview\"\n [style.background-color]=\"getCurrentColor()\"\n (click)=\"togglePicker()\"\n [class.c-color-picker__preview--disabled]=\"isDisabled()\">\n </div>\n \n <input\n type=\"text\"\n class=\"c-color-picker__text-input\"\n [id]=\"field().key\"\n [formControl]=\"formControl()\"\n [placeholder]=\"(field().placeholder ?? '#4783E1') | translate\"\n [class.c-color-picker__text-input--disabled]=\"isDisabled()\"\n [class.c-color-picker__text-input--error]=\"hasError()\"\n (input)=\"onTextInputChange($event)\"\n (blur)=\"onBlurInput($event)\"\n (keydown.enter)=\"handleEnterKey($event)\"\n maxlength=\"7\"\n />\n \n <input\n type=\"color\"\n class=\"c-color-picker__native-input\"\n [value]=\"getCurrentColor()\"\n [disabled]=\"isDisabled()\"\n (input)=\"onColorInputChange($event)\"\n />\n </div>\n\n @if (isPickerOpen()) {\n <div class=\"c-color-picker__dropdown\">\n <div class=\"c-color-picker__preset-colors\">\n @for (color of presetColors(); track color) {\n <button\n type=\"button\"\n class=\"c-color-picker__preset-color\"\n [style.background-color]=\"color\"\n [class.c-color-picker__preset-color--selected]=\"getCurrentColor() === color\"\n (click)=\"selectColor(color)\"\n [title]=\"color\">\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n\n <core-field-errors [errors]=\"errors()\"></core-field-errors>\n</label>\n", styles: [".c-color-picker{position:relative;width:100%}.c-color-picker__preview-wrapper{display:flex;align-items:center;gap:8px}.c-color-picker__preview{width:36px;height:36px;border-radius:6px;border:2px solid var(--color-border, #e0e0e0);cursor:pointer;transition:border-color .2s ease,box-shadow .2s ease;flex-shrink:0}.c-color-picker__preview:hover:not(.c-color-picker__preview--disabled){border-color:var(--color-primary, #4783E1);box-shadow:0 0 0 2px #4783e133}.c-color-picker__preview--disabled{cursor:not-allowed;opacity:.6}.c-color-picker__text-input{flex:1;height:36px;padding:0 12px;font-size:14px;font-family:monospace;text-transform:uppercase;border:1px solid var(--color-border, #e0e0e0);border-radius:6px;background-color:var(--color-background, #fff);transition:border-color .2s ease,box-shadow .2s ease}.c-color-picker__text-input:focus{outline:none;border-color:var(--color-primary, #4783E1);box-shadow:0 0 0 2px #4783e133}.c-color-picker__text-input--disabled{background-color:var(--color-disabled-bg, #f5f5f5);cursor:not-allowed;opacity:.6}.c-color-picker__text-input--error{border-color:var(--color-danger, #dc3545)}.c-color-picker__text-input--error:focus{box-shadow:0 0 0 2px #dc354533}.c-color-picker__native-input{width:36px;height:36px;padding:0;border:none;border-radius:6px;cursor:pointer;flex-shrink:0}.c-color-picker__native-input::-webkit-color-swatch-wrapper{padding:0}.c-color-picker__native-input::-webkit-color-swatch{border:2px solid var(--color-border, #e0e0e0);border-radius:6px}.c-color-picker__native-input:disabled{cursor:not-allowed;opacity:.6}.c-color-picker__dropdown{position:absolute;top:calc(100% + 8px);left:0;z-index:1000;background-color:var(--color-background, #fff);border:1px solid var(--color-border, #e0e0e0);border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;min-width:200px}.c-color-picker__preset-colors{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}.c-color-picker__preset-color{width:32px;height:32px;border:2px solid transparent;border-radius:6px;cursor:pointer;padding:0;transition:transform .15s ease,border-color .15s ease}.c-color-picker__preset-color:hover{transform:scale(1.1)}.c-color-picker__preset-color--selected{border-color:var(--color-text, #333);box-shadow:0 0 0 2px var(--color-background, #fff),0 0 0 4px var(--color-primary, #4783E1)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: FieldErrorsComponent, selector: "core-field-errors", inputs: ["errors"] }] });
|
|
664
|
+
}
|
|
665
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: ColorPickerFieldComponent, decorators: [{
|
|
666
|
+
type: Component,
|
|
667
|
+
args: [{ selector: 'core-color-picker-field', standalone: true, imports: [CommonModule, FormsModule, TranslateModule, ReactiveFormsModule, FieldErrorsComponent], hostDirectives: [CoreHostDirective], template: "<label class=\"c-entry-item\" [class.c-entry-item--inline]=\"field().inline\">\n <span class=\"c-entry-text\" *ngIf=\"field().label\">\n {{ field().label | translate }}\n @if (hasRequiredValidators()) {\n <span class=\"c-required\">*</span>\n }\n </span>\n\n <div class=\"c-entry-input c-entry-input--color\"\n [class.is-readonly]=\"isReadonly()\"\n [class.is-disabled]=\"isDisabled()\">\n <div class=\"c-color-picker\">\n <div class=\"c-color-picker__preview-wrapper\">\n <div \n class=\"c-color-picker__preview\"\n [style.background-color]=\"getCurrentColor()\"\n (click)=\"togglePicker()\"\n [class.c-color-picker__preview--disabled]=\"isDisabled()\">\n </div>\n \n <input\n type=\"text\"\n class=\"c-color-picker__text-input\"\n [id]=\"field().key\"\n [formControl]=\"formControl()\"\n [placeholder]=\"(field().placeholder ?? '#4783E1') | translate\"\n [class.c-color-picker__text-input--disabled]=\"isDisabled()\"\n [class.c-color-picker__text-input--error]=\"hasError()\"\n (input)=\"onTextInputChange($event)\"\n (blur)=\"onBlurInput($event)\"\n (keydown.enter)=\"handleEnterKey($event)\"\n maxlength=\"7\"\n />\n \n <input\n type=\"color\"\n class=\"c-color-picker__native-input\"\n [value]=\"getCurrentColor()\"\n [disabled]=\"isDisabled()\"\n (input)=\"onColorInputChange($event)\"\n />\n </div>\n\n @if (isPickerOpen()) {\n <div class=\"c-color-picker__dropdown\">\n <div class=\"c-color-picker__preset-colors\">\n @for (color of presetColors(); track color) {\n <button\n type=\"button\"\n class=\"c-color-picker__preset-color\"\n [style.background-color]=\"color\"\n [class.c-color-picker__preset-color--selected]=\"getCurrentColor() === color\"\n (click)=\"selectColor(color)\"\n [title]=\"color\">\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div>\n\n <core-field-errors [errors]=\"errors()\"></core-field-errors>\n</label>\n", styles: [".c-color-picker{position:relative;width:100%}.c-color-picker__preview-wrapper{display:flex;align-items:center;gap:8px}.c-color-picker__preview{width:36px;height:36px;border-radius:6px;border:2px solid var(--color-border, #e0e0e0);cursor:pointer;transition:border-color .2s ease,box-shadow .2s ease;flex-shrink:0}.c-color-picker__preview:hover:not(.c-color-picker__preview--disabled){border-color:var(--color-primary, #4783E1);box-shadow:0 0 0 2px #4783e133}.c-color-picker__preview--disabled{cursor:not-allowed;opacity:.6}.c-color-picker__text-input{flex:1;height:36px;padding:0 12px;font-size:14px;font-family:monospace;text-transform:uppercase;border:1px solid var(--color-border, #e0e0e0);border-radius:6px;background-color:var(--color-background, #fff);transition:border-color .2s ease,box-shadow .2s ease}.c-color-picker__text-input:focus{outline:none;border-color:var(--color-primary, #4783E1);box-shadow:0 0 0 2px #4783e133}.c-color-picker__text-input--disabled{background-color:var(--color-disabled-bg, #f5f5f5);cursor:not-allowed;opacity:.6}.c-color-picker__text-input--error{border-color:var(--color-danger, #dc3545)}.c-color-picker__text-input--error:focus{box-shadow:0 0 0 2px #dc354533}.c-color-picker__native-input{width:36px;height:36px;padding:0;border:none;border-radius:6px;cursor:pointer;flex-shrink:0}.c-color-picker__native-input::-webkit-color-swatch-wrapper{padding:0}.c-color-picker__native-input::-webkit-color-swatch{border:2px solid var(--color-border, #e0e0e0);border-radius:6px}.c-color-picker__native-input:disabled{cursor:not-allowed;opacity:.6}.c-color-picker__dropdown{position:absolute;top:calc(100% + 8px);left:0;z-index:1000;background-color:var(--color-background, #fff);border:1px solid var(--color-border, #e0e0e0);border-radius:8px;box-shadow:0 4px 12px #00000026;padding:12px;min-width:200px}.c-color-picker__preset-colors{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}.c-color-picker__preset-color{width:32px;height:32px;border:2px solid transparent;border-radius:6px;cursor:pointer;padding:0;transition:transform .15s ease,border-color .15s ease}.c-color-picker__preset-color:hover{transform:scale(1.1)}.c-color-picker__preset-color--selected{border-color:var(--color-text, #333);box-shadow:0 0 0 2px var(--color-background, #fff),0 0 0 4px var(--color-primary, #4783E1)}\n"] }]
|
|
668
|
+
}], ctorParameters: () => [] });
|
|
669
|
+
|
|
581
670
|
class DateFieldComponent extends BaseFieldComponent {
|
|
582
671
|
elementRef;
|
|
583
672
|
isPickerOpen = false;
|
|
@@ -2409,6 +2498,7 @@ var FieldType;
|
|
|
2409
2498
|
FieldType["FILE"] = "file";
|
|
2410
2499
|
FieldType["PHONE"] = "phone";
|
|
2411
2500
|
FieldType["DOCUMENT"] = "document";
|
|
2501
|
+
FieldType["COLOR"] = "color";
|
|
2412
2502
|
})(FieldType || (FieldType = {}));
|
|
2413
2503
|
var NumberFieldType;
|
|
2414
2504
|
(function (NumberFieldType) {
|
|
@@ -4969,6 +5059,7 @@ class DynamicFieldDirective {
|
|
|
4969
5059
|
document: DocumentFieldComponent,
|
|
4970
5060
|
file: FileFieldComponent,
|
|
4971
5061
|
phone: PhoneFieldComponent,
|
|
5062
|
+
color: ColorPickerFieldComponent,
|
|
4972
5063
|
};
|
|
4973
5064
|
ngOnChanges(changes) {
|
|
4974
5065
|
if (changes['field']?.firstChange || this.shouldReloadComponent(changes)) {
|
|
@@ -16556,12 +16647,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
|
|
|
16556
16647
|
// Este archivo es generado automáticamente por scripts/update-version.js
|
|
16557
16648
|
// No edites manualmente este archivo
|
|
16558
16649
|
const VERSION = {
|
|
16559
|
-
full: '2.17.
|
|
16650
|
+
full: '2.17.1',
|
|
16560
16651
|
major: 2,
|
|
16561
16652
|
minor: 17,
|
|
16562
|
-
patch:
|
|
16563
|
-
timestamp: '2025-12-
|
|
16564
|
-
buildDate: '
|
|
16653
|
+
patch: 1,
|
|
16654
|
+
timestamp: '2025-12-16T13:58:16.774Z',
|
|
16655
|
+
buildDate: '16/12/2025'
|
|
16565
16656
|
};
|
|
16566
16657
|
|
|
16567
16658
|
class MainNavComponent {
|
|
@@ -21156,7 +21247,8 @@ const DEFAULT_SCHEDULER_CONFIG = {
|
|
|
21156
21247
|
slotDuration: 30,
|
|
21157
21248
|
rowHeightRem: 4,
|
|
21158
21249
|
showCurrentTimeLine: true,
|
|
21159
|
-
locale: 'es-ES'
|
|
21250
|
+
locale: 'es-ES',
|
|
21251
|
+
viewMode: 'day'
|
|
21160
21252
|
};
|
|
21161
21253
|
|
|
21162
21254
|
class GenericSchedulerComponent {
|
|
@@ -21171,6 +21263,10 @@ class GenericSchedulerComponent {
|
|
|
21171
21263
|
disabledSlotLabel = input('No disponible');
|
|
21172
21264
|
todayLabel = input('Hoy');
|
|
21173
21265
|
locale = input('es-ES');
|
|
21266
|
+
weekLabel = input('Semana');
|
|
21267
|
+
dayLabel = input('Día');
|
|
21268
|
+
monthLabel = input('Mes');
|
|
21269
|
+
disabledDates = input([]);
|
|
21174
21270
|
slotClick = output();
|
|
21175
21271
|
eventClick = output();
|
|
21176
21272
|
eventHover = output();
|
|
@@ -21178,10 +21274,70 @@ class GenericSchedulerComponent {
|
|
|
21178
21274
|
todayClick = output();
|
|
21179
21275
|
previousDay = output();
|
|
21180
21276
|
nextDay = output();
|
|
21277
|
+
previousWeek = output();
|
|
21278
|
+
nextWeek = output();
|
|
21279
|
+
previousMonth = output();
|
|
21280
|
+
nextMonth = output();
|
|
21281
|
+
viewModeChange = output();
|
|
21181
21282
|
timeSlots = signal([]);
|
|
21182
21283
|
currentTime = signal(new Date());
|
|
21284
|
+
expandedDay = signal(null);
|
|
21183
21285
|
timeUpdateInterval = null;
|
|
21184
21286
|
mergedConfig = computed(() => ({ ...DEFAULT_SCHEDULER_CONFIG, ...this.config() }));
|
|
21287
|
+
viewMode = computed(() => this.mergedConfig().viewMode || 'day');
|
|
21288
|
+
weekDays = computed(() => {
|
|
21289
|
+
if (this.viewMode() !== 'week')
|
|
21290
|
+
return [];
|
|
21291
|
+
const selected = this.selectedDate();
|
|
21292
|
+
const localeValue = this.locale();
|
|
21293
|
+
const today = new Date();
|
|
21294
|
+
const dayOfWeek = selected.getUTCDay();
|
|
21295
|
+
const mondayOffset = dayOfWeek === 0 ? -6 : 1 - dayOfWeek;
|
|
21296
|
+
const monday = new Date(Date.UTC(selected.getUTCFullYear(), selected.getUTCMonth(), selected.getUTCDate() + mondayOffset));
|
|
21297
|
+
const days = [];
|
|
21298
|
+
for (let i = 0; i < 7; i++) {
|
|
21299
|
+
const date = new Date(Date.UTC(monday.getUTCFullYear(), monday.getUTCMonth(), monday.getUTCDate() + i));
|
|
21300
|
+
const isToday = date.getUTCFullYear() === today.getUTCFullYear() &&
|
|
21301
|
+
date.getUTCMonth() === today.getUTCMonth() &&
|
|
21302
|
+
date.getUTCDate() === today.getUTCDate();
|
|
21303
|
+
days.push({
|
|
21304
|
+
date,
|
|
21305
|
+
dayNumber: date.getUTCDate(),
|
|
21306
|
+
dayName: date.toLocaleDateString(localeValue, { weekday: 'short', timeZone: 'UTC' }),
|
|
21307
|
+
isToday,
|
|
21308
|
+
isWeekend: i >= 5
|
|
21309
|
+
});
|
|
21310
|
+
}
|
|
21311
|
+
return days;
|
|
21312
|
+
});
|
|
21313
|
+
monthDays = computed(() => {
|
|
21314
|
+
if (this.viewMode() !== 'month')
|
|
21315
|
+
return [];
|
|
21316
|
+
const selected = this.selectedDate();
|
|
21317
|
+
const localeValue = this.locale();
|
|
21318
|
+
const today = new Date();
|
|
21319
|
+
const year = selected.getUTCFullYear();
|
|
21320
|
+
const month = selected.getUTCMonth();
|
|
21321
|
+
const firstDayOfMonth = new Date(Date.UTC(year, month, 1));
|
|
21322
|
+
const dayOfWeek = firstDayOfMonth.getUTCDay();
|
|
21323
|
+
const mondayOffset = dayOfWeek === 0 ? -6 : 1 - dayOfWeek;
|
|
21324
|
+
const startDate = new Date(Date.UTC(year, month, 1 + mondayOffset));
|
|
21325
|
+
const days = [];
|
|
21326
|
+
for (let i = 0; i < 42; i++) {
|
|
21327
|
+
const date = new Date(Date.UTC(startDate.getUTCFullYear(), startDate.getUTCMonth(), startDate.getUTCDate() + i));
|
|
21328
|
+
const isToday = date.getUTCFullYear() === today.getUTCFullYear() &&
|
|
21329
|
+
date.getUTCMonth() === today.getUTCMonth() &&
|
|
21330
|
+
date.getUTCDate() === today.getUTCDate();
|
|
21331
|
+
days.push({
|
|
21332
|
+
date,
|
|
21333
|
+
dayNumber: date.getUTCDate(),
|
|
21334
|
+
dayName: date.toLocaleDateString(localeValue, { weekday: 'short', timeZone: 'UTC' }),
|
|
21335
|
+
isToday,
|
|
21336
|
+
isWeekend: [0, 6].includes(date.getUTCDay())
|
|
21337
|
+
});
|
|
21338
|
+
}
|
|
21339
|
+
return days;
|
|
21340
|
+
});
|
|
21185
21341
|
isToday = computed(() => {
|
|
21186
21342
|
const selected = this.selectedDate();
|
|
21187
21343
|
const today = new Date();
|
|
@@ -21192,6 +21348,32 @@ class GenericSchedulerComponent {
|
|
|
21192
21348
|
formattedDate = computed(() => {
|
|
21193
21349
|
const date = this.selectedDate();
|
|
21194
21350
|
const localeValue = this.locale();
|
|
21351
|
+
if (this.viewMode() === 'week') {
|
|
21352
|
+
const days = this.weekDays();
|
|
21353
|
+
if (days.length > 0) {
|
|
21354
|
+
const firstDay = days[0].date;
|
|
21355
|
+
const lastDay = days[6].date;
|
|
21356
|
+
const firstFormatted = firstDay.toLocaleDateString(localeValue, {
|
|
21357
|
+
day: 'numeric',
|
|
21358
|
+
month: 'short',
|
|
21359
|
+
timeZone: 'UTC'
|
|
21360
|
+
});
|
|
21361
|
+
const lastFormatted = lastDay.toLocaleDateString(localeValue, {
|
|
21362
|
+
day: 'numeric',
|
|
21363
|
+
month: 'short',
|
|
21364
|
+
year: 'numeric',
|
|
21365
|
+
timeZone: 'UTC'
|
|
21366
|
+
});
|
|
21367
|
+
return `${firstFormatted} - ${lastFormatted}`;
|
|
21368
|
+
}
|
|
21369
|
+
}
|
|
21370
|
+
if (this.viewMode() === 'month') {
|
|
21371
|
+
return date.toLocaleDateString(localeValue, {
|
|
21372
|
+
month: 'long',
|
|
21373
|
+
year: 'numeric',
|
|
21374
|
+
timeZone: 'UTC'
|
|
21375
|
+
});
|
|
21376
|
+
}
|
|
21195
21377
|
return date.toLocaleDateString(localeValue, {
|
|
21196
21378
|
weekday: 'long',
|
|
21197
21379
|
year: 'numeric',
|
|
@@ -21201,8 +21383,17 @@ class GenericSchedulerComponent {
|
|
|
21201
21383
|
});
|
|
21202
21384
|
});
|
|
21203
21385
|
currentTimePosition = computed(() => {
|
|
21204
|
-
if (!this.
|
|
21386
|
+
if (!this.mergedConfig().showCurrentTimeLine)
|
|
21387
|
+
return null;
|
|
21388
|
+
if (this.viewMode() === 'week') {
|
|
21389
|
+
const days = this.weekDays();
|
|
21390
|
+
const todayIndex = days.findIndex(d => d.isToday);
|
|
21391
|
+
if (todayIndex === -1)
|
|
21392
|
+
return null;
|
|
21393
|
+
}
|
|
21394
|
+
else if (!this.isToday()) {
|
|
21205
21395
|
return null;
|
|
21396
|
+
}
|
|
21206
21397
|
const now = this.currentTime();
|
|
21207
21398
|
const hours = now.getUTCHours();
|
|
21208
21399
|
const minutes = now.getUTCMinutes();
|
|
@@ -21215,6 +21406,12 @@ class GenericSchedulerComponent {
|
|
|
21215
21406
|
const positionInRem = slotsFromStart * cfg.rowHeightRem;
|
|
21216
21407
|
return positionInRem;
|
|
21217
21408
|
});
|
|
21409
|
+
currentTimeDayIndex = computed(() => {
|
|
21410
|
+
if (this.viewMode() !== 'week')
|
|
21411
|
+
return -1;
|
|
21412
|
+
const days = this.weekDays();
|
|
21413
|
+
return days.findIndex(d => d.isToday);
|
|
21414
|
+
});
|
|
21218
21415
|
eventMap = computed(() => {
|
|
21219
21416
|
const map = new Map();
|
|
21220
21417
|
const evts = this.events();
|
|
@@ -21295,6 +21492,10 @@ class GenericSchedulerComponent {
|
|
|
21295
21492
|
isSlotDisabled(columnId, slot) {
|
|
21296
21493
|
const now = new Date();
|
|
21297
21494
|
const selected = this.selectedDate();
|
|
21495
|
+
const dateStr = selected.toISOString().split('T')[0];
|
|
21496
|
+
if (this.disabledDates().includes(dateStr)) {
|
|
21497
|
+
return true;
|
|
21498
|
+
}
|
|
21298
21499
|
const todayUTC = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
|
|
21299
21500
|
const selectedUTC = Date.UTC(selected.getUTCFullYear(), selected.getUTCMonth(), selected.getUTCDate());
|
|
21300
21501
|
if (selectedUTC < todayUTC) {
|
|
@@ -21350,15 +21551,170 @@ class GenericSchedulerComponent {
|
|
|
21350
21551
|
const nextDayDate = new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth(), current.getUTCDate() + 1));
|
|
21351
21552
|
this.nextDay.emit(nextDayDate);
|
|
21352
21553
|
}
|
|
21554
|
+
onPreviousWeek() {
|
|
21555
|
+
const current = this.selectedDate();
|
|
21556
|
+
const prevWeek = new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth(), current.getUTCDate() - 7));
|
|
21557
|
+
this.previousWeek.emit(prevWeek);
|
|
21558
|
+
}
|
|
21559
|
+
onNextWeek() {
|
|
21560
|
+
const current = this.selectedDate();
|
|
21561
|
+
const nextWeekDate = new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth(), current.getUTCDate() + 7));
|
|
21562
|
+
this.nextWeek.emit(nextWeekDate);
|
|
21563
|
+
}
|
|
21564
|
+
onPreviousMonth() {
|
|
21565
|
+
const current = this.selectedDate();
|
|
21566
|
+
const prevMonth = new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth() - 1, 1));
|
|
21567
|
+
this.previousMonth.emit(prevMonth);
|
|
21568
|
+
}
|
|
21569
|
+
onNextMonth() {
|
|
21570
|
+
const current = this.selectedDate();
|
|
21571
|
+
const nextMonth = new Date(Date.UTC(current.getUTCFullYear(), current.getUTCMonth() + 1, 1));
|
|
21572
|
+
this.nextMonth.emit(nextMonth);
|
|
21573
|
+
}
|
|
21574
|
+
onPrevious() {
|
|
21575
|
+
if (this.viewMode() === 'week') {
|
|
21576
|
+
this.onPreviousWeek();
|
|
21577
|
+
}
|
|
21578
|
+
else if (this.viewMode() === 'month') {
|
|
21579
|
+
this.onPreviousMonth();
|
|
21580
|
+
}
|
|
21581
|
+
else {
|
|
21582
|
+
this.onPreviousDay();
|
|
21583
|
+
}
|
|
21584
|
+
}
|
|
21585
|
+
onNext() {
|
|
21586
|
+
if (this.viewMode() === 'week') {
|
|
21587
|
+
this.onNextWeek();
|
|
21588
|
+
}
|
|
21589
|
+
else if (this.viewMode() === 'month') {
|
|
21590
|
+
this.onNextMonth();
|
|
21591
|
+
}
|
|
21592
|
+
else {
|
|
21593
|
+
this.onNextDay();
|
|
21594
|
+
}
|
|
21595
|
+
}
|
|
21596
|
+
toggleViewMode() {
|
|
21597
|
+
const newMode = this.viewMode() === 'day' ? 'week' : 'day';
|
|
21598
|
+
this.viewModeChange.emit(newMode);
|
|
21599
|
+
}
|
|
21600
|
+
setViewMode(mode) {
|
|
21601
|
+
this.viewModeChange.emit(mode);
|
|
21602
|
+
}
|
|
21603
|
+
getEventsForDay(dayDate) {
|
|
21604
|
+
const evts = this.events();
|
|
21605
|
+
return evts.filter(event => {
|
|
21606
|
+
if (!event.date)
|
|
21607
|
+
return false;
|
|
21608
|
+
const eventDate = new Date(event.date);
|
|
21609
|
+
return eventDate.getUTCFullYear() === dayDate.getUTCFullYear() &&
|
|
21610
|
+
eventDate.getUTCMonth() === dayDate.getUTCMonth() &&
|
|
21611
|
+
eventDate.getUTCDate() === dayDate.getUTCDate();
|
|
21612
|
+
});
|
|
21613
|
+
}
|
|
21614
|
+
isSlotOccupiedForDay(dayDate, slot) {
|
|
21615
|
+
const evts = this.getEventsForDay(dayDate);
|
|
21616
|
+
return evts.some(event => this.isTimeInEvent(slot.time, event));
|
|
21617
|
+
}
|
|
21618
|
+
shouldShowEventForDay(dayDate, slot) {
|
|
21619
|
+
const evts = this.getEventsForDay(dayDate);
|
|
21620
|
+
return evts.some(event => event.startTime === slot.time);
|
|
21621
|
+
}
|
|
21622
|
+
getEventForDaySlot(dayDate, slot) {
|
|
21623
|
+
const evts = this.getEventsForDay(dayDate);
|
|
21624
|
+
return evts.find(event => event.startTime === slot.time);
|
|
21625
|
+
}
|
|
21626
|
+
isDayDisabled(dayDate) {
|
|
21627
|
+
const dateStr = dayDate.toISOString().split('T')[0];
|
|
21628
|
+
return this.disabledDates().includes(dateStr);
|
|
21629
|
+
}
|
|
21630
|
+
isSlotDisabledForDay(dayDate, slot) {
|
|
21631
|
+
if (this.isDayDisabled(dayDate)) {
|
|
21632
|
+
return true;
|
|
21633
|
+
}
|
|
21634
|
+
const now = new Date();
|
|
21635
|
+
const todayUTC = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
|
|
21636
|
+
const dayUTC = Date.UTC(dayDate.getUTCFullYear(), dayDate.getUTCMonth(), dayDate.getUTCDate());
|
|
21637
|
+
if (dayUTC < todayUTC) {
|
|
21638
|
+
return true;
|
|
21639
|
+
}
|
|
21640
|
+
if (dayUTC === todayUTC) {
|
|
21641
|
+
const [slotHour, slotMin] = slot.time.split(':').map(Number);
|
|
21642
|
+
const slotMinutes = slotHour * 60 + slotMin;
|
|
21643
|
+
const currentMinutes = now.getUTCHours() * 60 + now.getUTCMinutes();
|
|
21644
|
+
return slotMinutes < currentMinutes;
|
|
21645
|
+
}
|
|
21646
|
+
return false;
|
|
21647
|
+
}
|
|
21648
|
+
onWeekSlotClick(dayDate, slot) {
|
|
21649
|
+
if (this.isSlotOccupiedForDay(dayDate, slot) || this.isSlotDisabledForDay(dayDate, slot)) {
|
|
21650
|
+
return;
|
|
21651
|
+
}
|
|
21652
|
+
this.slotClick.emit({
|
|
21653
|
+
columnId: dayDate.toISOString(),
|
|
21654
|
+
slot,
|
|
21655
|
+
date: dayDate
|
|
21656
|
+
});
|
|
21657
|
+
}
|
|
21658
|
+
onWeekEventClick(event, dayDate) {
|
|
21659
|
+
const pseudoColumn = {
|
|
21660
|
+
id: dayDate.toISOString(),
|
|
21661
|
+
name: dayDate.toLocaleDateString(this.locale(), { weekday: 'long', timeZone: 'UTC' })
|
|
21662
|
+
};
|
|
21663
|
+
this.eventClick.emit({ event, column: pseudoColumn });
|
|
21664
|
+
}
|
|
21665
|
+
onMonthDayClick(dayDate) {
|
|
21666
|
+
const dummySlot = {
|
|
21667
|
+
time: '00:00',
|
|
21668
|
+
hour: 0,
|
|
21669
|
+
minutes: 0,
|
|
21670
|
+
isHalfHour: false,
|
|
21671
|
+
displayTime: false
|
|
21672
|
+
};
|
|
21673
|
+
this.slotClick.emit({
|
|
21674
|
+
columnId: dayDate.toISOString(),
|
|
21675
|
+
slot: dummySlot,
|
|
21676
|
+
date: dayDate
|
|
21677
|
+
});
|
|
21678
|
+
}
|
|
21679
|
+
onMonthEventClick(event, dayDate) {
|
|
21680
|
+
const pseudoColumn = {
|
|
21681
|
+
id: dayDate.toISOString(),
|
|
21682
|
+
name: dayDate.toLocaleDateString(this.locale(), { weekday: 'long', timeZone: 'UTC' })
|
|
21683
|
+
};
|
|
21684
|
+
this.eventClick.emit({ event, column: pseudoColumn });
|
|
21685
|
+
}
|
|
21686
|
+
openDayPopover(dayDate, event) {
|
|
21687
|
+
event.stopPropagation();
|
|
21688
|
+
this.expandedDay.set(dayDate);
|
|
21689
|
+
}
|
|
21690
|
+
closeDayPopover() {
|
|
21691
|
+
this.expandedDay.set(null);
|
|
21692
|
+
}
|
|
21693
|
+
getExpandedDayEvents() {
|
|
21694
|
+
const day = this.expandedDay();
|
|
21695
|
+
if (!day)
|
|
21696
|
+
return [];
|
|
21697
|
+
return this.getEventsForDay(day);
|
|
21698
|
+
}
|
|
21699
|
+
getExpandedDayLabel() {
|
|
21700
|
+
const day = this.expandedDay();
|
|
21701
|
+
if (!day)
|
|
21702
|
+
return '';
|
|
21703
|
+
const localeValue = this.locale();
|
|
21704
|
+
const weekday = day.toLocaleDateString(localeValue, { weekday: 'short', timeZone: 'UTC' }).toUpperCase();
|
|
21705
|
+
const dayNum = day.getUTCDate();
|
|
21706
|
+
return `${weekday}\n${dayNum}`;
|
|
21707
|
+
}
|
|
21353
21708
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: GenericSchedulerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
21354
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: GenericSchedulerComponent, isStandalone: true, selector: "core-generic-scheduler", inputs: { selectedDate: { classPropertyName: "selectedDate", publicName: "selectedDate", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, showTimeColumn: { classPropertyName: "showTimeColumn", publicName: "showTimeColumn", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, timeColumnLabel: { classPropertyName: "timeColumnLabel", publicName: "timeColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, emptySlotLabel: { classPropertyName: "emptySlotLabel", publicName: "emptySlotLabel", isSignal: true, isRequired: false, transformFunction: null }, disabledSlotLabel: { classPropertyName: "disabledSlotLabel", publicName: "disabledSlotLabel", isSignal: true, isRequired: false, transformFunction: null }, todayLabel: { classPropertyName: "todayLabel", publicName: "todayLabel", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { slotClick: "slotClick", eventClick: "eventClick", eventHover: "eventHover", eventLeave: "eventLeave", todayClick: "todayClick", previousDay: "previousDay", nextDay: "nextDay" }, host: { properties: { "style.--cols": "columns().length" }, classAttribute: "c-bookings-grid c-bookings-card" }, ngImport: i0, template: "@if (showHeader()) {\n<div class=\"c-bookings-header\">\n <button class=\"c-bookings-header__today\" (click)=\"onTodayClick()\">\n {{ todayLabel() }}\n </button>\n\n <div class=\"c-bookings-header__date\">\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-left\"\n title=\"D\u00EDa anterior\"\n (click)=\"onPreviousDay()\"\n ></button>\n <span>{{ formattedDate() }}</span>\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-right\"\n title=\"D\u00EDa siguiente\"\n (click)=\"onNextDay()\"\n ></button>\n </div>\n</div>\n}\n\n<div\n class=\"c-bookings-grid__wrapper\"\n [style.--cols]=\"columns().length\"\n style=\"position: relative\"\n>\n @if (isToday() && currentTimePosition() !== null) {\n <div\n class=\"c-bookings-grid__current-time-line\"\n [style.--time-position-rem]=\"currentTimePosition()\"\n ></div>\n } @if (showTimeColumn()) {\n <div class=\"c-bookings-grid__times\">\n <div class=\"c-bookings-grid__top\">\n <div class=\"c-bookings-grid__title\">{{ timeColumnLabel() }}</div>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (slot.displayTime) {\n <span class=\"c-bookings-grid__time\">{{ slot.time }}</span>\n }\n </div>\n }\n </div>\n } @for (column of columns(); track column.id) {\n <div class=\"c-bookings-grid__col\">\n <div class=\"c-bookings-grid__top\">\n <p class=\"c-bookings-grid__title\">{{ column.name }}</p>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (!isSlotOccupied(column.id, slot)) { @if (isSlotDisabled(column.id,\n slot)) {\n <button\n class=\"c-bookings-grid__slot c-bookings-grid__slot--disabled\"\n disabled\n [title]=\"disabledSlotLabel()\"\n >\n {{ disabledSlotLabel() }}\n </button>\n } @else {\n <button\n class=\"c-bookings-grid__slot\"\n [title]=\"emptySlotLabel()\"\n (click)=\"onSlotClick(column.id, slot)\"\n >\n {{ emptySlotLabel() }}\n </button>\n } } @if (shouldShowEvent(column.id, slot)) { @let event =\n getEventForSlot(column.id, slot); @if (event) {\n <div\n [class]=\"getEventClasses(event)\"\n [attr.data-type]=\"event.type\"\n [attr.data-status]=\"event.status\"\n [style.--rows]=\"getEventRowSpan(event)\"\n (mouseenter)=\"onEventHover($event, event)\"\n (mouseleave)=\"onEventLeave()\"\n (click)=\"onEventClick(event, column)\"\n >\n <p class=\"c-bookings-grid__title\">\n {{ event.subtitle || event.title }}\n </p>\n <p class=\"c-bookings-grid__text\">\n {{ event.startTime }} - {{ event.endTime }}\n </p>\n\n @if (event.canCancel) {\n <button\n class=\"c-bookings-grid__link c-link--underlined\"\n (click)=\"$event.stopPropagation()\"\n >\n <span class=\"icon-cross-thin\"></span>\n Cancelar\n </button>\n } @if ((event.canApprove || event.canReject) && event.duration >= 91) {\n <div class=\"c-bookings-grid__quick-actions\">\n @if (event.canApprove) {\n <button\n class=\"c-icon-btn--fill context:success icon-check\"\n title=\"Aprobar\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n } @if (event.canReject) {\n <button\n class=\"c-icon-btn--fill context:error icon-cross\"\n title=\"Rechazar\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n }\n </div>\n }\n </div>\n } }\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;overflow:visible}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
21709
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.0.6", type: GenericSchedulerComponent, isStandalone: true, selector: "core-generic-scheduler", inputs: { selectedDate: { classPropertyName: "selectedDate", publicName: "selectedDate", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: false, transformFunction: null }, showTimeColumn: { classPropertyName: "showTimeColumn", publicName: "showTimeColumn", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, timeColumnLabel: { classPropertyName: "timeColumnLabel", publicName: "timeColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, emptySlotLabel: { classPropertyName: "emptySlotLabel", publicName: "emptySlotLabel", isSignal: true, isRequired: false, transformFunction: null }, disabledSlotLabel: { classPropertyName: "disabledSlotLabel", publicName: "disabledSlotLabel", isSignal: true, isRequired: false, transformFunction: null }, todayLabel: { classPropertyName: "todayLabel", publicName: "todayLabel", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, weekLabel: { classPropertyName: "weekLabel", publicName: "weekLabel", isSignal: true, isRequired: false, transformFunction: null }, dayLabel: { classPropertyName: "dayLabel", publicName: "dayLabel", isSignal: true, isRequired: false, transformFunction: null }, monthLabel: { classPropertyName: "monthLabel", publicName: "monthLabel", isSignal: true, isRequired: false, transformFunction: null }, disabledDates: { classPropertyName: "disabledDates", publicName: "disabledDates", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { slotClick: "slotClick", eventClick: "eventClick", eventHover: "eventHover", eventLeave: "eventLeave", todayClick: "todayClick", previousDay: "previousDay", nextDay: "nextDay", previousWeek: "previousWeek", nextWeek: "nextWeek", previousMonth: "previousMonth", nextMonth: "nextMonth", viewModeChange: "viewModeChange" }, host: { properties: { "class.c-bookings-grid--weekly": "viewMode() === \"week\"", "style.--cols": "columns().length" }, classAttribute: "c-bookings-grid c-bookings-card" }, ngImport: i0, template: "@if (showHeader()) {\n<div class=\"c-bookings-header\">\n <button class=\"c-bookings-header__today\" (click)=\"onTodayClick()\">\n {{ todayLabel() }}\n </button>\n\n <div class=\"c-bookings-header__date\">\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-left\"\n [title]=\"viewMode() === 'week' ? 'Semana anterior' : 'D\u00EDa anterior'\"\n (click)=\"onPrevious()\"\n ></button>\n <span>{{ formattedDate() }}</span>\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-right\"\n [title]=\"viewMode() === 'week' ? 'Semana siguiente' : 'D\u00EDa siguiente'\"\n (click)=\"onNext()\"\n ></button>\n </div>\n\n <div class=\"c-bookings-header__view-toggle\">\n <button\n class=\"c-bookings-header__view-btn\"\n [class.is-active]=\"viewMode() === 'day'\"\n (click)=\"setViewMode('day')\"\n >\n {{ dayLabel() }}\n </button>\n <button\n class=\"c-bookings-header__view-btn\"\n [class.is-active]=\"viewMode() === 'week'\"\n (click)=\"setViewMode('week')\"\n >\n {{ weekLabel() }}\n </button>\n <button\n class=\"c-bookings-header__view-btn\"\n [class.is-active]=\"viewMode() === 'month'\"\n (click)=\"setViewMode('month')\"\n >\n {{ monthLabel() }}\n </button>\n </div>\n</div>\n} @if (viewMode() === 'day') {\n<!-- DAILY VIEW -->\n<div\n class=\"c-bookings-grid__wrapper\"\n [style.--cols]=\"columns().length\"\n style=\"position: relative\"\n>\n @if (isToday() && currentTimePosition() !== null) {\n <div\n class=\"c-bookings-grid__current-time-line\"\n [style.--time-position-rem]=\"currentTimePosition()\"\n ></div>\n } @if (showTimeColumn()) {\n <div class=\"c-bookings-grid__times\">\n <div class=\"c-bookings-grid__top\">\n <div class=\"c-bookings-grid__title\">{{ timeColumnLabel() }}</div>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (slot.displayTime) {\n <span class=\"c-bookings-grid__time\">{{ slot.time }}</span>\n }\n </div>\n }\n </div>\n } @for (column of columns(); track column.id) {\n <div class=\"c-bookings-grid__col\">\n <div class=\"c-bookings-grid__top\">\n <p class=\"c-bookings-grid__title\">{{ column.name }}</p>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (!isSlotOccupied(column.id, slot)) { @if (isSlotDisabled(column.id,\n slot)) {\n <button\n class=\"c-bookings-grid__slot c-bookings-grid__slot--disabled\"\n disabled\n [title]=\"disabledSlotLabel()\"\n >\n {{ disabledSlotLabel() }}\n </button>\n } @else {\n <button\n class=\"c-bookings-grid__slot\"\n [title]=\"emptySlotLabel()\"\n (click)=\"onSlotClick(column.id, slot)\"\n >\n {{ emptySlotLabel() }}\n </button>\n } } @if (shouldShowEvent(column.id, slot)) { @let event =\n getEventForSlot(column.id, slot); @if (event) {\n <div\n [class]=\"getEventClasses(event)\"\n [attr.data-type]=\"event.type\"\n [attr.data-status]=\"event.status\"\n [style.--rows]=\"getEventRowSpan(event)\"\n (mouseenter)=\"onEventHover($event, event)\"\n (mouseleave)=\"onEventLeave()\"\n (click)=\"onEventClick(event, column)\"\n >\n <p class=\"c-bookings-grid__title\">\n {{ event.subtitle || event.title }}\n </p>\n <p class=\"c-bookings-grid__text\">\n {{ event.startTime }} - {{ event.endTime }}\n </p>\n\n @if (event.canCancel) {\n <button\n class=\"c-bookings-grid__link c-link--underlined\"\n (click)=\"$event.stopPropagation()\"\n >\n <span class=\"icon-cross-thin\"></span>\n Cancelar\n </button>\n } @if ((event.canApprove || event.canReject) && event.duration >= 91) {\n <div class=\"c-bookings-grid__quick-actions\">\n @if (event.canApprove) {\n <button\n class=\"c-icon-btn--fill context:success icon-check\"\n title=\"Aprobar\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n } @if (event.canReject) {\n <button\n class=\"c-icon-btn--fill context:error icon-cross\"\n title=\"Rechazar\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n }\n </div>\n }\n </div>\n } }\n </div>\n }\n </div>\n }\n</div>\n} @else if (viewMode() === 'week') {\n<!-- WEEKLY VIEW -->\n<div\n class=\"c-bookings-grid__wrapper c-bookings-grid__wrapper--weekly\"\n [style.--cols]=\"7\"\n style=\"position: relative\"\n>\n @if (currentTimePosition() !== null && currentTimeDayIndex() >= 0) {\n <div\n class=\"c-bookings-grid__current-time-line c-bookings-grid__current-time-line--weekly\"\n [style.--time-position-rem]=\"currentTimePosition()\"\n [style.--day-index]=\"currentTimeDayIndex()\"\n ></div>\n } @if (showTimeColumn()) {\n <div class=\"c-bookings-grid__times\">\n <div class=\"c-bookings-grid__top c-bookings-grid__top--weekly\">\n <div class=\"c-bookings-grid__title\">{{ timeColumnLabel() }}</div>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (slot.displayTime) {\n <span class=\"c-bookings-grid__time\">{{ slot.time }}</span>\n }\n </div>\n }\n </div>\n } @for (day of weekDays(); track day.date.getTime()) {\n <div\n class=\"c-bookings-grid__col\"\n [class.c-bookings-grid__col--weekend]=\"day.isWeekend\"\n >\n <div class=\"c-bookings-grid__top c-bookings-grid__top--weekly\">\n <div class=\"c-bookings-grid__day-header\" [class.is-today]=\"day.isToday\">\n <span class=\"c-bookings-grid__day-name\">{{ day.dayName }}</span>\n <span\n class=\"c-bookings-grid__day-number\"\n [class.is-today]=\"day.isToday\"\n >{{ day.dayNumber }}</span\n >\n </div>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (!isSlotOccupiedForDay(day.date, slot)) { @if\n (isSlotDisabledForDay(day.date, slot)) {\n <button\n class=\"c-bookings-grid__slot c-bookings-grid__slot--disabled\"\n disabled\n [title]=\"disabledSlotLabel()\"\n ></button>\n } @else {\n <button\n class=\"c-bookings-grid__slot\"\n [title]=\"emptySlotLabel()\"\n (click)=\"onWeekSlotClick(day.date, slot)\"\n ></button>\n } } @if (shouldShowEventForDay(day.date, slot)) { @let event =\n getEventForDaySlot(day.date, slot); @if (event) {\n <div\n [class]=\"getEventClasses(event)\"\n [attr.data-type]=\"event.type\"\n [attr.data-status]=\"event.status\"\n [style.--rows]=\"getEventRowSpan(event)\"\n (mouseenter)=\"onEventHover($event, event)\"\n (mouseleave)=\"onEventLeave()\"\n (click)=\"onWeekEventClick(event, day.date)\"\n >\n <p class=\"c-bookings-grid__title\">\n {{ event.subtitle || event.title }}\n </p>\n <p class=\"c-bookings-grid__text\">\n {{ event.startTime }} - {{ event.endTime }}\n </p>\n </div>\n } }\n </div>\n }\n </div>\n }\n</div>\n} @else if (viewMode() === 'month') {\n<!-- MONTHLY VIEW -->\n<div class=\"c-bookings-grid__wrapper c-bookings-grid__wrapper--monthly\">\n <!-- Header Row -->\n <div class=\"c-bookings-grid__header-row\">\n @for (day of monthDays().slice(0, 7); track day.dayName) {\n <div class=\"c-bookings-grid__header-cell\">\n {{ day.dayName }}\n </div>\n }\n </div>\n\n <!-- Days Grid -->\n <div class=\"c-bookings-grid__month-grid\">\n @for (day of monthDays(); track day.date.getTime()) {\n <div\n class=\"c-bookings-grid__month-cell\"\n [class.is-today]=\"day.isToday\"\n [class.is-weekend]=\"day.isWeekend\"\n [class.is-other-month]=\"\n day.date.getUTCMonth() !== selectedDate().getUTCMonth()\n \"\n [class.is-disabled]=\"isDayDisabled(day.date)\"\n (click)=\"!isDayDisabled(day.date) && onMonthDayClick(day.date)\"\n >\n <div class=\"c-bookings-grid__month-day-number\">\n {{ day.dayNumber }}\n </div>\n\n <div class=\"c-bookings-grid__month-events\">\n @let dayEvents = getEventsForDay(day.date); @for (event of\n dayEvents.slice(0, 3); track event.id) {\n <div\n class=\"c-bookings-grid__month-event\"\n [attr.data-type]=\"event.type\"\n [style.background-color]=\"event.metadata?.['color']\"\n [style.border-left]=\"event.metadata?.['color'] ? '3px solid ' + event.metadata?.['color'] : ''\"\n (click)=\"$event.stopPropagation(); onMonthEventClick(event, day.date)\"\n >\n <span class=\"c-bookings-grid__month-event-title\">{{\n event.title\n }}</span>\n </div>\n } @if (dayEvents.length > 3) {\n <div\n class=\"c-bookings-grid__more-events\"\n (click)=\"openDayPopover(day.date, $event)\"\n >\n {{ dayEvents.length - 3 }} m\u00E1s\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (expandedDay()) {\n <div class=\"c-bookings-grid__popover-overlay\" (click)=\"closeDayPopover()\">\n <div class=\"c-bookings-grid__popover\" (click)=\"$event.stopPropagation()\">\n <div class=\"c-bookings-grid__popover-header\">\n <div class=\"c-bookings-grid__popover-date\">\n <span class=\"c-bookings-grid__popover-weekday\">{{\n expandedDay() | date : \"EEE\" : \"UTC\" : locale() | uppercase\n }}</span>\n <span class=\"c-bookings-grid__popover-daynum\">{{\n expandedDay() | date : \"d\" : \"UTC\"\n }}</span>\n </div>\n <button\n class=\"c-bookings-grid__popover-close\"\n (click)=\"closeDayPopover()\"\n >\n <span class=\"icon-cross\"></span>\n </button>\n </div>\n <div class=\"c-bookings-grid__popover-content\">\n @for (event of getExpandedDayEvents(); track event.id) {\n <div\n class=\"c-bookings-grid__month-event c-bookings-grid__month-event--popover\"\n [attr.data-type]=\"event.type\"\n [style.background-color]=\"event.metadata?.['color']\"\n [style.border-left]=\"event.metadata?.['color'] ? '3px solid ' + event.metadata?.['color'] : ''\"\n (click)=\"onMonthEventClick(event, expandedDay()!)\"\n >\n <span class=\"c-bookings-grid__month-event-title\">{{\n event.title\n }}</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n</div>\n}\n", styles: [":host{display:block;width:100%;overflow:visible}.c-bookings-grid__month-cell.is-disabled{background-color:#f3f4f6;cursor:not-allowed;opacity:.7}.c-bookings-grid__month-cell.is-disabled:hover{background-color:#f3f4f6}.c-bookings-grid__month-cell.is-disabled .c-bookings-grid__month-day-number{color:#9ca3af}.c-bookings-grid__slot--disabled{background-color:#f3f4f6;cursor:not-allowed}.c-bookings-grid__slot--disabled:hover{background-color:#f3f4f6}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i2.DatePipe, name: "date" }] });
|
|
21355
21710
|
}
|
|
21356
21711
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImport: i0, type: GenericSchedulerComponent, decorators: [{
|
|
21357
21712
|
type: Component,
|
|
21358
21713
|
args: [{ selector: 'core-generic-scheduler', standalone: true, imports: [CommonModule], host: {
|
|
21359
21714
|
'class': 'c-bookings-grid c-bookings-card',
|
|
21715
|
+
'[class.c-bookings-grid--weekly]': 'viewMode() === "week"',
|
|
21360
21716
|
'[style.--cols]': 'columns().length'
|
|
21361
|
-
}, template: "@if (showHeader()) {\n<div class=\"c-bookings-header\">\n <button class=\"c-bookings-header__today\" (click)=\"onTodayClick()\">\n {{ todayLabel() }}\n </button>\n\n <div class=\"c-bookings-header__date\">\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-left\"\n title=\"D\u00EDa anterior\"\n (click)=\"onPreviousDay()\"\n ></button>\n <span>{{ formattedDate() }}</span>\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-right\"\n title=\"D\u00EDa siguiente\"\n (click)=\"onNextDay()\"\n ></button>\n </div>\n</div>\n}\n\n<div\n class=\"c-bookings-grid__wrapper\"\n [style.--cols]=\"columns().length\"\n style=\"position: relative\"\n>\n @if (isToday() && currentTimePosition() !== null) {\n <div\n class=\"c-bookings-grid__current-time-line\"\n [style.--time-position-rem]=\"currentTimePosition()\"\n ></div>\n } @if (showTimeColumn()) {\n <div class=\"c-bookings-grid__times\">\n <div class=\"c-bookings-grid__top\">\n <div class=\"c-bookings-grid__title\">{{ timeColumnLabel() }}</div>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (slot.displayTime) {\n <span class=\"c-bookings-grid__time\">{{ slot.time }}</span>\n }\n </div>\n }\n </div>\n } @for (column of columns(); track column.id) {\n <div class=\"c-bookings-grid__col\">\n <div class=\"c-bookings-grid__top\">\n <p class=\"c-bookings-grid__title\">{{ column.name }}</p>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (!isSlotOccupied(column.id, slot)) { @if (isSlotDisabled(column.id,\n slot)) {\n <button\n class=\"c-bookings-grid__slot c-bookings-grid__slot--disabled\"\n disabled\n [title]=\"disabledSlotLabel()\"\n >\n {{ disabledSlotLabel() }}\n </button>\n } @else {\n <button\n class=\"c-bookings-grid__slot\"\n [title]=\"emptySlotLabel()\"\n (click)=\"onSlotClick(column.id, slot)\"\n >\n {{ emptySlotLabel() }}\n </button>\n } } @if (shouldShowEvent(column.id, slot)) { @let event =\n getEventForSlot(column.id, slot); @if (event) {\n <div\n [class]=\"getEventClasses(event)\"\n [attr.data-type]=\"event.type\"\n [attr.data-status]=\"event.status\"\n [style.--rows]=\"getEventRowSpan(event)\"\n (mouseenter)=\"onEventHover($event, event)\"\n (mouseleave)=\"onEventLeave()\"\n (click)=\"onEventClick(event, column)\"\n >\n <p class=\"c-bookings-grid__title\">\n {{ event.subtitle || event.title }}\n </p>\n <p class=\"c-bookings-grid__text\">\n {{ event.startTime }} - {{ event.endTime }}\n </p>\n\n @if (event.canCancel) {\n <button\n class=\"c-bookings-grid__link c-link--underlined\"\n (click)=\"$event.stopPropagation()\"\n >\n <span class=\"icon-cross-thin\"></span>\n Cancelar\n </button>\n } @if ((event.canApprove || event.canReject) && event.duration >= 91) {\n <div class=\"c-bookings-grid__quick-actions\">\n @if (event.canApprove) {\n <button\n class=\"c-icon-btn--fill context:success icon-check\"\n title=\"Aprobar\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n } @if (event.canReject) {\n <button\n class=\"c-icon-btn--fill context:error icon-cross\"\n title=\"Rechazar\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n }\n </div>\n }\n </div>\n } }\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;overflow:visible}\n"] }]
|
|
21717
|
+
}, template: "@if (showHeader()) {\n<div class=\"c-bookings-header\">\n <button class=\"c-bookings-header__today\" (click)=\"onTodayClick()\">\n {{ todayLabel() }}\n </button>\n\n <div class=\"c-bookings-header__date\">\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-left\"\n [title]=\"viewMode() === 'week' ? 'Semana anterior' : 'D\u00EDa anterior'\"\n (click)=\"onPrevious()\"\n ></button>\n <span>{{ formattedDate() }}</span>\n <button\n class=\"c-bookings-header__date-arrow icon-arrow-right\"\n [title]=\"viewMode() === 'week' ? 'Semana siguiente' : 'D\u00EDa siguiente'\"\n (click)=\"onNext()\"\n ></button>\n </div>\n\n <div class=\"c-bookings-header__view-toggle\">\n <button\n class=\"c-bookings-header__view-btn\"\n [class.is-active]=\"viewMode() === 'day'\"\n (click)=\"setViewMode('day')\"\n >\n {{ dayLabel() }}\n </button>\n <button\n class=\"c-bookings-header__view-btn\"\n [class.is-active]=\"viewMode() === 'week'\"\n (click)=\"setViewMode('week')\"\n >\n {{ weekLabel() }}\n </button>\n <button\n class=\"c-bookings-header__view-btn\"\n [class.is-active]=\"viewMode() === 'month'\"\n (click)=\"setViewMode('month')\"\n >\n {{ monthLabel() }}\n </button>\n </div>\n</div>\n} @if (viewMode() === 'day') {\n<!-- DAILY VIEW -->\n<div\n class=\"c-bookings-grid__wrapper\"\n [style.--cols]=\"columns().length\"\n style=\"position: relative\"\n>\n @if (isToday() && currentTimePosition() !== null) {\n <div\n class=\"c-bookings-grid__current-time-line\"\n [style.--time-position-rem]=\"currentTimePosition()\"\n ></div>\n } @if (showTimeColumn()) {\n <div class=\"c-bookings-grid__times\">\n <div class=\"c-bookings-grid__top\">\n <div class=\"c-bookings-grid__title\">{{ timeColumnLabel() }}</div>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (slot.displayTime) {\n <span class=\"c-bookings-grid__time\">{{ slot.time }}</span>\n }\n </div>\n }\n </div>\n } @for (column of columns(); track column.id) {\n <div class=\"c-bookings-grid__col\">\n <div class=\"c-bookings-grid__top\">\n <p class=\"c-bookings-grid__title\">{{ column.name }}</p>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (!isSlotOccupied(column.id, slot)) { @if (isSlotDisabled(column.id,\n slot)) {\n <button\n class=\"c-bookings-grid__slot c-bookings-grid__slot--disabled\"\n disabled\n [title]=\"disabledSlotLabel()\"\n >\n {{ disabledSlotLabel() }}\n </button>\n } @else {\n <button\n class=\"c-bookings-grid__slot\"\n [title]=\"emptySlotLabel()\"\n (click)=\"onSlotClick(column.id, slot)\"\n >\n {{ emptySlotLabel() }}\n </button>\n } } @if (shouldShowEvent(column.id, slot)) { @let event =\n getEventForSlot(column.id, slot); @if (event) {\n <div\n [class]=\"getEventClasses(event)\"\n [attr.data-type]=\"event.type\"\n [attr.data-status]=\"event.status\"\n [style.--rows]=\"getEventRowSpan(event)\"\n (mouseenter)=\"onEventHover($event, event)\"\n (mouseleave)=\"onEventLeave()\"\n (click)=\"onEventClick(event, column)\"\n >\n <p class=\"c-bookings-grid__title\">\n {{ event.subtitle || event.title }}\n </p>\n <p class=\"c-bookings-grid__text\">\n {{ event.startTime }} - {{ event.endTime }}\n </p>\n\n @if (event.canCancel) {\n <button\n class=\"c-bookings-grid__link c-link--underlined\"\n (click)=\"$event.stopPropagation()\"\n >\n <span class=\"icon-cross-thin\"></span>\n Cancelar\n </button>\n } @if ((event.canApprove || event.canReject) && event.duration >= 91) {\n <div class=\"c-bookings-grid__quick-actions\">\n @if (event.canApprove) {\n <button\n class=\"c-icon-btn--fill context:success icon-check\"\n title=\"Aprobar\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n } @if (event.canReject) {\n <button\n class=\"c-icon-btn--fill context:error icon-cross\"\n title=\"Rechazar\"\n (click)=\"$event.stopPropagation()\"\n ></button>\n }\n </div>\n }\n </div>\n } }\n </div>\n }\n </div>\n }\n</div>\n} @else if (viewMode() === 'week') {\n<!-- WEEKLY VIEW -->\n<div\n class=\"c-bookings-grid__wrapper c-bookings-grid__wrapper--weekly\"\n [style.--cols]=\"7\"\n style=\"position: relative\"\n>\n @if (currentTimePosition() !== null && currentTimeDayIndex() >= 0) {\n <div\n class=\"c-bookings-grid__current-time-line c-bookings-grid__current-time-line--weekly\"\n [style.--time-position-rem]=\"currentTimePosition()\"\n [style.--day-index]=\"currentTimeDayIndex()\"\n ></div>\n } @if (showTimeColumn()) {\n <div class=\"c-bookings-grid__times\">\n <div class=\"c-bookings-grid__top c-bookings-grid__top--weekly\">\n <div class=\"c-bookings-grid__title\">{{ timeColumnLabel() }}</div>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (slot.displayTime) {\n <span class=\"c-bookings-grid__time\">{{ slot.time }}</span>\n }\n </div>\n }\n </div>\n } @for (day of weekDays(); track day.date.getTime()) {\n <div\n class=\"c-bookings-grid__col\"\n [class.c-bookings-grid__col--weekend]=\"day.isWeekend\"\n >\n <div class=\"c-bookings-grid__top c-bookings-grid__top--weekly\">\n <div class=\"c-bookings-grid__day-header\" [class.is-today]=\"day.isToday\">\n <span class=\"c-bookings-grid__day-name\">{{ day.dayName }}</span>\n <span\n class=\"c-bookings-grid__day-number\"\n [class.is-today]=\"day.isToday\"\n >{{ day.dayNumber }}</span\n >\n </div>\n </div>\n\n @for (slot of timeSlots(); track slot.time) {\n <div class=\"c-bookings-grid__row\">\n @if (!isSlotOccupiedForDay(day.date, slot)) { @if\n (isSlotDisabledForDay(day.date, slot)) {\n <button\n class=\"c-bookings-grid__slot c-bookings-grid__slot--disabled\"\n disabled\n [title]=\"disabledSlotLabel()\"\n ></button>\n } @else {\n <button\n class=\"c-bookings-grid__slot\"\n [title]=\"emptySlotLabel()\"\n (click)=\"onWeekSlotClick(day.date, slot)\"\n ></button>\n } } @if (shouldShowEventForDay(day.date, slot)) { @let event =\n getEventForDaySlot(day.date, slot); @if (event) {\n <div\n [class]=\"getEventClasses(event)\"\n [attr.data-type]=\"event.type\"\n [attr.data-status]=\"event.status\"\n [style.--rows]=\"getEventRowSpan(event)\"\n (mouseenter)=\"onEventHover($event, event)\"\n (mouseleave)=\"onEventLeave()\"\n (click)=\"onWeekEventClick(event, day.date)\"\n >\n <p class=\"c-bookings-grid__title\">\n {{ event.subtitle || event.title }}\n </p>\n <p class=\"c-bookings-grid__text\">\n {{ event.startTime }} - {{ event.endTime }}\n </p>\n </div>\n } }\n </div>\n }\n </div>\n }\n</div>\n} @else if (viewMode() === 'month') {\n<!-- MONTHLY VIEW -->\n<div class=\"c-bookings-grid__wrapper c-bookings-grid__wrapper--monthly\">\n <!-- Header Row -->\n <div class=\"c-bookings-grid__header-row\">\n @for (day of monthDays().slice(0, 7); track day.dayName) {\n <div class=\"c-bookings-grid__header-cell\">\n {{ day.dayName }}\n </div>\n }\n </div>\n\n <!-- Days Grid -->\n <div class=\"c-bookings-grid__month-grid\">\n @for (day of monthDays(); track day.date.getTime()) {\n <div\n class=\"c-bookings-grid__month-cell\"\n [class.is-today]=\"day.isToday\"\n [class.is-weekend]=\"day.isWeekend\"\n [class.is-other-month]=\"\n day.date.getUTCMonth() !== selectedDate().getUTCMonth()\n \"\n [class.is-disabled]=\"isDayDisabled(day.date)\"\n (click)=\"!isDayDisabled(day.date) && onMonthDayClick(day.date)\"\n >\n <div class=\"c-bookings-grid__month-day-number\">\n {{ day.dayNumber }}\n </div>\n\n <div class=\"c-bookings-grid__month-events\">\n @let dayEvents = getEventsForDay(day.date); @for (event of\n dayEvents.slice(0, 3); track event.id) {\n <div\n class=\"c-bookings-grid__month-event\"\n [attr.data-type]=\"event.type\"\n [style.background-color]=\"event.metadata?.['color']\"\n [style.border-left]=\"event.metadata?.['color'] ? '3px solid ' + event.metadata?.['color'] : ''\"\n (click)=\"$event.stopPropagation(); onMonthEventClick(event, day.date)\"\n >\n <span class=\"c-bookings-grid__month-event-title\">{{\n event.title\n }}</span>\n </div>\n } @if (dayEvents.length > 3) {\n <div\n class=\"c-bookings-grid__more-events\"\n (click)=\"openDayPopover(day.date, $event)\"\n >\n {{ dayEvents.length - 3 }} m\u00E1s\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (expandedDay()) {\n <div class=\"c-bookings-grid__popover-overlay\" (click)=\"closeDayPopover()\">\n <div class=\"c-bookings-grid__popover\" (click)=\"$event.stopPropagation()\">\n <div class=\"c-bookings-grid__popover-header\">\n <div class=\"c-bookings-grid__popover-date\">\n <span class=\"c-bookings-grid__popover-weekday\">{{\n expandedDay() | date : \"EEE\" : \"UTC\" : locale() | uppercase\n }}</span>\n <span class=\"c-bookings-grid__popover-daynum\">{{\n expandedDay() | date : \"d\" : \"UTC\"\n }}</span>\n </div>\n <button\n class=\"c-bookings-grid__popover-close\"\n (click)=\"closeDayPopover()\"\n >\n <span class=\"icon-cross\"></span>\n </button>\n </div>\n <div class=\"c-bookings-grid__popover-content\">\n @for (event of getExpandedDayEvents(); track event.id) {\n <div\n class=\"c-bookings-grid__month-event c-bookings-grid__month-event--popover\"\n [attr.data-type]=\"event.type\"\n [style.background-color]=\"event.metadata?.['color']\"\n [style.border-left]=\"event.metadata?.['color'] ? '3px solid ' + event.metadata?.['color'] : ''\"\n (click)=\"onMonthEventClick(event, expandedDay()!)\"\n >\n <span class=\"c-bookings-grid__month-event-title\">{{\n event.title\n }}</span>\n </div>\n }\n </div>\n </div>\n </div>\n }\n</div>\n}\n", styles: [":host{display:block;width:100%;overflow:visible}.c-bookings-grid__month-cell.is-disabled{background-color:#f3f4f6;cursor:not-allowed;opacity:.7}.c-bookings-grid__month-cell.is-disabled:hover{background-color:#f3f4f6}.c-bookings-grid__month-cell.is-disabled .c-bookings-grid__month-day-number{color:#9ca3af}.c-bookings-grid__slot--disabled{background-color:#f3f4f6;cursor:not-allowed}.c-bookings-grid__slot--disabled:hover{background-color:#f3f4f6}\n"] }]
|
|
21362
21718
|
}] });
|
|
21363
21719
|
|
|
21364
21720
|
class CacheBustingInterceptor {
|
|
@@ -21642,5 +21998,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.6", ngImpor
|
|
|
21642
21998
|
* Generated bundle index. Do not edit.
|
|
21643
21999
|
*/
|
|
21644
22000
|
|
|
21645
|
-
export { AD_AUTH_CONFIG, AD_AUTH_INTERCEPTOR_CONFIG, ALL_COUNTRY_CODES, ActiveFiltersComponent, AdAuthService, AdInteractionType, AdLoginButtonComponent, AgeValidationHelper, AlertComponent, AlertContainerComponent, AlertService, AlertType, ApiConfigurationProvider, BaseFieldComponent, ButtonContext, ButtonSize, ButtonType, COMMON_COUNTRIES, CacheBustingInterceptor, CalendarEventType, CardComponent, CarouselComponent, ChatMessagePosition, ChatMessageType, CheckboxFieldComponent, ConfigurationModel, ConfirmationDialogComponent, ConfirmationDialogService, CoreHostDirective, CoreManualRefreshComponent, CoreUiHttpLoaderFactory, CoreUiTranslateLoader, CoreUiTranslateService, CountryCode, CustomClassService, DEFAULT_AD_AUTH_INTERCEPTOR_CONFIG, DEFAULT_COUNTRIES, DEFAULT_SCHEDULER_CONFIG, DataListComponent, DataListItemComponent, DataStoreService, DateFieldComponent, DateUtility, DatetimeFieldComponent, DayState, DayType, DialogActions, DocumentAction, DocumentDisplayMode, DocumentFieldComponent, DocumentFieldValidators, DocumentPayloadMode, DropdownComponent, DropdownDirection, DropdownService, DynamicFieldDirective, DynamicFieldsHelper, FieldErrorsComponent, FieldType, FileFieldComponent, FileModel, FilePreviewActionType, FileTemplateModel, FileTemplateType, FileType, FileTypeModel, FileUploadService, FilterModalComponent, FilterService, FilterType, FixedActionPosition, FixedActionsMobileModalComponent, FixedActionsMobileModalService, GalleryAnimationType, GalleryLayoutType, GalleryModalComponent, GalleryModalGlobalService, GenericButtonComponent, GenericCalendarComponent, GenericChatComponent, GenericChatService, GenericDocumentationComponent, GenericFixedActionsComponent, GenericGalleryComponent, GenericModalComponent, GenericPaginationComponent, GenericRatingComponent, GenericSchedulerComponent, GenericSidebarComponent, GenericSkeletonComponent, GenericStepsComponent, GenericSwitchComponent, GenericTableComponent, GenericTabsComponent, GenericTimelineComponent, GlobalApiConfigService, HeaderComponent, HeaderConfigurationService, HeaderElementType, HeaderService, HttpLoaderFactory, ImageModalComponent, ImageModalService, ImagePreviewComponent, LATIN_AMERICA_COUNTRIES, LayoutAuth, LayoutBreakpoint, LayoutComponent, LayoutService, LayoutStateService, LayoutType, LoaderComponent, LoaderService, MODEL_REFERENCE_SORT_KEY, MainNavComponent, MainNavService, ManualRefreshService, MobileHeaderComponent, MobileResolutionService, ModalMode, ModelApiService, MultiEntryFieldComponent, MultiEntryOutputFormat, NumberFieldComponent, NumberFieldConfigType, NumberFieldType, NumberRange, PERMISSION_ACTIONS_PROVIDER, PERMISSION_PROVIDER, PERMISSION_RESOURCES_PROVIDER, PaginationService, PasswordFieldComponent, PermissionEnumsService, PermissionModel, PermissionService, PermissionWrapperService, PermissionsActions, PermissionsCustomActions, PermissionsInterceptor, PermissionsResources, PhoneFieldComponent, ProgressBarComponent, ProgressBarSize, RatingService, RatingSize, RatingType, RedirectUrlService, ResetPasswordModel, RoleModel, SOUTH_AMERICA_COUNTRIES, SelectFieldComponent, ServerSelectFieldComponent, ServerSelectService, SidebarCustomModalComponent, SidebarCustomModalService, SidebarHeight, SidebarMobileModalService, SidebarMobileType, SidebarPosition, SidebarService, SidebarState, SidebarTemplateRegistryService, SidebarVisibility, SidebarWidth, SkeletonAnimation, SkeletonService, SkeletonSize, SkeletonType, SmartFieldComponent, SortDirection, SortMode, StepSize, StepStatus, StepType, StepsService, SwitchFieldComponent, TableAction, TableActionService, TableDataService, TableFixedActionsService, TableSortService, TextAreaFieldComponent, TextFieldComponent, TimeFieldComponent, TimeInterval, TimelineService, TimelineStatus, TimelineType, TranslationMergeService, UruguayanDocumentValidationHelper, UsersModel, VERSION, WeekDay, adAuthGuard, adAuthInterceptor, adGuestGuard, adRoleGuard, ageValidator, calculateAge, equalToValidator, generateRandomUruguayanDocument, getCountryCodeStrings, getLatestBirthDateForAge, getRandomCi, getUruguayanDocumentValidationDigit, getValidationDigit, isSameDate, isValidCountryCode, provideAdAuth, provideAdAuthInterceptor, provideAdAuthWithInterceptor, provideCoreUiTranslateLoader, providePermissionActions, providePermissionEnums, providePermissionResources, providePermissionService, providePermissionServiceFactory, provideTranslateLoader, random, transform, transformUruguayanDocument, uruguayanDocumentValidator, validate, validateAge, validateCi, validateUruguayanDocument, validationDigit };
|
|
22001
|
+
export { AD_AUTH_CONFIG, AD_AUTH_INTERCEPTOR_CONFIG, ALL_COUNTRY_CODES, ActiveFiltersComponent, AdAuthService, AdInteractionType, AdLoginButtonComponent, AgeValidationHelper, AlertComponent, AlertContainerComponent, AlertService, AlertType, ApiConfigurationProvider, BaseFieldComponent, ButtonContext, ButtonSize, ButtonType, COMMON_COUNTRIES, CacheBustingInterceptor, CalendarEventType, CardComponent, CarouselComponent, ChatMessagePosition, ChatMessageType, CheckboxFieldComponent, ColorPickerFieldComponent, ConfigurationModel, ConfirmationDialogComponent, ConfirmationDialogService, CoreHostDirective, CoreManualRefreshComponent, CoreUiHttpLoaderFactory, CoreUiTranslateLoader, CoreUiTranslateService, CountryCode, CustomClassService, DEFAULT_AD_AUTH_INTERCEPTOR_CONFIG, DEFAULT_COUNTRIES, DEFAULT_SCHEDULER_CONFIG, DataListComponent, DataListItemComponent, DataStoreService, DateFieldComponent, DateUtility, DatetimeFieldComponent, DayState, DayType, DialogActions, DocumentAction, DocumentDisplayMode, DocumentFieldComponent, DocumentFieldValidators, DocumentPayloadMode, DropdownComponent, DropdownDirection, DropdownService, DynamicFieldDirective, DynamicFieldsHelper, FieldErrorsComponent, FieldType, FileFieldComponent, FileModel, FilePreviewActionType, FileTemplateModel, FileTemplateType, FileType, FileTypeModel, FileUploadService, FilterModalComponent, FilterService, FilterType, FixedActionPosition, FixedActionsMobileModalComponent, FixedActionsMobileModalService, GalleryAnimationType, GalleryLayoutType, GalleryModalComponent, GalleryModalGlobalService, GenericButtonComponent, GenericCalendarComponent, GenericChatComponent, GenericChatService, GenericDocumentationComponent, GenericFixedActionsComponent, GenericGalleryComponent, GenericModalComponent, GenericPaginationComponent, GenericRatingComponent, GenericSchedulerComponent, GenericSidebarComponent, GenericSkeletonComponent, GenericStepsComponent, GenericSwitchComponent, GenericTableComponent, GenericTabsComponent, GenericTimelineComponent, GlobalApiConfigService, HeaderComponent, HeaderConfigurationService, HeaderElementType, HeaderService, HttpLoaderFactory, ImageModalComponent, ImageModalService, ImagePreviewComponent, LATIN_AMERICA_COUNTRIES, LayoutAuth, LayoutBreakpoint, LayoutComponent, LayoutService, LayoutStateService, LayoutType, LoaderComponent, LoaderService, MODEL_REFERENCE_SORT_KEY, MainNavComponent, MainNavService, ManualRefreshService, MobileHeaderComponent, MobileResolutionService, ModalMode, ModelApiService, MultiEntryFieldComponent, MultiEntryOutputFormat, NumberFieldComponent, NumberFieldConfigType, NumberFieldType, NumberRange, PERMISSION_ACTIONS_PROVIDER, PERMISSION_PROVIDER, PERMISSION_RESOURCES_PROVIDER, PaginationService, PasswordFieldComponent, PermissionEnumsService, PermissionModel, PermissionService, PermissionWrapperService, PermissionsActions, PermissionsCustomActions, PermissionsInterceptor, PermissionsResources, PhoneFieldComponent, ProgressBarComponent, ProgressBarSize, RatingService, RatingSize, RatingType, RedirectUrlService, ResetPasswordModel, RoleModel, SOUTH_AMERICA_COUNTRIES, SelectFieldComponent, ServerSelectFieldComponent, ServerSelectService, SidebarCustomModalComponent, SidebarCustomModalService, SidebarHeight, SidebarMobileModalService, SidebarMobileType, SidebarPosition, SidebarService, SidebarState, SidebarTemplateRegistryService, SidebarVisibility, SidebarWidth, SkeletonAnimation, SkeletonService, SkeletonSize, SkeletonType, SmartFieldComponent, SortDirection, SortMode, StepSize, StepStatus, StepType, StepsService, SwitchFieldComponent, TableAction, TableActionService, TableDataService, TableFixedActionsService, TableSortService, TextAreaFieldComponent, TextFieldComponent, TimeFieldComponent, TimeInterval, TimelineService, TimelineStatus, TimelineType, TranslationMergeService, UruguayanDocumentValidationHelper, UsersModel, VERSION, WeekDay, adAuthGuard, adAuthInterceptor, adGuestGuard, adRoleGuard, ageValidator, calculateAge, equalToValidator, generateRandomUruguayanDocument, getCountryCodeStrings, getLatestBirthDateForAge, getRandomCi, getUruguayanDocumentValidationDigit, getValidationDigit, isSameDate, isValidCountryCode, provideAdAuth, provideAdAuthInterceptor, provideAdAuthWithInterceptor, provideCoreUiTranslateLoader, providePermissionActions, providePermissionEnums, providePermissionResources, providePermissionService, providePermissionServiceFactory, provideTranslateLoader, random, transform, transformUruguayanDocument, uruguayanDocumentValidator, validate, validateAge, validateCi, validateUruguayanDocument, validationDigit };
|
|
21646
22002
|
//# sourceMappingURL=solcre-org-core-ui.mjs.map
|