@cerca/design-system 1.0.0 → 1.0.2

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,82 +1,239 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, signal, computed, Input, Component, forwardRef, EventEmitter, Output, ContentChild, HostListener, inject, HostBinding } from '@angular/core';
3
- import * as i1$2 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
5
- import * as i1 from 'ng-zorro-antd/button';
6
- import { NzButtonModule } from 'ng-zorro-antd/button';
7
- import * as i3$1 from 'ng-zorro-antd/icon';
8
- import { NzIconModule } from 'ng-zorro-antd/icon';
9
- import * as i2 from 'ng-zorro-antd/core/transition-patch';
10
- import * as i3 from 'ng-zorro-antd/core/wave';
2
+ import { Component, Injectable, Input, input, computed, output, HostListener, inject, signal, forwardRef, ViewEncapsulation, effect, createComponent, ChangeDetectionStrategy, ContentChild, ViewContainerRef, ViewChild, HostBinding } from '@angular/core';
11
3
  import * as i1$1 from '@angular/forms';
12
- import { FormsModule, NG_VALUE_ACCESSOR, FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
13
- import * as i2$1 from 'ng-zorro-antd/input';
14
- import { NzInputModule } from 'ng-zorro-antd/input';
15
- import { NzSelectComponent, NzOptionComponent } from 'ng-zorro-antd/select';
16
- import * as i1$3 from 'ng-zorro-antd/card';
17
- import { NzCardModule } from 'ng-zorro-antd/card';
18
- import { Subject, Subscription } from 'rxjs';
4
+ import { Validators, FormBuilder, FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule, FormGroup, FormControl } from '@angular/forms';
5
+ import * as i1 from '@angular/common';
6
+ import { CommonModule, NgClass, DatePipe, CurrencyPipe, DecimalPipe, PercentPipe } from '@angular/common';
7
+ import { Subject, Subscription, debounceTime as debounceTime$1, distinctUntilChanged as distinctUntilChanged$1, takeUntil } from 'rxjs';
8
+ import { __decorate } from 'tslib';
9
+ import { z } from 'zod';
19
10
  import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
20
- import { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router';
21
- import * as i2$2 from 'ng-zorro-antd/alert';
22
- import { NzAlertModule } from 'ng-zorro-antd/alert';
23
- import * as i4 from 'ng-zorro-antd/checkbox';
24
- import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';
25
- import { NzFormDirective, NzFormControlComponent, NzFormLabelComponent, NzFormItemComponent } from 'ng-zorro-antd/form';
26
-
27
- class CcButtonComponent {
11
+ import * as i1$2 from '@angular/router';
12
+ import { RouterLink, RouterLinkActive } from '@angular/router';
13
+
14
+ class DesignSystem {
15
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DesignSystem, deps: [], target: i0.ɵɵFactoryTarget.Component });
16
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: DesignSystem, isStandalone: true, selector: "ad-design-system", ngImport: i0, template: `
17
+ <p>
18
+ design-system works!
19
+ </p>
20
+ `, isInline: true, styles: [""] });
21
+ }
22
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DesignSystem, decorators: [{
23
+ type: Component,
24
+ args: [{ selector: 'ad-design-system', imports: [], template: `
25
+ <p>
26
+ design-system works!
27
+ </p>
28
+ ` }]
29
+ }] });
30
+
31
+ class FieldRendererRegistry {
32
+ renderers = new Map();
33
+ register(key, component) {
34
+ if (this.renderers.has(key)) {
35
+ console.warn(`Renderer for key '${key}' is already registered. Overwriting.`);
36
+ }
37
+ this.renderers.set(key, component);
38
+ }
39
+ get(key) {
40
+ return this.renderers.get(key);
41
+ }
42
+ has(key) {
43
+ return this.renderers.has(key);
44
+ }
45
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FieldRendererRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
46
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FieldRendererRegistry, providedIn: 'root' });
47
+ }
48
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FieldRendererRegistry, decorators: [{
49
+ type: Injectable,
50
+ args: [{
51
+ providedIn: 'root'
52
+ }]
53
+ }] });
54
+
55
+ class ValidatorRegistry {
56
+ validators = new Map();
28
57
  constructor() {
29
- this.variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : []));
30
- this.type = input('button', ...(ngDevMode ? [{ debugName: "type" }] : []));
31
- this._disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : []));
32
- this.loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
33
- this.icon = input(undefined, ...(ngDevMode ? [{ debugName: "icon" }] : []));
34
- this.size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : []));
35
- this.nzType = computed(() => {
36
- const variantMap = {
37
- 'primary': 'primary',
38
- 'secondary': 'default',
39
- 'ghost': 'text',
40
- 'outline': 'dashed'
41
- };
42
- return variantMap[this.variant()] || 'default';
43
- }, ...(ngDevMode ? [{ debugName: "nzType" }] : []));
58
+ this.registerDefaults();
44
59
  }
45
- set disabled(value) { this._disabled.set(value); }
46
- get disabled() { return this._disabled(); }
47
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
48
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: CcButtonComponent, isStandalone: true, selector: "cc-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<button nz-button [nzType]=\"nzType()\" [nzLoading]=\"loading()\" [nzSize]=\"size()\" [disabled]=\"disabled\" [type]=\"type()\"\r\n class=\"cerca-btn\">\r\n @if (icon(); as iconName) {\r\n <span nz-icon [nzType]=\"$any(iconName)\"></span>\r\n }\r\n <ng-content></ng-content>\r\n</button>", styles: [".cerca-btn{min-height:44px;min-width:44px;font-family:var(--font-family-base);font-weight:var(--btn-font-weight, var(--font-weight-medium));border-radius:var(--btn-radius, var(--radius-md));transition:all .2s cubic-bezier(.4,0,.2,1)}.cerca-btn:focus-visible{box-shadow:0 0 0 3px var(--color-focus-ring);outline:none}.cerca-btn:hover:not(:disabled){transform:translateY(-1px)}.cerca-btn:active:not(:disabled){transform:translateY(0)}:host ::ng-deep .ant-btn-primary.cerca-btn{background-color:var(--btn-bg-primary, var(--color-brand));border-color:var(--btn-bg-primary, var(--color-brand));box-shadow:var(--btn-shadow-default, var(--shadow-sm))}:host ::ng-deep .ant-btn-primary.cerca-btn:hover:not(:disabled){background-color:var(--color-brand-hover);border-color:var(--color-brand-hover);box-shadow:var(--btn-shadow-hover, var(--shadow-md))}:host ::ng-deep .ant-btn-default.cerca-btn{background-color:var(--color-bg-primary);color:var(--color-brand);border-color:var(--color-border-strong)}:host ::ng-deep .ant-btn-default.cerca-btn:hover:not(:disabled){background-color:var(--color-bg-secondary);border-color:var(--color-brand);color:var(--color-brand)}:host ::ng-deep .ant-btn-text.cerca-btn{color:var(--color-text-secondary)}:host ::ng-deep .ant-btn-text.cerca-btn:hover:not(:disabled){background-color:var(--color-bg-secondary);color:var(--color-brand)}:host ::ng-deep .ant-btn-dashed.cerca-btn{color:var(--color-brand);border-color:var(--color-brand)}:host ::ng-deep .ant-btn-dashed.cerca-btn:hover:not(:disabled){background-color:var(--color-bg-secondary);border-color:var(--color-brand-hover);color:var(--color-brand-hover)}:host ::ng-deep .cerca-btn:disabled{opacity:.5;cursor:not-allowed;transform:none!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: NzButtonModule }, { kind: "component", type: i1.NzButtonComponent, selector: "button[nz-button], a[nz-button]", inputs: ["nzBlock", "nzGhost", "nzSearch", "nzLoading", "nzDanger", "disabled", "tabIndex", "nzType", "nzShape", "nzSize"], exportAs: ["nzButton"] }, { kind: "directive", type: i2.ɵNzTransitionPatchDirective, selector: "[nz-button], [nz-icon], nz-icon, [nz-menu-item], [nz-submenu], nz-select-top-control, nz-select-placeholder, nz-input-group", inputs: ["hidden"] }, { kind: "directive", type: i3.NzWaveDirective, selector: "[nz-wave],button[nz-button]:not([nzType=\"link\"]):not([nzType=\"text\"])", inputs: ["nzWaveExtraNode"], exportAs: ["nzWave"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i3$1.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }] }); }
60
+ registerDefaults() {
61
+ this.register('required', () => Validators.required);
62
+ this.register('email', () => Validators.email);
63
+ this.register('min', (min) => Validators.min(min));
64
+ this.register('max', (max) => Validators.max(max));
65
+ this.register('minLength', (len) => Validators.minLength(len));
66
+ this.register('maxLength', (len) => Validators.maxLength(len));
67
+ this.register('pattern', (pattern) => Validators.pattern(pattern));
68
+ }
69
+ register(key, factory) {
70
+ this.validators.set(key, factory);
71
+ }
72
+ get(key, args) {
73
+ const factory = this.validators.get(key);
74
+ if (!factory) {
75
+ console.warn(`Validator '${key}' not found.`);
76
+ return null;
77
+ }
78
+ return factory(args);
79
+ }
80
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ValidatorRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
81
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ValidatorRegistry, providedIn: 'root' });
49
82
  }
50
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcButtonComponent, decorators: [{
83
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: ValidatorRegistry, decorators: [{
84
+ type: Injectable,
85
+ args: [{
86
+ providedIn: 'root'
87
+ }]
88
+ }], ctorParameters: () => [] });
89
+
90
+ class AdIconComponent {
91
+ name = '';
92
+ size = 'md';
93
+ color = 'currentColor';
94
+ get sizeClass() {
95
+ switch (this.size) {
96
+ case 'xs': return 'w-3 h-3 text-xs';
97
+ case 'sm': return 'w-4 h-4 text-base';
98
+ case 'md': return 'w-5 h-5 text-xl';
99
+ case 'lg': return 'w-6 h-6 text-2xl';
100
+ case 'xl': return 'w-8 h-8 text-3xl';
101
+ default: return 'w-5 h-5 text-xl';
102
+ }
103
+ }
104
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
105
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdIconComponent, isStandalone: true, selector: "ad-icon", inputs: { name: "name", size: "size", color: "color" }, ngImport: i0, template: "@if (name === 'user') {\r\n<svg [class]=\"sizeClass\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n d=\"M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z\" />\r\n</svg>\r\n} @else if (name === 'lock') {\r\n<svg [class]=\"sizeClass\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n d=\"M16.5 10.5V6.75a4.5 4.5 0 1 0-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H6.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z\" />\r\n</svg>\r\n} @else if (name === 'eye') {\r\n<svg [class]=\"sizeClass\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n d=\"M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z\" />\r\n</svg>\r\n} @else if (name === 'plus') {\r\n<svg [class]=\"sizeClass\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" />\r\n</svg>\r\n} @else if (name === 'download') {\r\n<svg [class]=\"sizeClass\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n d=\"M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3\" />\r\n</svg>\r\n} @else if (name === 'eye-invisible') {\r\n<svg [class]=\"sizeClass\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n d=\"M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88\" />\r\n</svg>\r\n} @else {\r\n<!-- Fallback -->\r\n<span class=\"material-icons-outlined ad-icon\" [ngClass]=\"sizeClass\">{{ name }}</span>\r\n}", styles: [".ad-icon{display:inline-flex;align-items:center;justify-content:center;font-family:Material Icons Outlined;font-weight:400;font-style:normal;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-smoothing:antialiased}.ad-icon.icon-xs{font-size:16px;width:16px;height:16px}.ad-icon.icon-sm{font-size:20px;width:20px;height:20px}.ad-icon.icon-md{font-size:24px;width:24px;height:24px}.ad-icon.icon-lg{font-size:32px;width:32px;height:32px}.ad-icon.icon-xl{font-size:40px;width:40px;height:40px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
106
+ }
107
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdIconComponent, decorators: [{
51
108
  type: Component,
52
- args: [{ selector: 'cc-button', standalone: true, imports: [CommonModule, NzButtonModule, NzIconModule], template: "<button nz-button [nzType]=\"nzType()\" [nzLoading]=\"loading()\" [nzSize]=\"size()\" [disabled]=\"disabled\" [type]=\"type()\"\r\n class=\"cerca-btn\">\r\n @if (icon(); as iconName) {\r\n <span nz-icon [nzType]=\"$any(iconName)\"></span>\r\n }\r\n <ng-content></ng-content>\r\n</button>", styles: [".cerca-btn{min-height:44px;min-width:44px;font-family:var(--font-family-base);font-weight:var(--btn-font-weight, var(--font-weight-medium));border-radius:var(--btn-radius, var(--radius-md));transition:all .2s cubic-bezier(.4,0,.2,1)}.cerca-btn:focus-visible{box-shadow:0 0 0 3px var(--color-focus-ring);outline:none}.cerca-btn:hover:not(:disabled){transform:translateY(-1px)}.cerca-btn:active:not(:disabled){transform:translateY(0)}:host ::ng-deep .ant-btn-primary.cerca-btn{background-color:var(--btn-bg-primary, var(--color-brand));border-color:var(--btn-bg-primary, var(--color-brand));box-shadow:var(--btn-shadow-default, var(--shadow-sm))}:host ::ng-deep .ant-btn-primary.cerca-btn:hover:not(:disabled){background-color:var(--color-brand-hover);border-color:var(--color-brand-hover);box-shadow:var(--btn-shadow-hover, var(--shadow-md))}:host ::ng-deep .ant-btn-default.cerca-btn{background-color:var(--color-bg-primary);color:var(--color-brand);border-color:var(--color-border-strong)}:host ::ng-deep .ant-btn-default.cerca-btn:hover:not(:disabled){background-color:var(--color-bg-secondary);border-color:var(--color-brand);color:var(--color-brand)}:host ::ng-deep .ant-btn-text.cerca-btn{color:var(--color-text-secondary)}:host ::ng-deep .ant-btn-text.cerca-btn:hover:not(:disabled){background-color:var(--color-bg-secondary);color:var(--color-brand)}:host ::ng-deep .ant-btn-dashed.cerca-btn{color:var(--color-brand);border-color:var(--color-brand)}:host ::ng-deep .ant-btn-dashed.cerca-btn:hover:not(:disabled){background-color:var(--color-bg-secondary);border-color:var(--color-brand-hover);color:var(--color-brand-hover)}:host ::ng-deep .cerca-btn:disabled{opacity:.5;cursor:not-allowed;transform:none!important}\n"] }]
53
- }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], disabled: [{
109
+ args: [{ selector: 'ad-icon', standalone: true, imports: [CommonModule], template: "@if (name === 'user') {\r\n<svg [class]=\"sizeClass\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n d=\"M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z\" />\r\n</svg>\r\n} @else if (name === 'lock') {\r\n<svg [class]=\"sizeClass\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n d=\"M16.5 10.5V6.75a4.5 4.5 0 1 0-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H6.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z\" />\r\n</svg>\r\n} @else if (name === 'eye') {\r\n<svg [class]=\"sizeClass\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n d=\"M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z\" />\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z\" />\r\n</svg>\r\n} @else if (name === 'plus') {\r\n<svg [class]=\"sizeClass\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" />\r\n</svg>\r\n} @else if (name === 'download') {\r\n<svg [class]=\"sizeClass\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n d=\"M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3\" />\r\n</svg>\r\n} @else if (name === 'eye-invisible') {\r\n<svg [class]=\"sizeClass\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n d=\"M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88\" />\r\n</svg>\r\n} @else {\r\n<!-- Fallback -->\r\n<span class=\"material-icons-outlined ad-icon\" [ngClass]=\"sizeClass\">{{ name }}</span>\r\n}", styles: [".ad-icon{display:inline-flex;align-items:center;justify-content:center;font-family:Material Icons Outlined;font-weight:400;font-style:normal;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-smoothing:antialiased}.ad-icon.icon-xs{font-size:16px;width:16px;height:16px}.ad-icon.icon-sm{font-size:20px;width:20px;height:20px}.ad-icon.icon-md{font-size:24px;width:24px;height:24px}.ad-icon.icon-lg{font-size:32px;width:32px;height:32px}.ad-icon.icon-xl{font-size:40px;width:40px;height:40px}\n"] }]
110
+ }], propDecorators: { name: [{
111
+ type: Input
112
+ }], size: [{
54
113
  type: Input
55
- }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
114
+ }], color: [{
115
+ type: Input
116
+ }] } });
56
117
 
57
- class CcInputComponent {
58
- constructor() {
59
- this.type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : []));
60
- this.placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
61
- this.label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
62
- this.error = input(false, ...(ngDevMode ? [{ debugName: "error" }] : []));
63
- this._disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : []));
64
- this.size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : []));
65
- this.prefix = input(undefined, ...(ngDevMode ? [{ debugName: "prefix" }] : []));
66
- this.suffix = input(undefined, ...(ngDevMode ? [{ debugName: "suffix" }] : []));
67
- this.value = '';
68
- this.passwordVisible = signal(false, ...(ngDevMode ? [{ debugName: "passwordVisible" }] : []));
69
- this.onChange = () => { };
70
- this.onTouched = () => { };
71
- this.inputType = computed(() => {
72
- if (this.type() === 'password') {
73
- return this.passwordVisible() ? 'text' : 'password';
118
+ class AdModalComponent {
119
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
120
+ isOpen = computed(() => this.resource().isOpen ?? false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
121
+ title = computed(() => this.resource().title ?? '', ...(ngDevMode ? [{ debugName: "title" }] : []));
122
+ accentedTitle = computed(() => this.resource().accentedTitle, ...(ngDevMode ? [{ debugName: "accentedTitle" }] : []));
123
+ size = computed(() => this.resource().size ?? 'md', ...(ngDevMode ? [{ debugName: "size" }] : []));
124
+ closeOnOverlay = computed(() => this.resource().closeOnOverlay ?? true, ...(ngDevMode ? [{ debugName: "closeOnOverlay" }] : []));
125
+ showFooter = computed(() => this.resource().showFooter ?? true, ...(ngDevMode ? [{ debugName: "showFooter" }] : []));
126
+ close = output();
127
+ onOverlayClick(event) {
128
+ if (this.closeOnOverlay() && event.target.classList.contains('ad-modal-overlay')) {
129
+ this.close.emit();
130
+ }
131
+ }
132
+ onEscape() {
133
+ if (this.isOpen()) {
134
+ this.close.emit();
135
+ }
136
+ }
137
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
138
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdModalComponent, isStandalone: true, selector: "ad-modal", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { close: "close" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "@if (isOpen()){\r\n<div class=\"ad-modal-overlay\" (click)=\"onOverlayClick($event)\">\r\n\r\n <div class=\"ad-modal\" [ngClass]=\"'size-' + size()\" role=\"dialog\" aria-modal=\"true\">\r\n\r\n <header class=\"ad-modal-header\">\r\n <h3 class=\"ad-modal-title\">\r\n {{ title() }}\r\n @if (accentedTitle()) {\r\n <span class=\"accent-text\">{{ accentedTitle() }}</span>\r\n }\r\n </h3>\r\n <button class=\"ad-modal-close\" (click)=\"close.emit()\" type=\"button\">\r\n <ad-icon name=\"close\" size=\"md\"></ad-icon>\r\n </button>\r\n </header>\r\n\r\n <div class=\"ad-modal-body\">\r\n <ng-content></ng-content>\r\n </div>\r\n @if (showFooter()){\r\n <footer class=\"ad-modal-footer\">\r\n <ng-content select=\"[footer]\"></ng-content>\r\n </footer>\r\n }\r\n </div>\r\n</div>\r\n}", styles: [".ad-modal-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:var(--modal-overlay-bg);display:flex;align-items:center;justify-content:center;z-index:var(--modal-z-index);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);padding:var(--space-4)}.ad-modal{background-color:var(--modal-bg);border-radius:var(--modal-radius);box-shadow:var(--modal-shadow);display:flex;flex-direction:column;max-height:90vh;width:100%;animation:modalScaleUp .2s ease-out;overflow:hidden;position:relative}.ad-modal.size-sm{max-width:var(--modal-sm-width)}.ad-modal.size-md{max-width:var(--modal-md-width)}.ad-modal.size-lg{max-width:var(--modal-lg-width)}.ad-modal-header{padding:var(--modal-header-padding);display:flex;align-items:center;justify-content:space-between;position:relative;border-bottom:none}.ad-modal-header:after{content:\"\";position:absolute;bottom:0;left:0;width:100%;height:4px;background:linear-gradient(to right,var(--color-primary),var(--color-primary-accent, #00d2ff))}.ad-modal-title{font-size:var(--font-size-lg);font-weight:var(--font-weight-bold);color:var(--color-text-primary);margin:0}.ad-modal-title .accent-text{background:linear-gradient(135deg,var(--color-primary) 0%,var(--color-primary-accent, #00d2ff) 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;margin-left:.3rem}.ad-modal-close{background:transparent;border:none;color:var(--color-text-muted);cursor:pointer;padding:var(--space-1);border-radius:var(--radius-md);display:flex;transition:all .15s ease}.ad-modal-close:hover{background-color:var(--color-bg-secondary);color:var(--color-text-primary)}.ad-modal-body{padding:var(--modal-body-padding);overflow-y:auto;flex:1}.ad-modal-footer{padding:var(--modal-footer-padding);border-top:1px solid var(--color-border-subtle);display:flex;justify-content:flex-end;gap:var(--space-3);background-color:var(--color-bg-secondary)}@keyframes modalScaleUp{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AdIconComponent, selector: "ad-icon", inputs: ["name", "size", "color"] }] });
139
+ }
140
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdModalComponent, decorators: [{
141
+ type: Component,
142
+ args: [{ selector: 'ad-modal', standalone: true, imports: [CommonModule, AdIconComponent], template: "@if (isOpen()){\r\n<div class=\"ad-modal-overlay\" (click)=\"onOverlayClick($event)\">\r\n\r\n <div class=\"ad-modal\" [ngClass]=\"'size-' + size()\" role=\"dialog\" aria-modal=\"true\">\r\n\r\n <header class=\"ad-modal-header\">\r\n <h3 class=\"ad-modal-title\">\r\n {{ title() }}\r\n @if (accentedTitle()) {\r\n <span class=\"accent-text\">{{ accentedTitle() }}</span>\r\n }\r\n </h3>\r\n <button class=\"ad-modal-close\" (click)=\"close.emit()\" type=\"button\">\r\n <ad-icon name=\"close\" size=\"md\"></ad-icon>\r\n </button>\r\n </header>\r\n\r\n <div class=\"ad-modal-body\">\r\n <ng-content></ng-content>\r\n </div>\r\n @if (showFooter()){\r\n <footer class=\"ad-modal-footer\">\r\n <ng-content select=\"[footer]\"></ng-content>\r\n </footer>\r\n }\r\n </div>\r\n</div>\r\n}", styles: [".ad-modal-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:var(--modal-overlay-bg);display:flex;align-items:center;justify-content:center;z-index:var(--modal-z-index);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);padding:var(--space-4)}.ad-modal{background-color:var(--modal-bg);border-radius:var(--modal-radius);box-shadow:var(--modal-shadow);display:flex;flex-direction:column;max-height:90vh;width:100%;animation:modalScaleUp .2s ease-out;overflow:hidden;position:relative}.ad-modal.size-sm{max-width:var(--modal-sm-width)}.ad-modal.size-md{max-width:var(--modal-md-width)}.ad-modal.size-lg{max-width:var(--modal-lg-width)}.ad-modal-header{padding:var(--modal-header-padding);display:flex;align-items:center;justify-content:space-between;position:relative;border-bottom:none}.ad-modal-header:after{content:\"\";position:absolute;bottom:0;left:0;width:100%;height:4px;background:linear-gradient(to right,var(--color-primary),var(--color-primary-accent, #00d2ff))}.ad-modal-title{font-size:var(--font-size-lg);font-weight:var(--font-weight-bold);color:var(--color-text-primary);margin:0}.ad-modal-title .accent-text{background:linear-gradient(135deg,var(--color-primary) 0%,var(--color-primary-accent, #00d2ff) 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;margin-left:.3rem}.ad-modal-close{background:transparent;border:none;color:var(--color-text-muted);cursor:pointer;padding:var(--space-1);border-radius:var(--radius-md);display:flex;transition:all .15s ease}.ad-modal-close:hover{background-color:var(--color-bg-secondary);color:var(--color-text-primary)}.ad-modal-body{padding:var(--modal-body-padding);overflow-y:auto;flex:1}.ad-modal-footer{padding:var(--modal-footer-padding);border-top:1px solid var(--color-border-subtle);display:flex;justify-content:flex-end;gap:var(--space-3);background-color:var(--color-bg-secondary)}@keyframes modalScaleUp{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}\n"] }]
143
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], close: [{ type: i0.Output, args: ["close"] }], onEscape: [{
144
+ type: HostListener,
145
+ args: ['document:keydown.escape']
146
+ }] } });
147
+
148
+ let FormEngineService = class FormEngineService {
149
+ fb = inject(FormBuilder);
150
+ validatorRegistry = inject(ValidatorRegistry); // Assuming this exists or mocking behavior
151
+ createFormGroup(schema, model = {}) {
152
+ const group = {};
153
+ // Support Legacy Sections
154
+ if (schema.sections) {
155
+ schema.sections.forEach(section => {
156
+ this.processFields(section.fields, group, model);
157
+ });
158
+ }
159
+ // Support New Recursive Fields
160
+ if (schema.fields) {
161
+ this.processRecursiveFields(schema.fields, group, model);
162
+ }
163
+ return this.fb.group(group);
164
+ }
165
+ processFields(fields, group, model) {
166
+ fields.forEach(field => {
167
+ this.addFieldToGroup(field, group, model);
168
+ });
169
+ }
170
+ processRecursiveFields(nodes, group, model) {
171
+ nodes.forEach(node => {
172
+ if ('children' in node && node.children) {
173
+ this.processRecursiveFields(node.children, group, model);
74
174
  }
75
- return this.type();
76
- }, ...(ngDevMode ? [{ debugName: "inputType" }] : []));
175
+ else {
176
+ // It's a field
177
+ this.addFieldToGroup(node, group, model);
178
+ }
179
+ });
180
+ }
181
+ addFieldToGroup(field, group, model) {
182
+ // Handle name/key alias
183
+ const fieldName = field.name || field.key;
184
+ if (!fieldName)
185
+ return; // Skip if no name
186
+ const validators = field.validators || [];
187
+ // Handle required shortcut
188
+ if (field.required || field.props?.['required']) {
189
+ validators.push(Validators.required);
190
+ }
191
+ const initialValue = model[fieldName] !== undefined ? model[fieldName] : (field.defaultValue !== undefined ? field.defaultValue : null);
192
+ const state = { value: initialValue, disabled: field.disabled };
193
+ group[fieldName] = [state, validators];
77
194
  }
195
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FormEngineService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
196
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FormEngineService, providedIn: 'root' });
197
+ };
198
+ FormEngineService = __decorate([
199
+ Injectable({
200
+ providedIn: 'root'
201
+ })
202
+ ], FormEngineService);
203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FormEngineService, decorators: [{
204
+ type: Injectable,
205
+ args: [{
206
+ providedIn: 'root'
207
+ }]
208
+ }, {
209
+ type: Injectable,
210
+ args: [{
211
+ providedIn: 'root'
212
+ }]
213
+ }] });
214
+
215
+ class AdInputComponent {
216
+ type = input('text', ...(ngDevMode ? [{ debugName: "type" }] : []));
217
+ placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
218
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
219
+ error = input(false, ...(ngDevMode ? [{ debugName: "error" }] : []));
220
+ rows = input(3, ...(ngDevMode ? [{ debugName: "rows" }] : []));
221
+ _disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : []));
78
222
  set disabled(value) { this._disabled.set(value); }
79
223
  get disabled() { return this._disabled(); }
224
+ size = input('small', ...(ngDevMode ? [{ debugName: "size" }] : []));
225
+ prefix = input(undefined, ...(ngDevMode ? [{ debugName: "prefix" }] : []));
226
+ suffix = input(undefined, ...(ngDevMode ? [{ debugName: "suffix" }] : []));
227
+ value = '';
228
+ passwordVisible = signal(false, ...(ngDevMode ? [{ debugName: "passwordVisible" }] : []));
229
+ onChange = () => { };
230
+ onTouched = () => { };
231
+ inputType = computed(() => {
232
+ if (this.type() === 'password') {
233
+ return this.passwordVisible() ? 'text' : 'password';
234
+ }
235
+ return this.type();
236
+ }, ...(ngDevMode ? [{ debugName: "inputType" }] : []));
80
237
  onInputChange(event) {
81
238
  const target = event.target;
82
239
  this.value = target.value;
@@ -100,47 +257,45 @@ class CcInputComponent {
100
257
  setDisabledState(isDisabled) {
101
258
  this._disabled.set(isDisabled);
102
259
  }
103
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
104
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: CcInputComponent, isStandalone: true, selector: "cc-input", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, prefix: { classPropertyName: "prefix", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null }, suffix: { classPropertyName: "suffix", publicName: "suffix", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
260
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
261
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdInputComponent, isStandalone: true, selector: "ad-input", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, prefix: { classPropertyName: "prefix", publicName: "prefix", isSignal: true, isRequired: false, transformFunction: null }, suffix: { classPropertyName: "suffix", publicName: "suffix", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
105
262
  {
106
263
  provide: NG_VALUE_ACCESSOR,
107
- useExisting: forwardRef(() => CcInputComponent),
264
+ useExisting: forwardRef(() => AdInputComponent),
108
265
  multi: true
109
266
  }
110
- ], ngImport: i0, template: "@if (label()) {\r\n<label class=\"input-label\">{{ label() }}</label>\r\n}\r\n\r\n<nz-input-group [class.has-error]=\"$any(error())\" [nzPrefix]=\"prefixTemplate\" [nzSuffix]=\"suffixTemplate\">\r\n <input nz-input [type]=\"inputType()\" [placeholder]=\"$any(placeholder())\" [disabled]=\"disabled\" [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onChange($event)\" (blur)=\"onTouched()\" [nzSize]=\"$any(size())\" />\r\n</nz-input-group>\r\n\r\n<ng-template #prefixTemplate>\r\n @if (prefix()) {\r\n <span nz-icon [nzType]=\"$any(prefix())\"></span>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #suffixTemplate>\r\n @if (type() === 'password') {\r\n <span nz-icon [nzType]=\"passwordVisible() ? 'eye-invisible' : 'eye'\" (click)=\"togglePasswordVisibility()\"\r\n class=\"password-toggle\"></span>\r\n }\r\n @if (type() !== 'password' && suffix()) {\r\n <span nz-icon [nzType]=\"$any(suffix())\"></span>\r\n }\r\n</ng-template>", styles: [":host{display:block;width:100%}.input-label{display:block;margin-bottom:8px;font-size:14px;color:#262626;font-weight:500}.password-toggle{cursor:pointer;color:#00000073}.password-toggle:hover{color:#000000d9}nz-input-group{width:100%}.has-error ::ng-deep .ant-input,.has-error ::ng-deep .ant-input-affix-wrapper{border-color:#ff4d4f}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NzInputModule }, { kind: "directive", type: i2$1.NzInputDirective, selector: "input[nz-input],textarea[nz-input]", inputs: ["nzVariant", "nzSize", "nzStepperless", "nzStatus", "disabled", "readonly"], exportAs: ["nzInput"] }, { kind: "component", type: i2$1.NzInputGroupComponent, selector: "nz-input-group", inputs: ["nzAddOnBeforeIcon", "nzAddOnAfterIcon", "nzPrefixIcon", "nzSuffixIcon", "nzAddOnBefore", "nzAddOnAfter", "nzPrefix", "nzStatus", "nzSuffix", "nzSize", "nzSearch"], exportAs: ["nzInputGroup"] }, { kind: "directive", type: i2$1.NzInputGroupWhitSuffixOrPrefixDirective, selector: "nz-input-group[nzSuffix], nz-input-group[nzPrefix]" }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i3$1.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }] }); }
267
+ ], ngImport: i0, template: "@if (label()) {\r\n<label class=\"block text-sm font-medium leading-6 text-slate-900 mb-2\">{{ label() }}</label>\r\n}\r\n\r\n<div class=\"flex items-center w-full rounded-md border border-slate-300 bg-white px-3 py-1.5 shadow-sm transition-all focus-within:border-cerca-primary\"\r\n [class.bg-slate-50]=\"disabled\" [class.text-slate-500]=\"disabled\" [class.cursor-not-allowed]=\"disabled\"\r\n [class.border-cerca-alert]=\"error()\" [class.text-cerca-alert-text]=\"error()\"\r\n [class.focus-within:border-cerca-alert]=\"error()\">\r\n\r\n @if (prefix()) {\r\n <span class=\"mr-2 flex items-center\" [class.text-slate-500]=\"!error()\" [class.text-cerca-alert-text]=\"error()\">\r\n <ad-icon [name]=\"prefix()!\" size=\"sm\"></ad-icon>\r\n </span>\r\n }\r\n\r\n @if (type() === 'textarea') {\r\n <textarea [rows]=\"rows()\" [placeholder]=\"placeholder()\" [disabled]=\"disabled\" [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onChange($event)\" (blur)=\"onTouched()\"\r\n class=\"block w-full border-0 p-0 text-slate-900 placeholder:text-slate-400 focus:ring-0 outline-none sm:text-sm sm:leading-6 bg-transparent disabled:cursor-not-allowed resize-none\"></textarea>\r\n } @else {\r\n <input [type]=\"inputType()\" [placeholder]=\"placeholder()\" [disabled]=\"disabled\" [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onChange($event)\" (blur)=\"onTouched()\"\r\n class=\"block w-full border-0 p-0 text-slate-900 placeholder:text-slate-400 focus:ring-0 outline-none sm:text-sm sm:leading-6 bg-transparent disabled:cursor-not-allowed\" />\r\n }\r\n\r\n @if (type() === 'password') {\r\n <button type=\"button\" (click)=\"togglePasswordVisibility()\"\r\n class=\"ml-2 text-slate-500 hover:text-slate-700 focus:outline-none cursor-pointer\">\r\n <ad-icon [name]=\"passwordVisible() ? 'eye-invisible' : 'eye'\" size=\"sm\"></ad-icon>\r\n </button>\r\n }\r\n\r\n @if (type() !== 'password' && suffix()) {\r\n <span class=\"ml-2 text-slate-500 flex items-center\">\r\n <ad-icon [name]=\"suffix()!\" size=\"sm\"></ad-icon>\r\n </span>\r\n }\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AdIconComponent, selector: "ad-icon", inputs: ["name", "size", "color"] }] });
111
268
  }
112
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcInputComponent, decorators: [{
269
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdInputComponent, decorators: [{
113
270
  type: Component,
114
- args: [{ selector: 'cc-input', standalone: true, imports: [
271
+ args: [{ selector: 'ad-input', standalone: true, imports: [
115
272
  CommonModule,
116
273
  FormsModule,
117
- NzInputModule,
118
- NzIconModule
274
+ AdIconComponent
119
275
  ], providers: [
120
276
  {
121
277
  provide: NG_VALUE_ACCESSOR,
122
- useExisting: forwardRef(() => CcInputComponent),
278
+ useExisting: forwardRef(() => AdInputComponent),
123
279
  multi: true
124
280
  }
125
- ], template: "@if (label()) {\r\n<label class=\"input-label\">{{ label() }}</label>\r\n}\r\n\r\n<nz-input-group [class.has-error]=\"$any(error())\" [nzPrefix]=\"prefixTemplate\" [nzSuffix]=\"suffixTemplate\">\r\n <input nz-input [type]=\"inputType()\" [placeholder]=\"$any(placeholder())\" [disabled]=\"disabled\" [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onChange($event)\" (blur)=\"onTouched()\" [nzSize]=\"$any(size())\" />\r\n</nz-input-group>\r\n\r\n<ng-template #prefixTemplate>\r\n @if (prefix()) {\r\n <span nz-icon [nzType]=\"$any(prefix())\"></span>\r\n }\r\n</ng-template>\r\n\r\n<ng-template #suffixTemplate>\r\n @if (type() === 'password') {\r\n <span nz-icon [nzType]=\"passwordVisible() ? 'eye-invisible' : 'eye'\" (click)=\"togglePasswordVisibility()\"\r\n class=\"password-toggle\"></span>\r\n }\r\n @if (type() !== 'password' && suffix()) {\r\n <span nz-icon [nzType]=\"$any(suffix())\"></span>\r\n }\r\n</ng-template>", styles: [":host{display:block;width:100%}.input-label{display:block;margin-bottom:8px;font-size:14px;color:#262626;font-weight:500}.password-toggle{cursor:pointer;color:#00000073}.password-toggle:hover{color:#000000d9}nz-input-group{width:100%}.has-error ::ng-deep .ant-input,.has-error ::ng-deep .ant-input-affix-wrapper{border-color:#ff4d4f}\n"] }]
126
- }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], disabled: [{
281
+ ], template: "@if (label()) {\r\n<label class=\"block text-sm font-medium leading-6 text-slate-900 mb-2\">{{ label() }}</label>\r\n}\r\n\r\n<div class=\"flex items-center w-full rounded-md border border-slate-300 bg-white px-3 py-1.5 shadow-sm transition-all focus-within:border-cerca-primary\"\r\n [class.bg-slate-50]=\"disabled\" [class.text-slate-500]=\"disabled\" [class.cursor-not-allowed]=\"disabled\"\r\n [class.border-cerca-alert]=\"error()\" [class.text-cerca-alert-text]=\"error()\"\r\n [class.focus-within:border-cerca-alert]=\"error()\">\r\n\r\n @if (prefix()) {\r\n <span class=\"mr-2 flex items-center\" [class.text-slate-500]=\"!error()\" [class.text-cerca-alert-text]=\"error()\">\r\n <ad-icon [name]=\"prefix()!\" size=\"sm\"></ad-icon>\r\n </span>\r\n }\r\n\r\n @if (type() === 'textarea') {\r\n <textarea [rows]=\"rows()\" [placeholder]=\"placeholder()\" [disabled]=\"disabled\" [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onChange($event)\" (blur)=\"onTouched()\"\r\n class=\"block w-full border-0 p-0 text-slate-900 placeholder:text-slate-400 focus:ring-0 outline-none sm:text-sm sm:leading-6 bg-transparent disabled:cursor-not-allowed resize-none\"></textarea>\r\n } @else {\r\n <input [type]=\"inputType()\" [placeholder]=\"placeholder()\" [disabled]=\"disabled\" [(ngModel)]=\"value\"\r\n (ngModelChange)=\"onChange($event)\" (blur)=\"onTouched()\"\r\n class=\"block w-full border-0 p-0 text-slate-900 placeholder:text-slate-400 focus:ring-0 outline-none sm:text-sm sm:leading-6 bg-transparent disabled:cursor-not-allowed\" />\r\n }\r\n\r\n @if (type() === 'password') {\r\n <button type=\"button\" (click)=\"togglePasswordVisibility()\"\r\n class=\"ml-2 text-slate-500 hover:text-slate-700 focus:outline-none cursor-pointer\">\r\n <ad-icon [name]=\"passwordVisible() ? 'eye-invisible' : 'eye'\" size=\"sm\"></ad-icon>\r\n </button>\r\n }\r\n\r\n @if (type() !== 'password' && suffix()) {\r\n <span class=\"ml-2 text-slate-500 flex items-center\">\r\n <ad-icon [name]=\"suffix()!\" size=\"sm\"></ad-icon>\r\n </span>\r\n }\r\n</div>" }]
282
+ }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], disabled: [{
127
283
  type: Input
128
284
  }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], prefix: [{ type: i0.Input, args: [{ isSignal: true, alias: "prefix", required: false }] }], suffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "suffix", required: false }] }] } });
129
285
 
130
- class CcSelectComponent {
131
- constructor() {
132
- this.options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
133
- this.placeholder = input('Seleccionar opción', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
134
- this.label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
135
- this.size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : []));
136
- this.allowClear = input(true, ...(ngDevMode ? [{ debugName: "allowClear" }] : []));
137
- this.showSearch = input(false, ...(ngDevMode ? [{ debugName: "showSearch" }] : []));
138
- this._disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : []));
139
- this.onChange = () => { };
140
- this.onTouched = () => { };
141
- }
286
+ class AdSelectComponent {
287
+ options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
288
+ placeholder = input('Seleccionar opción', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
289
+ label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
290
+ size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : []));
291
+ allowClear = input(true, ...(ngDevMode ? [{ debugName: "allowClear" }] : []));
292
+ showSearch = input(false, ...(ngDevMode ? [{ debugName: "showSearch" }] : []));
293
+ _disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : []));
142
294
  set disabled(value) { this._disabled.set(value); }
143
295
  get disabled() { return this._disabled(); }
296
+ value;
297
+ onChange = () => { };
298
+ onTouched = () => { };
144
299
  onValueChange(value) {
145
300
  this.value = value;
146
301
  this.onChange(value);
@@ -158,153 +313,1522 @@ class CcSelectComponent {
158
313
  setDisabledState(isDisabled) {
159
314
  this._disabled.set(isDisabled);
160
315
  }
161
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
162
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.4", type: CcSelectComponent, isStandalone: true, selector: "cc-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, allowClear: { classPropertyName: "allowClear", publicName: "allowClear", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null } }, providers: [
316
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
317
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdSelectComponent, isStandalone: true, selector: "ad-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, allowClear: { classPropertyName: "allowClear", publicName: "allowClear", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null } }, providers: [
163
318
  {
164
319
  provide: NG_VALUE_ACCESSOR,
165
- useExisting: forwardRef(() => CcSelectComponent),
320
+ useExisting: forwardRef(() => AdSelectComponent),
166
321
  multi: true
167
322
  }
168
- ], ngImport: i0, template: "<div class=\"cc-select-wrapper\">\r\n <nz-select class=\"cerca-select\" [nzSize]=\"$any(size())\" [nzPlaceHolder]=\"$any(placeholder())\"\r\n [nzDisabled]=\"disabled\" [nzAllowClear]=\"$any(allowClear())\" [nzShowSearch]=\"$any(showSearch())\"\r\n [(ngModel)]=\"value\" (ngModelChange)=\"onValueChange($event)\">\r\n <nz-option *ngFor=\"let option of options()\" [nzValue]=\"option.value\" [nzLabel]=\"option.label\">\r\n </nz-option>\r\n </nz-select>\r\n</div>", styles: [".cc-select-wrapper{width:100%}:host ::ng-deep .cerca-select{width:100%}:host ::ng-deep .cerca-select .ant-select-selector{min-height:44px!important;border-radius:var(--radius-md)!important;font-family:var(--font-family-base)!important;transition:all .2s cubic-bezier(.4,0,.2,1)!important}:host ::ng-deep .cerca-select .ant-select-selector:focus,:host ::ng-deep .cerca-select .ant-select-selector:focus-within{box-shadow:0 0 0 3px var(--color-focus-ring)!important;border-color:var(--color-brand)!important}:host ::ng-deep .cerca-select:hover .ant-select-selector{border-color:var(--color-brand)!important}:host ::ng-deep .cerca-select.ant-select-disabled .ant-select-selector{background-color:var(--color-bg-secondary)!important;cursor:not-allowed!important;opacity:.7!important}:host ::ng-deep .ant-select-dropdown{border-radius:var(--radius-md)!important;box-shadow:var(--shadow-lg)!important}:host ::ng-deep .ant-select-dropdown .ant-select-item{min-height:40px!important;padding:var(--space-2) var(--space-3)!important;transition:background-color .15s ease!important}:host ::ng-deep .ant-select-dropdown .ant-select-item:hover{background-color:var(--color-bg-hover)!important}:host ::ng-deep .ant-select-dropdown .ant-select-item.ant-select-item-option-selected{background-color:var(--color-brand-subtle)!important;color:var(--color-brand)!important;font-weight:var(--font-weight-medium)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: NzSelectComponent, selector: "nz-select", inputs: ["nzId", "nzSize", "nzStatus", "nzVariant", "nzOptionHeightPx", "nzOptionOverflowSize", "nzDropdownClassName", "nzDropdownMatchSelectWidth", "nzDropdownStyle", "nzNotFoundContent", "nzPlaceHolder", "nzPlacement", "nzMaxTagCount", "nzDropdownRender", "nzCustomTemplate", "nzPrefix", "nzSuffixIcon", "nzClearIcon", "nzRemoveIcon", "nzMenuItemSelectedIcon", "nzTokenSeparators", "nzMaxTagPlaceholder", "nzMaxMultipleCount", "nzMode", "nzFilterOption", "compareWith", "nzAllowClear", "nzShowSearch", "nzLoading", "nzAutoFocus", "nzAutoClearSearchValue", "nzServerSearch", "nzDisabled", "nzOpen", "nzSelectOnTab", "nzBackdrop", "nzOptions", "nzShowArrow"], outputs: ["nzOnSearch", "nzScrollToBottom", "nzOpenChange", "nzBlur", "nzFocus", "nzOnClear"], exportAs: ["nzSelect"] }, { kind: "component", type: NzOptionComponent, selector: "nz-option", inputs: ["nzTitle", "nzLabel", "nzValue", "nzKey", "nzDisabled", "nzHide", "nzCustomContent"], exportAs: ["nzOption"] }] }); }
323
+ ], ngImport: i0, template: "<div class=\"w-full\">\r\n @if (label()) {\r\n <label class=\"block text-sm font-medium leading-6 text-slate-900 mb-2\">{{ label() }}</label>\r\n }\r\n <div class=\"relative\">\r\n <select [disabled]=\"disabled\" [(ngModel)]=\"value\" (ngModelChange)=\"onValueChange($event)\" (blur)=\"onTouched()\"\r\n class=\"block w-full rounded-md border-0 py-1.5 pl-3 pr-10 text-slate-900 shadow-sm ring-1 ring-inset ring-slate-300 focus:ring-2 focus:ring-inset focus:ring-sky-600 sm:text-sm sm:leading-6 bg-white disabled:bg-slate-50 disabled:text-slate-500 disabled:cursor-not-allowed\">\r\n @if (placeholder()) {\r\n <option [ngValue]=\"null\" disabled selected>{{ placeholder() }}</option>\r\n }\r\n @if (allowClear()) {\r\n <option [ngValue]=\"null\">-- Seleccionar --</option>\r\n }\r\n @for (option of options(); track option.value) {\r\n <option [ngValue]=\"option.value\">{{ option.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
169
324
  }
170
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcSelectComponent, decorators: [{
325
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdSelectComponent, decorators: [{
171
326
  type: Component,
172
- args: [{ selector: 'cc-select', standalone: true, imports: [CommonModule, FormsModule, NzSelectComponent, NzOptionComponent], providers: [
327
+ args: [{ selector: 'ad-select', standalone: true, imports: [CommonModule, FormsModule], providers: [
173
328
  {
174
329
  provide: NG_VALUE_ACCESSOR,
175
- useExisting: forwardRef(() => CcSelectComponent),
330
+ useExisting: forwardRef(() => AdSelectComponent),
176
331
  multi: true
177
332
  }
178
- ], template: "<div class=\"cc-select-wrapper\">\r\n <nz-select class=\"cerca-select\" [nzSize]=\"$any(size())\" [nzPlaceHolder]=\"$any(placeholder())\"\r\n [nzDisabled]=\"disabled\" [nzAllowClear]=\"$any(allowClear())\" [nzShowSearch]=\"$any(showSearch())\"\r\n [(ngModel)]=\"value\" (ngModelChange)=\"onValueChange($event)\">\r\n <nz-option *ngFor=\"let option of options()\" [nzValue]=\"option.value\" [nzLabel]=\"option.label\">\r\n </nz-option>\r\n </nz-select>\r\n</div>", styles: [".cc-select-wrapper{width:100%}:host ::ng-deep .cerca-select{width:100%}:host ::ng-deep .cerca-select .ant-select-selector{min-height:44px!important;border-radius:var(--radius-md)!important;font-family:var(--font-family-base)!important;transition:all .2s cubic-bezier(.4,0,.2,1)!important}:host ::ng-deep .cerca-select .ant-select-selector:focus,:host ::ng-deep .cerca-select .ant-select-selector:focus-within{box-shadow:0 0 0 3px var(--color-focus-ring)!important;border-color:var(--color-brand)!important}:host ::ng-deep .cerca-select:hover .ant-select-selector{border-color:var(--color-brand)!important}:host ::ng-deep .cerca-select.ant-select-disabled .ant-select-selector{background-color:var(--color-bg-secondary)!important;cursor:not-allowed!important;opacity:.7!important}:host ::ng-deep .ant-select-dropdown{border-radius:var(--radius-md)!important;box-shadow:var(--shadow-lg)!important}:host ::ng-deep .ant-select-dropdown .ant-select-item{min-height:40px!important;padding:var(--space-2) var(--space-3)!important;transition:background-color .15s ease!important}:host ::ng-deep .ant-select-dropdown .ant-select-item:hover{background-color:var(--color-bg-hover)!important}:host ::ng-deep .ant-select-dropdown .ant-select-item.ant-select-item-option-selected{background-color:var(--color-brand-subtle)!important;color:var(--color-brand)!important;font-weight:var(--font-weight-medium)!important}\n"] }]
333
+ ], template: "<div class=\"w-full\">\r\n @if (label()) {\r\n <label class=\"block text-sm font-medium leading-6 text-slate-900 mb-2\">{{ label() }}</label>\r\n }\r\n <div class=\"relative\">\r\n <select [disabled]=\"disabled\" [(ngModel)]=\"value\" (ngModelChange)=\"onValueChange($event)\" (blur)=\"onTouched()\"\r\n class=\"block w-full rounded-md border-0 py-1.5 pl-3 pr-10 text-slate-900 shadow-sm ring-1 ring-inset ring-slate-300 focus:ring-2 focus:ring-inset focus:ring-sky-600 sm:text-sm sm:leading-6 bg-white disabled:bg-slate-50 disabled:text-slate-500 disabled:cursor-not-allowed\">\r\n @if (placeholder()) {\r\n <option [ngValue]=\"null\" disabled selected>{{ placeholder() }}</option>\r\n }\r\n @if (allowClear()) {\r\n <option [ngValue]=\"null\">-- Seleccionar --</option>\r\n }\r\n @for (option of options(); track option.value) {\r\n <option [ngValue]=\"option.value\">{{ option.label }}</option>\r\n }\r\n </select>\r\n </div>\r\n</div>" }]
179
334
  }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], allowClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowClear", required: false }] }], showSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSearch", required: false }] }], disabled: [{
180
335
  type: Input
181
336
  }] } });
182
337
 
183
- class CcBadgeComponent {
184
- constructor() {
185
- this.variant = 'neutral';
186
- this.type = 'subtle';
338
+ class AdSwitchComponent {
339
+ options = input([
340
+ { label: 'Inactivo', value: false },
341
+ { label: 'Activo', value: true }
342
+ ], ...(ngDevMode ? [{ debugName: "options" }] : []));
343
+ _disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : []));
344
+ set disabled(value) { this._disabled.set(value); }
345
+ get disabled() { return this._disabled(); }
346
+ value = false;
347
+ onChange = () => { };
348
+ onTouched = () => { };
349
+ /**
350
+ * Get the current label based on the switch value
351
+ */
352
+ get currentLabel() {
353
+ const option = this.options().find(opt => opt.value === this.value);
354
+ return option?.label || '';
355
+ }
356
+ toggle() {
357
+ if (this.disabled)
358
+ return;
359
+ this.onValueChange(!this.value);
360
+ }
361
+ onValueChange(value) {
362
+ this.value = value;
363
+ this.onChange(value);
364
+ this.onTouched();
365
+ }
366
+ writeValue(value) {
367
+ this.value = value ?? false;
187
368
  }
188
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
189
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcBadgeComponent, isStandalone: true, selector: "cc-badge", inputs: { variant: "variant", type: "type" }, ngImport: i0, template: "<span class=\"cc-badge\" [ngClass]=\"[variant, type]\">\r\n <ng-content></ng-content>\r\n</span>", styles: [".cc-badge{display:inline-flex;align-items:center;justify-content:center;padding:var(--badge-padding-v) var(--badge-padding-h);border-radius:var(--badge-radius);font-size:var(--badge-font-size);font-weight:var(--badge-font-weight);line-height:1;white-space:nowrap;border:1px solid transparent}.cc-badge.success.filled{background-color:var(--color-success-500);color:#fff}.cc-badge.success.subtle{background-color:var(--badge-success-bg);color:var(--badge-success-text);border-color:var(--badge-success-border)}.cc-badge.success.outline{background-color:transparent;color:var(--badge-success-text);border-color:var(--badge-success-border)}.cc-badge.warning.filled{background-color:var(--color-warning-500);color:#fff}.cc-badge.warning.subtle{background-color:var(--badge-warning-bg);color:var(--badge-warning-text);border-color:var(--badge-warning-border)}.cc-badge.warning.outline{background-color:transparent;color:var(--badge-warning-text);border-color:var(--badge-warning-border)}.cc-badge.error.filled{background-color:var(--color-error-500);color:#fff}.cc-badge.error.subtle{background-color:var(--badge-error-bg);color:var(--badge-error-text);border-color:var(--badge-error-border)}.cc-badge.error.outline{background-color:transparent;color:var(--badge-error-text);border-color:var(--badge-error-border)}.cc-badge.info.filled{background-color:var(--color-info-500);color:#fff}.cc-badge.info.subtle{background-color:var(--badge-info-bg);color:var(--badge-info-text);border-color:var(--badge-info-border)}.cc-badge.info.outline{background-color:transparent;color:var(--badge-info-text);border-color:var(--badge-info-border)}.cc-badge.neutral.filled{background-color:var(--color-text-primary);color:var(--color-bg-primary)}.cc-badge.neutral.subtle{background-color:var(--badge-neutral-bg);color:var(--badge-neutral-text);border-color:var(--badge-neutral-border)}.cc-badge.neutral.outline{background-color:transparent;color:var(--badge-neutral-text);border-color:var(--badge-neutral-border)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
369
+ registerOnChange(fn) {
370
+ this.onChange = fn;
371
+ }
372
+ registerOnTouched(fn) {
373
+ this.onTouched = fn;
374
+ }
375
+ setDisabledState(isDisabled) {
376
+ this._disabled.set(isDisabled);
377
+ }
378
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdSwitchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
379
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdSwitchComponent, isStandalone: true, selector: "ad-switch", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null } }, providers: [
380
+ {
381
+ provide: NG_VALUE_ACCESSOR,
382
+ useExisting: forwardRef(() => AdSwitchComponent),
383
+ multi: true
384
+ }
385
+ ], ngImport: i0, template: "<div class=\"ad-switch-container\">\r\n <div class=\"flex items-center gap-3\">\r\n <button type=\"button\"\r\n class=\"relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-sky-600 focus:ring-offset-2\"\r\n [class.bg-sky-600]=\"value\" [class.bg-slate-200]=\"!value\" [class.opacity-50]=\"disabled\"\r\n [class.cursor-not-allowed]=\"disabled\" (click)=\"toggle()\" [attr.aria-checked]=\"value\" role=\"switch\">\r\n\r\n <span class=\"sr-only\">{{ currentLabel }}</span>\r\n\r\n <span aria-hidden=\"true\"\r\n class=\"pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out\"\r\n [class.translate-x-5]=\"value\" [class.translate-x-0]=\"!value\">\r\n </span>\r\n </button>\r\n\r\n @if (currentLabel) {\r\n <span class=\"text-sm font-medium text-slate-700 dark:text-slate-200\" [class.opacity-50]=\"disabled\">{{\r\n currentLabel }}</span>\r\n }\r\n </div>\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }] });
190
386
  }
191
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcBadgeComponent, decorators: [{
387
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdSwitchComponent, decorators: [{
192
388
  type: Component,
193
- args: [{ selector: 'cc-badge', standalone: true, imports: [CommonModule], template: "<span class=\"cc-badge\" [ngClass]=\"[variant, type]\">\r\n <ng-content></ng-content>\r\n</span>", styles: [".cc-badge{display:inline-flex;align-items:center;justify-content:center;padding:var(--badge-padding-v) var(--badge-padding-h);border-radius:var(--badge-radius);font-size:var(--badge-font-size);font-weight:var(--badge-font-weight);line-height:1;white-space:nowrap;border:1px solid transparent}.cc-badge.success.filled{background-color:var(--color-success-500);color:#fff}.cc-badge.success.subtle{background-color:var(--badge-success-bg);color:var(--badge-success-text);border-color:var(--badge-success-border)}.cc-badge.success.outline{background-color:transparent;color:var(--badge-success-text);border-color:var(--badge-success-border)}.cc-badge.warning.filled{background-color:var(--color-warning-500);color:#fff}.cc-badge.warning.subtle{background-color:var(--badge-warning-bg);color:var(--badge-warning-text);border-color:var(--badge-warning-border)}.cc-badge.warning.outline{background-color:transparent;color:var(--badge-warning-text);border-color:var(--badge-warning-border)}.cc-badge.error.filled{background-color:var(--color-error-500);color:#fff}.cc-badge.error.subtle{background-color:var(--badge-error-bg);color:var(--badge-error-text);border-color:var(--badge-error-border)}.cc-badge.error.outline{background-color:transparent;color:var(--badge-error-text);border-color:var(--badge-error-border)}.cc-badge.info.filled{background-color:var(--color-info-500);color:#fff}.cc-badge.info.subtle{background-color:var(--badge-info-bg);color:var(--badge-info-text);border-color:var(--badge-info-border)}.cc-badge.info.outline{background-color:transparent;color:var(--badge-info-text);border-color:var(--badge-info-border)}.cc-badge.neutral.filled{background-color:var(--color-text-primary);color:var(--color-bg-primary)}.cc-badge.neutral.subtle{background-color:var(--badge-neutral-bg);color:var(--badge-neutral-text);border-color:var(--badge-neutral-border)}.cc-badge.neutral.outline{background-color:transparent;color:var(--badge-neutral-text);border-color:var(--badge-neutral-border)}\n"] }]
194
- }], propDecorators: { variant: [{
195
- type: Input
196
- }], type: [{
389
+ args: [{ selector: 'ad-switch', standalone: true, imports: [CommonModule, FormsModule], providers: [
390
+ {
391
+ provide: NG_VALUE_ACCESSOR,
392
+ useExisting: forwardRef(() => AdSwitchComponent),
393
+ multi: true
394
+ }
395
+ ], template: "<div class=\"ad-switch-container\">\r\n <div class=\"flex items-center gap-3\">\r\n <button type=\"button\"\r\n class=\"relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-sky-600 focus:ring-offset-2\"\r\n [class.bg-sky-600]=\"value\" [class.bg-slate-200]=\"!value\" [class.opacity-50]=\"disabled\"\r\n [class.cursor-not-allowed]=\"disabled\" (click)=\"toggle()\" [attr.aria-checked]=\"value\" role=\"switch\">\r\n\r\n <span class=\"sr-only\">{{ currentLabel }}</span>\r\n\r\n <span aria-hidden=\"true\"\r\n class=\"pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out\"\r\n [class.translate-x-5]=\"value\" [class.translate-x-0]=\"!value\">\r\n </span>\r\n </button>\r\n\r\n @if (currentLabel) {\r\n <span class=\"text-sm font-medium text-slate-700 dark:text-slate-200\" [class.opacity-50]=\"disabled\">{{\r\n currentLabel }}</span>\r\n }\r\n </div>\r\n</div>" }]
396
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], disabled: [{
197
397
  type: Input
198
398
  }] } });
199
399
 
200
- class CcLabelComponent {
201
- constructor() {
202
- this.text = '';
203
- this.for = '';
204
- this.required = false;
205
- this.error = false;
400
+ class DynamicFieldComponent {
401
+ field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
402
+ form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
403
+ registry = inject(FieldRendererRegistry);
404
+ get controlName() {
405
+ return this.field().name || this.field().key || '';
406
+ }
407
+ get renderType() {
408
+ return this.field().rendererKey || this.field().type || 'input';
409
+ }
410
+ get placeholder() {
411
+ return this.field().placeholder || this.field().nzConfig?.nzProps?.placeholder || '';
412
+ }
413
+ get isRequired() {
414
+ return this.field().required || !!this.field().validators?.some(v => v.name === 'required');
415
+ }
416
+ get rows() {
417
+ return this.field().props?.['rows'] || this.field().nzConfig?.nzProps?.rows || 3;
418
+ }
419
+ getRenderer(key) {
420
+ return this.registry.get(key);
206
421
  }
207
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
208
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcLabelComponent, isStandalone: true, selector: "cc-label", inputs: { text: "text", for: "for", required: "required", error: "error" }, ngImport: i0, template: "<label [attr.for]=\"for\" class=\"cc-label\" [class.has-error]=\"error\">\r\n {{ text }}\r\n <span *ngIf=\"required\" class=\"required-indicator\" aria-hidden=\"true\">*</span>\r\n</label>", styles: [".cc-label{display:block;font-size:var(--label-font-size);font-weight:var(--label-font-weight);color:var(--label-color);margin-bottom:var(--label-margin-bottom);-webkit-user-select:none;user-select:none}.cc-label .required-indicator{color:var(--label-required-color);margin-left:var(--space-0-5)}.cc-label.has-error{color:var(--color-error-600)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
422
+ getSwitchOptions() {
423
+ const f = this.field();
424
+ const checked = f.props?.['checkedChildren'] || 'Activo';
425
+ const unchecked = f.props?.['unCheckedChildren'] || 'Inactivo';
426
+ return [{ label: unchecked, value: false }, { label: checked, value: true }];
427
+ }
428
+ hasError() {
429
+ const control = this.form().get(this.controlName);
430
+ return control?.invalid && (control?.dirty || control?.touched);
431
+ }
432
+ getError(code) {
433
+ const control = this.form().get(this.controlName);
434
+ return control?.errors?.[code];
435
+ }
436
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DynamicFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
437
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: DynamicFieldComponent, isStandalone: true, selector: "ad-dynamic-field", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
438
+ <div class="mb-4" [formGroup]="form()">
439
+ <!-- Label -->
440
+ @if (renderType !== 'checkbox' && renderType !== 'switch' && field().label) {
441
+ <label [for]="controlName" class="block text-sm font-medium leading-6 text-slate-900 dark:text-slate-200 mb-2">
442
+ {{ field().label }}
443
+ @if (isRequired) { <span class="text-cerca-rose">*</span> }
444
+ </label>
445
+ }
446
+
447
+ <!-- Control -->
448
+ <div class="relative">
449
+ @switch (renderType) {
450
+ @case ('input') {
451
+ <ad-input
452
+ [formControlName]="controlName"
453
+ [placeholder]="placeholder"
454
+ [type]="field().props?.['type'] || 'text'"
455
+ [prefix]="field().props?.['prefix']"
456
+ [suffix]="field().props?.['suffix']"
457
+ [disabled]="field().disabled || false">
458
+ </ad-input>
459
+ }
460
+ @case ('text-input') {
461
+ <ad-input
462
+ [formControlName]="controlName"
463
+ [placeholder]="placeholder"
464
+ type="text"
465
+ [prefix]="field().props?.['prefix']"
466
+ [suffix]="field().props?.['suffix']"
467
+ [disabled]="field().disabled || false">
468
+ </ad-input>
469
+ }
470
+ @case ('number-input') {
471
+ <ad-input
472
+ [formControlName]="controlName"
473
+ [placeholder]="placeholder"
474
+ type="number"
475
+ [prefix]="field().props?.['prefix']"
476
+ [suffix]="field().props?.['suffix']"
477
+ [disabled]="field().disabled || false">
478
+ </ad-input>
479
+ }
480
+ @case ('textarea') {
481
+ <ad-input
482
+ [formControlName]="controlName"
483
+ type="textarea"
484
+ [placeholder]="placeholder"
485
+ [rows]="rows"
486
+ [disabled]="field().disabled || false">
487
+ </ad-input>
488
+ }
489
+ @case ('select') {
490
+ <ad-select
491
+ [formControlName]="controlName"
492
+ [options]="field().options || []"
493
+ [placeholder]="placeholder">
494
+ </ad-select>
495
+ }
496
+ @case ('select-input') {
497
+ <ad-select
498
+ [formControlName]="controlName"
499
+ [options]="field().options || []"
500
+ [placeholder]="placeholder">
501
+ </ad-select>
502
+ }
503
+ @case ('switch') {
504
+ <ad-switch
505
+ [formControlName]="controlName"
506
+ [options]="getSwitchOptions()">
507
+ </ad-switch>
508
+ }
509
+ @case ('custom') {
510
+ @if (getRenderer(controlName); as component) {
511
+ <ng-container *ngComponentOutlet="component"></ng-container>
512
+ } @else {
513
+ <p class="text-sm text-red-500">No renderer found for {{ controlName }}</p>
514
+ }
515
+ }
516
+ @default {
517
+ <p class="text-sm text-red-500">Unsupported field type: {{ renderType }}</p>
518
+ }
519
+ }
520
+ </div>
521
+
522
+ <!-- Errors -->
523
+ @if (hasError()) {
524
+ <p class="mt-2 text-sm text-cerca-rose">
525
+ @if (getError('required')) { Campo requerido }
526
+ @if (getError('email')) { Email inválido }
527
+ @if (getError('min')) { Valor mínimo no alcanzado }
528
+ </p>
529
+ }
530
+ </div>
531
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: AdInputComponent, selector: "ad-input", inputs: ["type", "placeholder", "label", "error", "rows", "disabled", "size", "prefix", "suffix"] }, { kind: "component", type: AdSelectComponent, selector: "ad-select", inputs: ["options", "placeholder", "label", "size", "allowClear", "showSearch", "disabled"] }, { kind: "component", type: AdSwitchComponent, selector: "ad-switch", inputs: ["options", "disabled"] }] });
209
532
  }
210
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcLabelComponent, decorators: [{
533
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DynamicFieldComponent, decorators: [{
211
534
  type: Component,
212
- args: [{ selector: 'cc-label', standalone: true, imports: [CommonModule], template: "<label [attr.for]=\"for\" class=\"cc-label\" [class.has-error]=\"error\">\r\n {{ text }}\r\n <span *ngIf=\"required\" class=\"required-indicator\" aria-hidden=\"true\">*</span>\r\n</label>", styles: [".cc-label{display:block;font-size:var(--label-font-size);font-weight:var(--label-font-weight);color:var(--label-color);margin-bottom:var(--label-margin-bottom);-webkit-user-select:none;user-select:none}.cc-label .required-indicator{color:var(--label-required-color);margin-left:var(--space-0-5)}.cc-label.has-error{color:var(--color-error-600)}\n"] }]
213
- }], propDecorators: { text: [{
214
- type: Input
215
- }], for: [{
216
- type: Input
217
- }], required: [{
218
- type: Input
219
- }], error: [{
535
+ args: [{
536
+ selector: 'ad-dynamic-field',
537
+ standalone: true,
538
+ imports: [CommonModule, ReactiveFormsModule, AdInputComponent, AdSelectComponent, AdSwitchComponent],
539
+ template: `
540
+ <div class="mb-4" [formGroup]="form()">
541
+ <!-- Label -->
542
+ @if (renderType !== 'checkbox' && renderType !== 'switch' && field().label) {
543
+ <label [for]="controlName" class="block text-sm font-medium leading-6 text-slate-900 dark:text-slate-200 mb-2">
544
+ {{ field().label }}
545
+ @if (isRequired) { <span class="text-cerca-rose">*</span> }
546
+ </label>
547
+ }
548
+
549
+ <!-- Control -->
550
+ <div class="relative">
551
+ @switch (renderType) {
552
+ @case ('input') {
553
+ <ad-input
554
+ [formControlName]="controlName"
555
+ [placeholder]="placeholder"
556
+ [type]="field().props?.['type'] || 'text'"
557
+ [prefix]="field().props?.['prefix']"
558
+ [suffix]="field().props?.['suffix']"
559
+ [disabled]="field().disabled || false">
560
+ </ad-input>
561
+ }
562
+ @case ('text-input') {
563
+ <ad-input
564
+ [formControlName]="controlName"
565
+ [placeholder]="placeholder"
566
+ type="text"
567
+ [prefix]="field().props?.['prefix']"
568
+ [suffix]="field().props?.['suffix']"
569
+ [disabled]="field().disabled || false">
570
+ </ad-input>
571
+ }
572
+ @case ('number-input') {
573
+ <ad-input
574
+ [formControlName]="controlName"
575
+ [placeholder]="placeholder"
576
+ type="number"
577
+ [prefix]="field().props?.['prefix']"
578
+ [suffix]="field().props?.['suffix']"
579
+ [disabled]="field().disabled || false">
580
+ </ad-input>
581
+ }
582
+ @case ('textarea') {
583
+ <ad-input
584
+ [formControlName]="controlName"
585
+ type="textarea"
586
+ [placeholder]="placeholder"
587
+ [rows]="rows"
588
+ [disabled]="field().disabled || false">
589
+ </ad-input>
590
+ }
591
+ @case ('select') {
592
+ <ad-select
593
+ [formControlName]="controlName"
594
+ [options]="field().options || []"
595
+ [placeholder]="placeholder">
596
+ </ad-select>
597
+ }
598
+ @case ('select-input') {
599
+ <ad-select
600
+ [formControlName]="controlName"
601
+ [options]="field().options || []"
602
+ [placeholder]="placeholder">
603
+ </ad-select>
604
+ }
605
+ @case ('switch') {
606
+ <ad-switch
607
+ [formControlName]="controlName"
608
+ [options]="getSwitchOptions()">
609
+ </ad-switch>
610
+ }
611
+ @case ('custom') {
612
+ @if (getRenderer(controlName); as component) {
613
+ <ng-container *ngComponentOutlet="component"></ng-container>
614
+ } @else {
615
+ <p class="text-sm text-red-500">No renderer found for {{ controlName }}</p>
616
+ }
617
+ }
618
+ @default {
619
+ <p class="text-sm text-red-500">Unsupported field type: {{ renderType }}</p>
620
+ }
621
+ }
622
+ </div>
623
+
624
+ <!-- Errors -->
625
+ @if (hasError()) {
626
+ <p class="mt-2 text-sm text-cerca-rose">
627
+ @if (getError('required')) { Campo requerido }
628
+ @if (getError('email')) { Email inválido }
629
+ @if (getError('min')) { Valor mínimo no alcanzado }
630
+ </p>
631
+ }
632
+ </div>
633
+ `
634
+ }]
635
+ }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: true }] }] } });
636
+
637
+ class DynamicLayoutComponent {
638
+ field = input.required(...(ngDevMode ? [{ debugName: "field" }] : []));
639
+ form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
640
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DynamicLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
641
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.4", type: DynamicLayoutComponent, isStandalone: true, selector: "ad-dynamic-layout", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
642
+ <div [class]="field().gridClass || 'col-span-12'">
643
+ <ad-dynamic-field [field]="field()" [form]="form()"></ad-dynamic-field>
644
+ </div>
645
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: DynamicFieldComponent, selector: "ad-dynamic-field", inputs: ["field", "form"] }] });
646
+ }
647
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: DynamicLayoutComponent, decorators: [{
648
+ type: Component,
649
+ args: [{
650
+ selector: 'ad-dynamic-layout',
651
+ standalone: true,
652
+ imports: [
653
+ CommonModule,
654
+ ReactiveFormsModule,
655
+ DynamicFieldComponent
656
+ ],
657
+ template: `
658
+ <div [class]="field().gridClass || 'col-span-12'">
659
+ <ad-dynamic-field [field]="field()" [form]="form()"></ad-dynamic-field>
660
+ </div>
661
+ `
662
+ }]
663
+ }], propDecorators: { field: [{ type: i0.Input, args: [{ isSignal: true, alias: "field", required: true }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: true }] }] } });
664
+
665
+ class AdLoadingComponent {
666
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
667
+ color = input('text-sky-600', ...(ngDevMode ? [{ debugName: "color" }] : []));
668
+ computedClasses = computed(() => {
669
+ let sizeClass = 'h-5 w-5';
670
+ switch (this.size()) {
671
+ case 'sm':
672
+ sizeClass = 'h-4 w-4';
673
+ break;
674
+ case 'lg':
675
+ sizeClass = 'h-8 w-8';
676
+ break;
677
+ }
678
+ return `animate-spin ${sizeClass} ${this.color()}`;
679
+ }, ...(ngDevMode ? [{ debugName: "computedClasses" }] : []));
680
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdLoadingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
681
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.4", type: AdLoadingComponent, isStandalone: true, selector: "ad-loading", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<svg [class]=\"computedClasses()\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\r\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\r\n <path class=\"opacity-75\" fill=\"currentColor\"\r\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\">\r\n </path>\r\n</svg>", dependencies: [{ kind: "ngmodule", type: CommonModule }] });
682
+ }
683
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdLoadingComponent, decorators: [{
684
+ type: Component,
685
+ args: [{ selector: 'ad-loading', standalone: true, imports: [CommonModule], template: "<svg [class]=\"computedClasses()\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\r\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\r\n <path class=\"opacity-75\" fill=\"currentColor\"\r\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\">\r\n </path>\r\n</svg>" }]
686
+ }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }] } });
687
+
688
+ class AdButtonComponent {
689
+ variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : []));
690
+ type = input('button', ...(ngDevMode ? [{ debugName: "type" }] : []));
691
+ _disabled = signal(false, ...(ngDevMode ? [{ debugName: "_disabled" }] : []));
692
+ set disabled(value) { this._disabled.set(value); }
693
+ get disabled() { return this._disabled(); }
694
+ loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
695
+ icon = input(undefined, ...(ngDevMode ? [{ debugName: "icon" }] : []));
696
+ size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : []));
697
+ block = input(false, ...(ngDevMode ? [{ debugName: "block" }] : []));
698
+ computedClasses = computed(() => {
699
+ const baseClasses = 'ad-btn inline-flex items-center justify-center gap-2 rounded-lg font-medium transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed';
700
+ const displayClass = this.block() ? 'w-full flex' : 'inline-flex';
701
+ const sizeClasses = {
702
+ 'small': 'px-3 py-1.5 text-xs',
703
+ 'default': 'px-4 py-2 text-sm',
704
+ 'large': 'px-6 py-3 text-base'
705
+ };
706
+ const variantClasses = {
707
+ 'primary': 'bg-cerca-primary text-white hover:bg-cerca-primary-hover active:bg-cerca-primary-active focus-visible:ring-cerca-primary shadow-sm',
708
+ 'secondary': 'bg-white text-cerca-secondary border border-slate-300 hover:bg-slate-50 focus-visible:ring-slate-500 shadow-sm',
709
+ 'ghost': 'text-cerca-secondary hover:bg-slate-100 focus-visible:ring-slate-500',
710
+ 'outline': 'border-2 border-cerca-primary text-cerca-primary hover:bg-cerca-primary-light focus-visible:ring-cerca-primary',
711
+ 'danger': 'bg-cerca-alert text-white hover:bg-red-600 focus-visible:ring-cerca-alert shadow-sm'
712
+ };
713
+ return `${baseClasses.replace('inline-flex', '')} ${displayClass} ${sizeClasses[this.size()]} ${variantClasses[this.variant()] || variantClasses['primary']}`;
714
+ }, ...(ngDevMode ? [{ debugName: "computedClasses" }] : []));
715
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
716
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdButtonComponent, isStandalone: true, selector: "ad-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: false, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, block: { classPropertyName: "block", publicName: "block", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<button [class]=\"computedClasses()\" [disabled]=\"disabled\" [type]=\"type()\">\r\n @if (loading()) {\r\n <ad-loading size=\"sm\" color=\"text-current\"></ad-loading>\r\n }\r\n @if (icon() && !loading()) {\r\n <ad-icon [name]=\"icon()!\" [size]=\"size() === 'small' ? 'sm' : size() === 'large' ? 'lg' : 'md'\"></ad-icon>\r\n }\r\n <ng-content></ng-content>\r\n</button>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AdIconComponent, selector: "ad-icon", inputs: ["name", "size", "color"] }, { kind: "component", type: AdLoadingComponent, selector: "ad-loading", inputs: ["size", "color"] }] });
717
+ }
718
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdButtonComponent, decorators: [{
719
+ type: Component,
720
+ args: [{ selector: 'ad-button', standalone: true, imports: [CommonModule, AdIconComponent, AdLoadingComponent], template: "<button [class]=\"computedClasses()\" [disabled]=\"disabled\" [type]=\"type()\">\r\n @if (loading()) {\r\n <ad-loading size=\"sm\" color=\"text-current\"></ad-loading>\r\n }\r\n @if (icon() && !loading()) {\r\n <ad-icon [name]=\"icon()!\" [size]=\"size() === 'small' ? 'sm' : size() === 'large' ? 'lg' : 'md'\"></ad-icon>\r\n }\r\n <ng-content></ng-content>\r\n</button>" }]
721
+ }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], disabled: [{
220
722
  type: Input
221
- }] } });
723
+ }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], block: [{ type: i0.Input, args: [{ isSignal: true, alias: "block", required: false }] }] } });
222
724
 
223
- class CcIconComponent {
224
- constructor() {
225
- this.name = '';
226
- this.size = 'md';
227
- this.color = 'currentColor';
725
+ class AdFormSectionComponent {
726
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
727
+ title = computed(() => this.resource().title, ...(ngDevMode ? [{ debugName: "title" }] : []));
728
+ cols = computed(() => this.resource().cols ?? 12, ...(ngDevMode ? [{ debugName: "cols" }] : []));
729
+ loading = computed(() => this.resource().loading ?? false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
730
+ // Map for safe Tailwind class detection
731
+ colSpanMap = {
732
+ 1: 'md:col-span-1',
733
+ 2: 'md:col-span-2',
734
+ 3: 'md:col-span-3',
735
+ 4: 'md:col-span-4',
736
+ 5: 'md:col-span-5',
737
+ 6: 'md:col-span-6',
738
+ 7: 'md:col-span-7',
739
+ 8: 'md:col-span-8',
740
+ 9: 'md:col-span-9',
741
+ 10: 'md:col-span-10',
742
+ 11: 'md:col-span-11',
743
+ 12: 'md:col-span-12'
744
+ };
745
+ hostClasses = computed(() => {
746
+ const colClass = this.colSpanMap[this.cols()] || 'md:col-span-12';
747
+ return `block ${colClass}`;
748
+ }, ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
749
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdFormSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
750
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdFormSectionComponent, isStandalone: true, selector: "ad-form-section", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
751
+ <div class="bg-white rounded-lg shadow-sm border border-stone-200 dark:border-cerca-primary dark:bg-cerca-navy h-full flex flex-col transition-colors duration-300">
752
+
753
+ @if (title()) {
754
+ <div class="px-6 py-4 border-b border-stone-100 dark:border-cerca-primary-hover">
755
+ <h3 class="text-lg font-semibold text-stone-800 dark:text-white">{{ title() }}</h3>
756
+ </div>
757
+ }
758
+
759
+ <div class="p-6 flex-1 space-y-4">
760
+ @if (loading()) {
761
+ <div class="animate-pulse space-y-4">
762
+ <div class="h-4 bg-stone-200 dark:bg-stone-700 rounded w-3/4"></div>
763
+ <div class="h-10 bg-stone-100 dark:bg-stone-800 rounded"></div>
764
+ <div class="h-4 bg-stone-200 dark:bg-stone-700 rounded w-1/2"></div>
765
+ <div class="h-24 bg-stone-100 dark:bg-stone-800 rounded"></div>
766
+ </div>
767
+ } @else {
768
+ <ng-content></ng-content>
769
+ }
770
+ </div>
771
+ </div>
772
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
773
+ }
774
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdFormSectionComponent, decorators: [{
775
+ type: Component,
776
+ args: [{
777
+ selector: 'ad-form-section',
778
+ standalone: true,
779
+ imports: [CommonModule],
780
+ template: `
781
+ <div class="bg-white rounded-lg shadow-sm border border-stone-200 dark:border-cerca-primary dark:bg-cerca-navy h-full flex flex-col transition-colors duration-300">
782
+
783
+ @if (title()) {
784
+ <div class="px-6 py-4 border-b border-stone-100 dark:border-cerca-primary-hover">
785
+ <h3 class="text-lg font-semibold text-stone-800 dark:text-white">{{ title() }}</h3>
786
+ </div>
787
+ }
788
+
789
+ <div class="p-6 flex-1 space-y-4">
790
+ @if (loading()) {
791
+ <div class="animate-pulse space-y-4">
792
+ <div class="h-4 bg-stone-200 dark:bg-stone-700 rounded w-3/4"></div>
793
+ <div class="h-10 bg-stone-100 dark:bg-stone-800 rounded"></div>
794
+ <div class="h-4 bg-stone-200 dark:bg-stone-700 rounded w-1/2"></div>
795
+ <div class="h-24 bg-stone-100 dark:bg-stone-800 rounded"></div>
796
+ </div>
797
+ } @else {
798
+ <ng-content></ng-content>
799
+ }
800
+ </div>
801
+ </div>
802
+ `,
803
+ encapsulation: ViewEncapsulation.None,
804
+ host: {
805
+ '[class]': 'hostClasses()'
806
+ }
807
+ }]
808
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }] } });
809
+
810
+ class AdFormRendererComponent {
811
+ // Maps for safe Tailwind class detection (JIT compatible)
812
+ mdColSpanMap = {
813
+ 1: 'md:col-span-1',
814
+ 2: 'md:col-span-2',
815
+ 3: 'md:col-span-3',
816
+ 4: 'md:col-span-4',
817
+ 5: 'md:col-span-5',
818
+ 6: 'md:col-span-6',
819
+ 7: 'md:col-span-7',
820
+ 8: 'md:col-span-8',
821
+ 9: 'md:col-span-9',
822
+ 10: 'md:col-span-10',
823
+ 11: 'md:col-span-11',
824
+ 12: 'md:col-span-12'
825
+ };
826
+ lgColSpanMap = {
827
+ 1: 'lg:col-span-1',
828
+ 2: 'lg:col-span-2',
829
+ 3: 'lg:col-span-3',
830
+ 4: 'lg:col-span-4',
831
+ 5: 'lg:col-span-5',
832
+ 6: 'lg:col-span-6',
833
+ 7: 'lg:col-span-7',
834
+ 8: 'lg:col-span-8',
835
+ 9: 'lg:col-span-9',
836
+ 10: 'lg:col-span-10',
837
+ 11: 'lg:col-span-11',
838
+ 12: 'lg:col-span-12'
839
+ };
840
+ xlColSpanMap = {
841
+ 1: 'xl:col-span-1',
842
+ 2: 'xl:col-span-2',
843
+ 3: 'xl:col-span-3',
844
+ 4: 'xl:col-span-4',
845
+ 5: 'xl:col-span-5',
846
+ 6: 'xl:col-span-6',
847
+ 7: 'xl:col-span-7',
848
+ 8: 'xl:col-span-8',
849
+ 9: 'xl:col-span-9',
850
+ 10: 'xl:col-span-10',
851
+ 11: 'xl:col-span-11',
852
+ 12: 'xl:col-span-12'
853
+ };
854
+ getGridClass(props) {
855
+ const classes = [];
856
+ // Base Span (Mobile/Default) mapped to MD because our grid starts at MD
857
+ if (props?.span) {
858
+ classes.push(this.mdColSpanMap[props.span] || 'md:col-span-12');
859
+ }
860
+ else {
861
+ classes.push('md:col-span-12'); // Default full width
862
+ }
863
+ // LG Override
864
+ if (props?.lg) {
865
+ classes.push(this.lgColSpanMap[props.lg]);
866
+ }
867
+ // XL Override
868
+ if (props?.xl) {
869
+ classes.push(this.xlColSpanMap[props.xl]);
870
+ }
871
+ return classes.join(' ');
872
+ }
873
+ nodes = input.required(...(ngDevMode ? [{ debugName: "nodes" }] : []));
874
+ form = input.required(...(ngDevMode ? [{ debugName: "form" }] : []));
875
+ isLayout(node) {
876
+ return 'layoutType' in node && !!node.children;
877
+ }
878
+ asField(node) {
879
+ return node;
228
880
  }
229
- get iconClass() {
230
- return `icon-${this.size}`;
881
+ asLayout(node) {
882
+ return node;
231
883
  }
232
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
233
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcIconComponent, isStandalone: true, selector: "cc-icon", inputs: { name: "name", size: "size", color: "color" }, ngImport: i0, template: "<i class=\"cc-icon\" [ngClass]=\"iconClass\" [style.color]=\"color\" aria-hidden=\"true\">\r\n {{ name }}\r\n</i>", styles: [".cc-icon{display:inline-flex;align-items:center;justify-content:center;font-family:Material Symbols Outlined;font-weight:400;font-style:normal;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-smoothing:antialiased}.cc-icon.icon-xs{font-size:16px;width:16px;height:16px}.cc-icon.icon-sm{font-size:20px;width:20px;height:20px}.cc-icon.icon-md{font-size:24px;width:24px;height:24px}.cc-icon.icon-lg{font-size:32px;width:32px;height:32px}.cc-icon.icon-xl{font-size:40px;width:40px;height:40px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
884
+ trackByFn(index, item) {
885
+ return item.key || item.name || index;
886
+ }
887
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdFormRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
888
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdFormRendererComponent, isStandalone: true, selector: "ad-form-renderer", inputs: { nodes: { classPropertyName: "nodes", publicName: "nodes", isSignal: true, isRequired: true, transformFunction: null }, form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null } }, host: { styleAttribute: "display: contents" }, ngImport: i0, template: `
889
+ @for (node of nodes(); track $any(node).key || $any(node).name || $index) {
890
+
891
+ @if (isLayout(node)) {
892
+ <!-- Recursive Layout Rendering -->
893
+ @switch (node.layoutType) {
894
+
895
+ @case ('row') {
896
+ <div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-start w-full md:col-span-12">
897
+ <ad-form-renderer [nodes]="node.children || []" [form]="form()"></ad-form-renderer>
898
+ </div>
899
+ }
900
+
901
+ @case ('col') {
902
+ <!-- 'col' wraps content in a div with grid classes. -->
903
+ <div [class]="getGridClass(node.layoutProps)">
904
+ <ad-form-renderer [nodes]="node.children || []" [form]="form()"></ad-form-renderer>
905
+ </div>
906
+ }
907
+
908
+ @case ('card') {
909
+ <!-- For card, we might want to also use the grid class on the wrapper?
910
+ AdFormSection uses 'cols' input to generate wrapper class.
911
+ We should probably update AdFormSection to accept full class string or improve mapping.
912
+ But AdFormSection just uses cols Input -> md:col-span-X.
913
+ Let's keep legacy behavior for card if simple span, or enhance AdFormSection later.
914
+ Actually, card usually sits inside a 'col'. If card is direct child of row, it needs width.
915
+ Usage in schema:
916
+ row -> children: [ { layoutType: 'col', children: [ { layoutType: 'card' } ] } ]
917
+ So card is inside col (which has width). Card itself usually takes full width of parent.
918
+ Wait, AdFormSection has [cols] input. Default 12.
919
+ If card is inside a col (which is e.g. span 8), then card should be span 12 (100% of parent).
920
+ The schema in demo has card INSIDE col.
921
+ So card shouldn't need sizing props if it's 100%.
922
+ But if card is direct child of row?
923
+ Safest is to let card be 12 (100% of container).
924
+ If User put card directly in row, they might expect it to size.
925
+ But let's assume standard pattern: Row -> Col -> Card.
926
+ -->
927
+ <ad-form-section [resource]="{ title: node.layoutProps?.title, cols: 12 }">
928
+ <ad-form-renderer [nodes]="node.children || []" [form]="form()"></ad-form-renderer>
929
+ </ad-form-section>
930
+ }
931
+
932
+ @case ('stack') {
933
+ <div class="flex flex-col" [style.gap.px]="node.layoutProps?.gap || 0">
934
+ <ad-form-renderer [nodes]="node.children || []" [form]="form()"></ad-form-renderer>
935
+ </div>
936
+ }
937
+
938
+ @default {
939
+ <!-- Fallback for unknown layout: render children directly -->
940
+ <!-- Explicitly cast to unknown then LayoutSchema to access children safely in default block -->
941
+ <ad-form-renderer [nodes]="asLayout(node).children || []" [form]="form()"></ad-form-renderer>
942
+ }
943
+ }
944
+ } @else {
945
+ <!-- Leaf Node: Field -->
946
+ <!-- Fields use getGridClass to support layoutProps: { span: X } directly on the field -->
947
+ <div [class]="getGridClass(node.layoutProps)">
948
+ <ad-dynamic-layout [field]="asField(node)" [form]="form()"></ad-dynamic-layout>
949
+ </div>
950
+ }
951
+ }
952
+ `, isInline: true, dependencies: [{ kind: "component", type: i0.forwardRef(() => AdFormRendererComponent), selector: "ad-form-renderer", inputs: ["nodes", "form"] }, { kind: "ngmodule", type: i0.forwardRef(() => CommonModule) }, { kind: "ngmodule", type: i0.forwardRef(() => ReactiveFormsModule) }, { kind: "component", type: i0.forwardRef(() => DynamicLayoutComponent), selector: "ad-dynamic-layout", inputs: ["field", "form"] }, { kind: "component", type: i0.forwardRef(() => AdFormSectionComponent), selector: "ad-form-section", inputs: ["resource"] }] });
234
953
  }
235
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcIconComponent, decorators: [{
954
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdFormRendererComponent, decorators: [{
236
955
  type: Component,
237
- args: [{ selector: 'cc-icon', standalone: true, imports: [CommonModule], template: "<i class=\"cc-icon\" [ngClass]=\"iconClass\" [style.color]=\"color\" aria-hidden=\"true\">\r\n {{ name }}\r\n</i>", styles: [".cc-icon{display:inline-flex;align-items:center;justify-content:center;font-family:Material Symbols Outlined;font-weight:400;font-style:normal;letter-spacing:normal;text-transform:none;display:inline-block;white-space:nowrap;word-wrap:normal;direction:ltr;-webkit-font-smoothing:antialiased}.cc-icon.icon-xs{font-size:16px;width:16px;height:16px}.cc-icon.icon-sm{font-size:20px;width:20px;height:20px}.cc-icon.icon-md{font-size:24px;width:24px;height:24px}.cc-icon.icon-lg{font-size:32px;width:32px;height:32px}.cc-icon.icon-xl{font-size:40px;width:40px;height:40px}\n"] }]
238
- }], propDecorators: { name: [{
239
- type: Input
240
- }], size: [{
241
- type: Input
242
- }], color: [{
243
- type: Input
244
- }] } });
956
+ args: [{
957
+ selector: 'ad-form-renderer',
958
+ standalone: true,
959
+ imports: [
960
+ CommonModule,
961
+ ReactiveFormsModule,
962
+ DynamicLayoutComponent, // Renders individual fields (leaf nodes)
963
+ AdFormSectionComponent, // Renders 'card'
964
+ forwardRef(() => AdFormRendererComponent)
965
+ ],
966
+ template: `
967
+ @for (node of nodes(); track $any(node).key || $any(node).name || $index) {
968
+
969
+ @if (isLayout(node)) {
970
+ <!-- Recursive Layout Rendering -->
971
+ @switch (node.layoutType) {
972
+
973
+ @case ('row') {
974
+ <div class="grid grid-cols-1 md:grid-cols-12 gap-6 items-start w-full md:col-span-12">
975
+ <ad-form-renderer [nodes]="node.children || []" [form]="form()"></ad-form-renderer>
976
+ </div>
977
+ }
978
+
979
+ @case ('col') {
980
+ <!-- 'col' wraps content in a div with grid classes. -->
981
+ <div [class]="getGridClass(node.layoutProps)">
982
+ <ad-form-renderer [nodes]="node.children || []" [form]="form()"></ad-form-renderer>
983
+ </div>
984
+ }
985
+
986
+ @case ('card') {
987
+ <!-- For card, we might want to also use the grid class on the wrapper?
988
+ AdFormSection uses 'cols' input to generate wrapper class.
989
+ We should probably update AdFormSection to accept full class string or improve mapping.
990
+ But AdFormSection just uses cols Input -> md:col-span-X.
991
+ Let's keep legacy behavior for card if simple span, or enhance AdFormSection later.
992
+ Actually, card usually sits inside a 'col'. If card is direct child of row, it needs width.
993
+ Usage in schema:
994
+ row -> children: [ { layoutType: 'col', children: [ { layoutType: 'card' } ] } ]
995
+ So card is inside col (which has width). Card itself usually takes full width of parent.
996
+ Wait, AdFormSection has [cols] input. Default 12.
997
+ If card is inside a col (which is e.g. span 8), then card should be span 12 (100% of parent).
998
+ The schema in demo has card INSIDE col.
999
+ So card shouldn't need sizing props if it's 100%.
1000
+ But if card is direct child of row?
1001
+ Safest is to let card be 12 (100% of container).
1002
+ If User put card directly in row, they might expect it to size.
1003
+ But let's assume standard pattern: Row -> Col -> Card.
1004
+ -->
1005
+ <ad-form-section [resource]="{ title: node.layoutProps?.title, cols: 12 }">
1006
+ <ad-form-renderer [nodes]="node.children || []" [form]="form()"></ad-form-renderer>
1007
+ </ad-form-section>
1008
+ }
1009
+
1010
+ @case ('stack') {
1011
+ <div class="flex flex-col" [style.gap.px]="node.layoutProps?.gap || 0">
1012
+ <ad-form-renderer [nodes]="node.children || []" [form]="form()"></ad-form-renderer>
1013
+ </div>
1014
+ }
1015
+
1016
+ @default {
1017
+ <!-- Fallback for unknown layout: render children directly -->
1018
+ <!-- Explicitly cast to unknown then LayoutSchema to access children safely in default block -->
1019
+ <ad-form-renderer [nodes]="asLayout(node).children || []" [form]="form()"></ad-form-renderer>
1020
+ }
1021
+ }
1022
+ } @else {
1023
+ <!-- Leaf Node: Field -->
1024
+ <!-- Fields use getGridClass to support layoutProps: { span: X } directly on the field -->
1025
+ <div [class]="getGridClass(node.layoutProps)">
1026
+ <ad-dynamic-layout [field]="asField(node)" [form]="form()"></ad-dynamic-layout>
1027
+ </div>
1028
+ }
1029
+ }
1030
+ `,
1031
+ host: {
1032
+ style: 'display: contents'
1033
+ }
1034
+ }]
1035
+ }], propDecorators: { nodes: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodes", required: true }] }], form: [{ type: i0.Input, args: [{ isSignal: true, alias: "form", required: true }] }] } });
245
1036
 
246
- class CcCardComponent {
1037
+ class FormEngineComponent {
1038
+ // Inputs (Signals)
1039
+ schema = input.required(...(ngDevMode ? [{ debugName: "schema" }] : []));
1040
+ model = input({}, ...(ngDevMode ? [{ debugName: "model" }] : []));
1041
+ showCancel = input(false, ...(ngDevMode ? [{ debugName: "showCancel" }] : []));
1042
+ showSubmit = input(true, ...(ngDevMode ? [{ debugName: "showSubmit" }] : []));
1043
+ // Outputs
1044
+ formSubmit = output();
1045
+ formCancel = output();
1046
+ // Dependencies
1047
+ engineService = inject(FormEngineService);
1048
+ // State
1049
+ form = computed(() => {
1050
+ const schema = this.schema();
1051
+ const model = this.model();
1052
+ // Note: model availability in computed might be tricky if model updates later.
1053
+ // But createFormGroup usually runs once.
1054
+ // Better: create form once, then patch.
1055
+ if (!schema)
1056
+ return new FormGroup({});
1057
+ return this.engineService.createFormGroup(schema, model);
1058
+ }, ...(ngDevMode ? [{ debugName: "form" }] : []));
247
1059
  constructor() {
248
- this.title = input('', ...(ngDevMode ? [{ debugName: "title" }] : []));
249
- this.extra = input(undefined, ...(ngDevMode ? [{ debugName: "extra" }] : []));
250
- this.loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
251
- this.bordered = input(true, ...(ngDevMode ? [{ debugName: "bordered" }] : []));
252
- this.padding = input('24px', ...(ngDevMode ? [{ debugName: "padding" }] : []));
1060
+ // Effect to patch value when model changes AFTER form creation
1061
+ effect(() => {
1062
+ const currentModel = this.model();
1063
+ const currentForm = this.form();
1064
+ if (currentForm && currentModel && Object.keys(currentModel).length > 0) {
1065
+ currentForm.patchValue(currentModel);
1066
+ }
1067
+ });
253
1068
  }
254
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
255
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.4", type: CcCardComponent, isStandalone: true, selector: "cc-card", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, extra: { classPropertyName: "extra", publicName: "extra", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<nz-card [nzTitle]=\"$any(title())\" [nzExtra]=\"extra()\" [nzLoading]=\"$any(loading())\" [nzBordered]=\"$any(bordered())\">\r\n <ng-content></ng-content>\r\n</nz-card>", styles: [":host ::ng-deep .cerca-card{border-radius:var(--radius-lg)!important;box-shadow:var(--shadow-md)!important;transition:all .2s cubic-bezier(.4,0,.2,1)!important}:host ::ng-deep .cerca-card .ant-card-head{border-bottom-color:var(--color-border-subtle)!important;font-family:var(--font-family-base)!important;font-weight:var(--font-weight-semibold)!important}:host ::ng-deep .cerca-card.ant-card-hoverable:hover{box-shadow:var(--shadow-lg)!important;transform:translateY(-2px)!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: NzCardModule }, { kind: "component", type: i1$3.NzCardComponent, selector: "nz-card", inputs: ["nzBordered", "nzLoading", "nzHoverable", "nzBodyStyle", "nzCover", "nzActions", "nzType", "nzSize", "nzTitle", "nzExtra"], exportAs: ["nzCard"] }] }); }
1069
+ ngOnInit() { }
1070
+ submit() {
1071
+ const f = this.form();
1072
+ if (f.valid) {
1073
+ this.formSubmit.emit(f.value);
1074
+ }
1075
+ else {
1076
+ Object.values(f.controls).forEach(control => {
1077
+ if (control.invalid) {
1078
+ control.markAsDirty();
1079
+ control.updateValueAndValidity({ onlySelf: true });
1080
+ }
1081
+ });
1082
+ }
1083
+ }
1084
+ onCancel() {
1085
+ this.formCancel.emit();
1086
+ }
1087
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FormEngineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1088
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: FormEngineComponent, isStandalone: true, selector: "ad-form-engine", inputs: { schema: { classPropertyName: "schema", publicName: "schema", isSignal: true, isRequired: true, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: false, transformFunction: null }, showCancel: { classPropertyName: "showCancel", publicName: "showCancel", isSignal: true, isRequired: false, transformFunction: null }, showSubmit: { classPropertyName: "showSubmit", publicName: "showSubmit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { formSubmit: "formSubmit", formCancel: "formCancel" }, ngImport: i0, template: `
1089
+ @if (form()) {
1090
+ <form [formGroup]="form()" class="space-y-6" (ngSubmit)="submit()">
1091
+
1092
+ <!-- NEW: Recursive Schema Rendering -->
1093
+ @if (schema().fields) {
1094
+ <div class="grid grid-cols-1 md:grid-cols-12 gap-6 w-full">
1095
+ <ad-form-renderer [nodes]="schema().fields!" [form]="form()"></ad-form-renderer>
1096
+ </div>
1097
+ }
1098
+
1099
+ <!-- LEGACY: Sections Rendering (Fallback) -->
1100
+ @if (!schema().fields && schema().sections) {
1101
+ @for (section of schema().sections; track $index) {
1102
+ <div [class]="section.gridClass || 'grid grid-cols-12 gap-6'">
1103
+ @if (section.title) {
1104
+ <div class="col-span-12">
1105
+ <h3 class="text-lg font-medium leading-6 text-slate-900">{{ section.title }}</h3>
1106
+ @if (section.description) {
1107
+ <p class="mt-1 text-sm text-slate-500">{{ section.description }}</p>
1108
+ }
1109
+ </div>
1110
+ }
1111
+
1112
+ @for (field of section.fields; track field.key) {
1113
+ <ad-dynamic-layout [field]="field" [form]="form()"></ad-dynamic-layout>
1114
+ }
1115
+ </div>
1116
+ }
1117
+ }
1118
+
1119
+ <!-- Actions -->
1120
+ <div class="flex justify-end gap-x-4">
1121
+ @if (showCancel()) {
1122
+ <ad-button variant="secondary" type="button" (click)="onCancel()">{{ schema().cancelLabel || 'Cancelar' }}</ad-button>
1123
+ }
1124
+ @if (showSubmit()) {
1125
+ <ad-button variant="primary" type="submit">{{ schema().submitLabel || 'Guardar' }}</ad-button>
1126
+ }
1127
+ </div>
1128
+ </form>
1129
+ }
1130
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: DynamicLayoutComponent, selector: "ad-dynamic-layout", inputs: ["field", "form"] }, { kind: "component", type: AdButtonComponent, selector: "ad-button", inputs: ["variant", "type", "disabled", "loading", "icon", "size", "block"] }, { kind: "component", type: AdFormRendererComponent, selector: "ad-form-renderer", inputs: ["nodes", "form"] }] });
256
1131
  }
257
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcCardComponent, decorators: [{
1132
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: FormEngineComponent, decorators: [{
258
1133
  type: Component,
259
- args: [{ selector: 'cc-card', standalone: true, imports: [CommonModule, NzCardModule], template: "<nz-card [nzTitle]=\"$any(title())\" [nzExtra]=\"extra()\" [nzLoading]=\"$any(loading())\" [nzBordered]=\"$any(bordered())\">\r\n <ng-content></ng-content>\r\n</nz-card>", styles: [":host ::ng-deep .cerca-card{border-radius:var(--radius-lg)!important;box-shadow:var(--shadow-md)!important;transition:all .2s cubic-bezier(.4,0,.2,1)!important}:host ::ng-deep .cerca-card .ant-card-head{border-bottom-color:var(--color-border-subtle)!important;font-family:var(--font-family-base)!important;font-weight:var(--font-weight-semibold)!important}:host ::ng-deep .cerca-card.ant-card-hoverable:hover{box-shadow:var(--shadow-lg)!important;transform:translateY(-2px)!important}\n"] }]
260
- }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], extra: [{ type: i0.Input, args: [{ isSignal: true, alias: "extra", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], bordered: [{ type: i0.Input, args: [{ isSignal: true, alias: "bordered", required: false }] }], padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }] } });
1134
+ args: [{
1135
+ selector: 'ad-form-engine',
1136
+ standalone: true,
1137
+ imports: [CommonModule, ReactiveFormsModule, DynamicLayoutComponent, AdButtonComponent, AdFormRendererComponent],
1138
+ template: `
1139
+ @if (form()) {
1140
+ <form [formGroup]="form()" class="space-y-6" (ngSubmit)="submit()">
1141
+
1142
+ <!-- NEW: Recursive Schema Rendering -->
1143
+ @if (schema().fields) {
1144
+ <div class="grid grid-cols-1 md:grid-cols-12 gap-6 w-full">
1145
+ <ad-form-renderer [nodes]="schema().fields!" [form]="form()"></ad-form-renderer>
1146
+ </div>
1147
+ }
1148
+
1149
+ <!-- LEGACY: Sections Rendering (Fallback) -->
1150
+ @if (!schema().fields && schema().sections) {
1151
+ @for (section of schema().sections; track $index) {
1152
+ <div [class]="section.gridClass || 'grid grid-cols-12 gap-6'">
1153
+ @if (section.title) {
1154
+ <div class="col-span-12">
1155
+ <h3 class="text-lg font-medium leading-6 text-slate-900">{{ section.title }}</h3>
1156
+ @if (section.description) {
1157
+ <p class="mt-1 text-sm text-slate-500">{{ section.description }}</p>
1158
+ }
1159
+ </div>
1160
+ }
1161
+
1162
+ @for (field of section.fields; track field.key) {
1163
+ <ad-dynamic-layout [field]="field" [form]="form()"></ad-dynamic-layout>
1164
+ }
1165
+ </div>
1166
+ }
1167
+ }
1168
+
1169
+ <!-- Actions -->
1170
+ <div class="flex justify-end gap-x-4">
1171
+ @if (showCancel()) {
1172
+ <ad-button variant="secondary" type="button" (click)="onCancel()">{{ schema().cancelLabel || 'Cancelar' }}</ad-button>
1173
+ }
1174
+ @if (showSubmit()) {
1175
+ <ad-button variant="primary" type="submit">{{ schema().submitLabel || 'Guardar' }}</ad-button>
1176
+ }
1177
+ </div>
1178
+ </form>
1179
+ }
1180
+ `
1181
+ }]
1182
+ }], ctorParameters: () => [], propDecorators: { schema: [{ type: i0.Input, args: [{ isSignal: true, alias: "schema", required: true }] }], model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: false }] }], showCancel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCancel", required: false }] }], showSubmit: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSubmit", required: false }] }], formSubmit: [{ type: i0.Output, args: ["formSubmit"] }], formCancel: [{ type: i0.Output, args: ["formCancel"] }] } });
261
1183
 
262
- class CcFormFieldComponent {
263
- constructor() {
264
- this.label = '';
265
- this.hint = '';
266
- this.errorMessage = null;
267
- this.required = false;
268
- this.error = false;
269
- this.for = '';
1184
+ class AdModalWrapperComponent {
1185
+ resource;
1186
+ data = {};
1187
+ isOpen = signal(true, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
1188
+ modalResource = computed(() => ({
1189
+ isOpen: this.isOpen(),
1190
+ title: this.resource?.title,
1191
+ size: 'md',
1192
+ showFooter: false
1193
+ }), ...(ngDevMode ? [{ debugName: "modalResource" }] : []));
1194
+ resultSubject = new Subject();
1195
+ result$ = this.resultSubject.asObservable();
1196
+ onClose() {
1197
+ this.isOpen.set(false);
1198
+ this.resultSubject.next(null);
1199
+ this.resultSubject.complete();
270
1200
  }
271
- get hasError() {
272
- return !!this.errorMessage;
1201
+ onSubmit(result) {
1202
+ this.isOpen.set(false);
1203
+ this.resultSubject.next(result);
1204
+ this.resultSubject.complete();
273
1205
  }
274
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
275
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcFormFieldComponent, isStandalone: true, selector: "cc-form-field", inputs: { label: "label", hint: "hint", errorMessage: "errorMessage", required: "required", error: "error", for: "for" }, ngImport: i0, template: "<div class=\"cc-form-field\" [class.has-error]=\"hasError\">\r\n <cc-label *ngIf=\"label\" [text]=\"label\" [for]=\"for\" [required]=\"required\" [error]=\"hasError\">\r\n </cc-label>\r\n\r\n <div class=\"cc-form-field-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n <div class=\"cc-form-field-info\" *ngIf=\"hint || errorMessage\">\r\n <span class=\"cc-form-field-error\" *ngIf=\"errorMessage\">{{ errorMessage }}</span>\r\n <span class=\"cc-form-field-hint\" *ngIf=\"hint && !errorMessage\">{{ hint }}</span>\r\n </div>\r\n</div>", styles: [".cc-form-field{display:flex;flex-direction:column;margin-bottom:var(--form-field-margin-bottom);width:100%}.cc-form-field .cc-form-field-content{position:relative;display:flex;flex-direction:column}.cc-form-field .cc-form-field-info{margin-top:var(--form-field-message-margin);min-height:1.25rem}.cc-form-field .cc-form-field-error{color:var(--form-field-error-color);font-size:var(--form-field-message-font-size);font-weight:var(--font-weight-medium);display:block;animation:fadeIn .2s ease-out}.cc-form-field .cc-form-field-hint{color:var(--form-field-message-color);font-size:var(--form-field-message-font-size);display:block}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CcLabelComponent, selector: "cc-label", inputs: ["text", "for", "required", "error"] }] }); }
1206
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdModalWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1207
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdModalWrapperComponent, isStandalone: true, selector: "ad-modal-wrapper", ngImport: i0, template: `
1208
+ <ad-modal
1209
+ [resource]="modalResource()"
1210
+ (close)="onClose()">
1211
+
1212
+ @if (resource.type === 'form' && resource.formConfig) {
1213
+ <ad-form-engine
1214
+ [schema]="resource.formConfig"
1215
+ [model]="data"
1216
+ [showCancel]="true"
1217
+ (formSubmit)="onSubmit($event)"
1218
+ (formCancel)="onClose()">
1219
+ </ad-form-engine>
1220
+ } @else {
1221
+ <div class="p-6 text-center text-slate-500">
1222
+ Renderer para el tipo "{{ resource.type }}" no implementado en el modal.
1223
+ </div>
1224
+ }
1225
+ </ad-modal>
1226
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AdModalComponent, selector: "ad-modal", inputs: ["resource"], outputs: ["close"] }, { kind: "component", type: FormEngineComponent, selector: "ad-form-engine", inputs: ["schema", "model", "showCancel", "showSubmit"], outputs: ["formSubmit", "formCancel"] }] });
276
1227
  }
277
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcFormFieldComponent, decorators: [{
1228
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdModalWrapperComponent, decorators: [{
278
1229
  type: Component,
279
- args: [{ selector: 'cc-form-field', standalone: true, imports: [CommonModule, CcLabelComponent], template: "<div class=\"cc-form-field\" [class.has-error]=\"hasError\">\r\n <cc-label *ngIf=\"label\" [text]=\"label\" [for]=\"for\" [required]=\"required\" [error]=\"hasError\">\r\n </cc-label>\r\n\r\n <div class=\"cc-form-field-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n <div class=\"cc-form-field-info\" *ngIf=\"hint || errorMessage\">\r\n <span class=\"cc-form-field-error\" *ngIf=\"errorMessage\">{{ errorMessage }}</span>\r\n <span class=\"cc-form-field-hint\" *ngIf=\"hint && !errorMessage\">{{ hint }}</span>\r\n </div>\r\n</div>", styles: [".cc-form-field{display:flex;flex-direction:column;margin-bottom:var(--form-field-margin-bottom);width:100%}.cc-form-field .cc-form-field-content{position:relative;display:flex;flex-direction:column}.cc-form-field .cc-form-field-info{margin-top:var(--form-field-message-margin);min-height:1.25rem}.cc-form-field .cc-form-field-error{color:var(--form-field-error-color);font-size:var(--form-field-message-font-size);font-weight:var(--font-weight-medium);display:block;animation:fadeIn .2s ease-out}.cc-form-field .cc-form-field-hint{color:var(--form-field-message-color);font-size:var(--form-field-message-font-size);display:block}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
280
- }], propDecorators: { label: [{
1230
+ args: [{
1231
+ selector: 'ad-modal-wrapper',
1232
+ standalone: true,
1233
+ imports: [CommonModule, AdModalComponent, FormEngineComponent],
1234
+ template: `
1235
+ <ad-modal
1236
+ [resource]="modalResource()"
1237
+ (close)="onClose()">
1238
+
1239
+ @if (resource.type === 'form' && resource.formConfig) {
1240
+ <ad-form-engine
1241
+ [schema]="resource.formConfig"
1242
+ [model]="data"
1243
+ [showCancel]="true"
1244
+ (formSubmit)="onSubmit($event)"
1245
+ (formCancel)="onClose()">
1246
+ </ad-form-engine>
1247
+ } @else {
1248
+ <div class="p-6 text-center text-slate-500">
1249
+ Renderer para el tipo "{{ resource.type }}" no implementado en el modal.
1250
+ </div>
1251
+ }
1252
+ </ad-modal>
1253
+ `
1254
+ }]
1255
+ }] });
1256
+ class AdModalService {
1257
+ appRef;
1258
+ injector;
1259
+ constructor(appRef, injector) {
1260
+ this.appRef = appRef;
1261
+ this.injector = injector;
1262
+ }
1263
+ open(resource, data) {
1264
+ const componentRef = createComponent(AdModalWrapperComponent, {
1265
+ environmentInjector: this.injector
1266
+ });
1267
+ // Set inputs
1268
+ componentRef.instance.resource = resource;
1269
+ if (data)
1270
+ componentRef.instance.data = data;
1271
+ // Attach to ApplicationRef so change detection works
1272
+ this.appRef.attachView(componentRef.hostView);
1273
+ // Append to DOM
1274
+ const domElement = componentRef.hostView.rootNodes[0];
1275
+ document.body.appendChild(domElement);
1276
+ // Cleanup on complete
1277
+ componentRef.instance.result$.subscribe({
1278
+ complete: () => {
1279
+ // Small delay to allow Angular modal to animate its close state
1280
+ setTimeout(() => {
1281
+ this.appRef.detachView(componentRef.hostView);
1282
+ componentRef.destroy();
1283
+ }, 300);
1284
+ }
1285
+ });
1286
+ return componentRef.instance.result$;
1287
+ }
1288
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdModalService, deps: [{ token: i0.ApplicationRef }, { token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Injectable });
1289
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdModalService, providedIn: 'root' });
1290
+ }
1291
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdModalService, decorators: [{
1292
+ type: Injectable,
1293
+ args: [{
1294
+ providedIn: 'root'
1295
+ }]
1296
+ }], ctorParameters: () => [{ type: i0.ApplicationRef }, { type: i0.EnvironmentInjector }] });
1297
+
1298
+ class TableEngineComponent {
1299
+ // Signals
1300
+ schema = input.required(...(ngDevMode ? [{ debugName: "schema" }] : [])); // Optional if using columns directly, but Schema approach implies passing the whole schema object usually.
1301
+ // Actually, keeping flexible to support both direct cols or schema.
1302
+ // Let's support independent inputs for now to match old API but strict typed.
1303
+ // Re-defining inputs to match Core Schema
1304
+ columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
1305
+ data = input([], ...(ngDevMode ? [{ debugName: "data" }] : []));
1306
+ loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1307
+ total = input(0, ...(ngDevMode ? [{ debugName: "total" }] : []));
1308
+ pageSize = input(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
1309
+ pageIndex = input(1, ...(ngDevMode ? [{ debugName: "pageIndex" }] : []));
1310
+ actions = input([], ...(ngDevMode ? [{ debugName: "actions" }] : [])); // Parameterized actions
1311
+ queryParamsChange = output();
1312
+ action = output();
1313
+ Math = Math;
1314
+ displayColumns = computed(() => {
1315
+ // Filter visible if property exists, or default true
1316
+ // CoreTableColumn doesn't have is_v displayColumns = computed(() => {
1317
+ // Use schema columns if available, otherwise fallback to columns input
1318
+ return this.schema().columns || this.columns();
1319
+ }, ...(ngDevMode ? [{ debugName: "displayColumns" }] : []));
1320
+ hasActions = computed(() => {
1321
+ const schemaActions = this.schema().actions || [];
1322
+ const inputActions = this.actions();
1323
+ return schemaActions.length > 0 || inputActions.length > 0;
1324
+ }, ...(ngDevMode ? [{ debugName: "hasActions" }] : []));
1325
+ // Helper to get combined actions
1326
+ getActions = computed(() => {
1327
+ const schemaActions = this.schema().actions || [];
1328
+ const inputActions = this.actions();
1329
+ return [...schemaActions, ...inputActions];
1330
+ }, ...(ngDevMode ? [{ debugName: "getActions" }] : []));
1331
+ mapVariant(color) {
1332
+ if (color === 'primary')
1333
+ return 'primary';
1334
+ if (color === 'secondary')
1335
+ return 'secondary';
1336
+ if (color === 'danger')
1337
+ return 'danger';
1338
+ return 'ghost';
1339
+ }
1340
+ onPageChange(newPageIndex) {
1341
+ if (newPageIndex < 1 || (newPageIndex - 1) * this.pageSize() >= this.total())
1342
+ return;
1343
+ this.queryParamsChange.emit({
1344
+ pageIndex: newPageIndex,
1345
+ pageSize: this.pageSize(),
1346
+ sort: [],
1347
+ filter: []
1348
+ });
1349
+ }
1350
+ onActionClick(action, data) {
1351
+ this.action.emit({ action, data });
1352
+ }
1353
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: TableEngineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1354
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: TableEngineComponent, isStandalone: true, selector: "ad-table-engine", inputs: { schema: { classPropertyName: "schema", publicName: "schema", isSignal: true, isRequired: true, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageIndex: { classPropertyName: "pageIndex", publicName: "pageIndex", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { queryParamsChange: "queryParamsChange", action: "action" }, ngImport: i0, template: `
1355
+ <div class="flow-root">
1356
+ <div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
1357
+ <div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
1358
+ <div class="relative">
1359
+ @if (loading()) {
1360
+ <div class="absolute inset-0 bg-white/50 z-10 flex items-center justify-center">
1361
+ <svg class="animate-spin h-8 w-8 text-sky-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
1362
+ <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
1363
+ <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
1364
+ </svg>
1365
+ </div>
1366
+ }
1367
+
1368
+ <table class="min-w-full divide-y divide-slate-300">
1369
+ <thead>
1370
+ <tr>
1371
+ <!-- Checkbox Column if selectable (Future) -->
1372
+
1373
+ @for (column of displayColumns(); track column.key) {
1374
+ <th scope="col"
1375
+ class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-slate-900 sm:pl-0"
1376
+ [style.width]="column.width || 'auto'">
1377
+ {{ column.label }}
1378
+ </th>
1379
+ }
1380
+ @if (hasActions()) {
1381
+ <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-0">
1382
+ <span class="sr-only">Acciones</span>
1383
+ </th>
1384
+ }
1385
+ </tr>
1386
+ </thead>
1387
+ <tbody class="divide-y divide-slate-200 bg-white">
1388
+ @for (item of data(); track item) {
1389
+ <tr>
1390
+ @for (column of displayColumns(); track column.key) {
1391
+ <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm text-slate-500 sm:pl-0">
1392
+ <!-- Simple rendering for now. Registry support can be added here -->
1393
+ {{ item[column.key] }}
1394
+ </td>
1395
+ }
1396
+ @if (hasActions()) {
1397
+ <td class="whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-0">
1398
+ <div class="flex justify-end gap-2">
1399
+ @for (act of getActions(); track act.action) {
1400
+ <ad-button
1401
+ [variant]="mapVariant(act.color)"
1402
+ size="small"
1403
+ (click)="onActionClick(act.action, item)">
1404
+ @if (act.icon) {
1405
+ <ad-icon [name]="act.icon" class="mr-1"></ad-icon>
1406
+ }
1407
+ {{ act.label }}
1408
+ </ad-button>
1409
+ }
1410
+ </div>
1411
+ </td>
1412
+ }
1413
+ </tr>
1414
+ }
1415
+ @if (data().length === 0 && !loading()) {
1416
+ <tr>
1417
+ <td [attr.colspan]="displayColumns().length + (hasActions() ? 1 : 0)" class="py-8 text-center text-sm text-slate-500">
1418
+ No hay datos disponibles
1419
+ </td>
1420
+ </tr>
1421
+ }
1422
+ </tbody>
1423
+ </table>
1424
+ </div>
1425
+ </div>
1426
+ </div>
1427
+
1428
+ <!-- Pagination -->
1429
+ <div class="flex items-center justify-between border-t border-slate-200 bg-white px-4 py-3 sm:px-6 mt-4">
1430
+ <!-- Simplified Pagination for brevity, can be expanded -->
1431
+ <div class="flex flex-1 justify-between sm:hidden">
1432
+ <ad-button variant="secondary" [disabled]="pageIndex() === 1" (click)="onPageChange(pageIndex() - 1)">Anterior</ad-button>
1433
+ <ad-button variant="secondary" [disabled]="pageIndex() * pageSize() >= total()" (click)="onPageChange(pageIndex() + 1)">Siguiente</ad-button>
1434
+ </div>
1435
+ <div class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between">
1436
+ <div>
1437
+ <p class="text-sm text-slate-700">
1438
+ Mostrando <span class="font-medium">{{ (pageIndex() - 1) * pageSize() + 1 }}</span> a <span class="font-medium">{{ Math.min(pageIndex() * pageSize(), total()) }}</span> de <span class="font-medium">{{ total() }}</span> resultados
1439
+ </p>
1440
+ </div>
1441
+ <div>
1442
+ <nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
1443
+ <ad-button variant="secondary" class="rounded-l-md" [disabled]="pageIndex() === 1" (click)="onPageChange(pageIndex() - 1)">Ant</ad-button>
1444
+ <ad-button variant="secondary" class="rounded-r-md" [disabled]="pageIndex() * pageSize() >= total()" (click)="onPageChange(pageIndex() + 1)">Sig</ad-button>
1445
+ </nav>
1446
+ </div>
1447
+ </div>
1448
+ </div>
1449
+ </div>
1450
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AdButtonComponent, selector: "ad-button", inputs: ["variant", "type", "disabled", "loading", "icon", "size", "block"] }, { kind: "component", type: AdIconComponent, selector: "ad-icon", inputs: ["name", "size", "color"] }] });
1451
+ }
1452
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: TableEngineComponent, decorators: [{
1453
+ type: Component,
1454
+ args: [{
1455
+ selector: 'ad-table-engine',
1456
+ standalone: true,
1457
+ imports: [CommonModule, AdButtonComponent, AdIconComponent],
1458
+ template: `
1459
+ <div class="flow-root">
1460
+ <div class="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
1461
+ <div class="inline-block min-w-full py-2 align-middle sm:px-6 lg:px-8">
1462
+ <div class="relative">
1463
+ @if (loading()) {
1464
+ <div class="absolute inset-0 bg-white/50 z-10 flex items-center justify-center">
1465
+ <svg class="animate-spin h-8 w-8 text-sky-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
1466
+ <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
1467
+ <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
1468
+ </svg>
1469
+ </div>
1470
+ }
1471
+
1472
+ <table class="min-w-full divide-y divide-slate-300">
1473
+ <thead>
1474
+ <tr>
1475
+ <!-- Checkbox Column if selectable (Future) -->
1476
+
1477
+ @for (column of displayColumns(); track column.key) {
1478
+ <th scope="col"
1479
+ class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-slate-900 sm:pl-0"
1480
+ [style.width]="column.width || 'auto'">
1481
+ {{ column.label }}
1482
+ </th>
1483
+ }
1484
+ @if (hasActions()) {
1485
+ <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-0">
1486
+ <span class="sr-only">Acciones</span>
1487
+ </th>
1488
+ }
1489
+ </tr>
1490
+ </thead>
1491
+ <tbody class="divide-y divide-slate-200 bg-white">
1492
+ @for (item of data(); track item) {
1493
+ <tr>
1494
+ @for (column of displayColumns(); track column.key) {
1495
+ <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm text-slate-500 sm:pl-0">
1496
+ <!-- Simple rendering for now. Registry support can be added here -->
1497
+ {{ item[column.key] }}
1498
+ </td>
1499
+ }
1500
+ @if (hasActions()) {
1501
+ <td class="whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-0">
1502
+ <div class="flex justify-end gap-2">
1503
+ @for (act of getActions(); track act.action) {
1504
+ <ad-button
1505
+ [variant]="mapVariant(act.color)"
1506
+ size="small"
1507
+ (click)="onActionClick(act.action, item)">
1508
+ @if (act.icon) {
1509
+ <ad-icon [name]="act.icon" class="mr-1"></ad-icon>
1510
+ }
1511
+ {{ act.label }}
1512
+ </ad-button>
1513
+ }
1514
+ </div>
1515
+ </td>
1516
+ }
1517
+ </tr>
1518
+ }
1519
+ @if (data().length === 0 && !loading()) {
1520
+ <tr>
1521
+ <td [attr.colspan]="displayColumns().length + (hasActions() ? 1 : 0)" class="py-8 text-center text-sm text-slate-500">
1522
+ No hay datos disponibles
1523
+ </td>
1524
+ </tr>
1525
+ }
1526
+ </tbody>
1527
+ </table>
1528
+ </div>
1529
+ </div>
1530
+ </div>
1531
+
1532
+ <!-- Pagination -->
1533
+ <div class="flex items-center justify-between border-t border-slate-200 bg-white px-4 py-3 sm:px-6 mt-4">
1534
+ <!-- Simplified Pagination for brevity, can be expanded -->
1535
+ <div class="flex flex-1 justify-between sm:hidden">
1536
+ <ad-button variant="secondary" [disabled]="pageIndex() === 1" (click)="onPageChange(pageIndex() - 1)">Anterior</ad-button>
1537
+ <ad-button variant="secondary" [disabled]="pageIndex() * pageSize() >= total()" (click)="onPageChange(pageIndex() + 1)">Siguiente</ad-button>
1538
+ </div>
1539
+ <div class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-between">
1540
+ <div>
1541
+ <p class="text-sm text-slate-700">
1542
+ Mostrando <span class="font-medium">{{ (pageIndex() - 1) * pageSize() + 1 }}</span> a <span class="font-medium">{{ Math.min(pageIndex() * pageSize(), total()) }}</span> de <span class="font-medium">{{ total() }}</span> resultados
1543
+ </p>
1544
+ </div>
1545
+ <div>
1546
+ <nav class="isolate inline-flex -space-x-px rounded-md shadow-sm" aria-label="Pagination">
1547
+ <ad-button variant="secondary" class="rounded-l-md" [disabled]="pageIndex() === 1" (click)="onPageChange(pageIndex() - 1)">Ant</ad-button>
1548
+ <ad-button variant="secondary" class="rounded-r-md" [disabled]="pageIndex() * pageSize() >= total()" (click)="onPageChange(pageIndex() + 1)">Sig</ad-button>
1549
+ </nav>
1550
+ </div>
1551
+ </div>
1552
+ </div>
1553
+ </div>
1554
+ `
1555
+ }]
1556
+ }], propDecorators: { schema: [{ type: i0.Input, args: [{ isSignal: true, alias: "schema", required: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], total: [{ type: i0.Input, args: [{ isSignal: true, alias: "total", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageIndex", required: false }] }], actions: [{ type: i0.Input, args: [{ isSignal: true, alias: "actions", required: false }] }], queryParamsChange: [{ type: i0.Output, args: ["queryParamsChange"] }], action: [{ type: i0.Output, args: ["action"] }] } });
1557
+
1558
+ class AdBadgeComponent {
1559
+ variant = 'neutral';
1560
+ type = 'subtle';
1561
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1562
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: AdBadgeComponent, isStandalone: true, selector: "ad-badge", inputs: { variant: "variant", type: "type" }, ngImport: i0, template: "<span class=\"ad-badge\" [ngClass]=\"[variant, type]\">\r\n <ng-content></ng-content>\r\n</span>", styles: [".ad-badge{display:inline-flex;align-items:center;justify-content:center;padding:var(--badge-padding-v) var(--badge-padding-h);border-radius:var(--badge-radius);font-size:var(--badge-font-size);font-weight:var(--badge-font-weight);line-height:1;white-space:nowrap;border:1px solid transparent}.ad-badge.success.filled{background-color:var(--color-success-500);color:#fff}.ad-badge.success.subtle{background-color:var(--badge-success-bg);color:var(--badge-success-text);border-color:var(--badge-success-border)}.ad-badge.success.outline{background-color:transparent;color:var(--badge-success-text);border-color:var(--badge-success-border)}.ad-badge.warning.filled{background-color:var(--color-warning-500);color:#fff}.ad-badge.warning.subtle{background-color:var(--badge-warning-bg);color:var(--badge-warning-text);border-color:var(--badge-warning-border)}.ad-badge.warning.outline{background-color:transparent;color:var(--badge-warning-text);border-color:var(--badge-warning-border)}.ad-badge.error.filled{background-color:var(--color-error-500);color:#fff}.ad-badge.error.subtle{background-color:var(--badge-error-bg);color:var(--badge-error-text);border-color:var(--badge-error-border)}.ad-badge.error.outline{background-color:transparent;color:var(--badge-error-text);border-color:var(--badge-error-border)}.ad-badge.info.filled{background-color:var(--color-info-500);color:#fff}.ad-badge.info.subtle{background-color:var(--badge-info-bg);color:var(--badge-info-text);border-color:var(--badge-info-border)}.ad-badge.info.outline{background-color:transparent;color:var(--badge-info-text);border-color:var(--badge-info-border)}.ad-badge.neutral.filled{background-color:var(--color-text-primary);color:var(--color-bg-primary)}.ad-badge.neutral.subtle{background-color:var(--badge-neutral-bg);color:var(--badge-neutral-text);border-color:var(--badge-neutral-border)}.ad-badge.neutral.outline{background-color:transparent;color:var(--badge-neutral-text);border-color:var(--badge-neutral-border)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
1563
+ }
1564
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdBadgeComponent, decorators: [{
1565
+ type: Component,
1566
+ args: [{ selector: 'ad-badge', standalone: true, imports: [CommonModule], template: "<span class=\"ad-badge\" [ngClass]=\"[variant, type]\">\r\n <ng-content></ng-content>\r\n</span>", styles: [".ad-badge{display:inline-flex;align-items:center;justify-content:center;padding:var(--badge-padding-v) var(--badge-padding-h);border-radius:var(--badge-radius);font-size:var(--badge-font-size);font-weight:var(--badge-font-weight);line-height:1;white-space:nowrap;border:1px solid transparent}.ad-badge.success.filled{background-color:var(--color-success-500);color:#fff}.ad-badge.success.subtle{background-color:var(--badge-success-bg);color:var(--badge-success-text);border-color:var(--badge-success-border)}.ad-badge.success.outline{background-color:transparent;color:var(--badge-success-text);border-color:var(--badge-success-border)}.ad-badge.warning.filled{background-color:var(--color-warning-500);color:#fff}.ad-badge.warning.subtle{background-color:var(--badge-warning-bg);color:var(--badge-warning-text);border-color:var(--badge-warning-border)}.ad-badge.warning.outline{background-color:transparent;color:var(--badge-warning-text);border-color:var(--badge-warning-border)}.ad-badge.error.filled{background-color:var(--color-error-500);color:#fff}.ad-badge.error.subtle{background-color:var(--badge-error-bg);color:var(--badge-error-text);border-color:var(--badge-error-border)}.ad-badge.error.outline{background-color:transparent;color:var(--badge-error-text);border-color:var(--badge-error-border)}.ad-badge.info.filled{background-color:var(--color-info-500);color:#fff}.ad-badge.info.subtle{background-color:var(--badge-info-bg);color:var(--badge-info-text);border-color:var(--badge-info-border)}.ad-badge.info.outline{background-color:transparent;color:var(--badge-info-text);border-color:var(--badge-info-border)}.ad-badge.neutral.filled{background-color:var(--color-text-primary);color:var(--color-bg-primary)}.ad-badge.neutral.subtle{background-color:var(--badge-neutral-bg);color:var(--badge-neutral-text);border-color:var(--badge-neutral-border)}.ad-badge.neutral.outline{background-color:transparent;color:var(--badge-neutral-text);border-color:var(--badge-neutral-border)}\n"] }]
1567
+ }], propDecorators: { variant: [{
281
1568
  type: Input
282
- }], hint: [{
1569
+ }], type: [{
283
1570
  type: Input
284
- }], errorMessage: [{
1571
+ }] } });
1572
+
1573
+ class AdLabelComponent {
1574
+ text = '';
1575
+ for = '';
1576
+ required = false;
1577
+ error = false;
1578
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1579
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: AdLabelComponent, isStandalone: true, selector: "ad-label", inputs: { text: "text", for: "for", required: "required", error: "error" }, ngImport: i0, template: "<label [attr.for]=\"for\" class=\"ad-label\" [class.has-error]=\"error\">\r\n {{ text }}\r\n <span *ngIf=\"required\" class=\"required-indicator\" aria-hidden=\"true\">*</span>\r\n</label>", styles: [".ad-label{display:block;font-size:var(--label-font-size);font-weight:var(--label-font-weight);color:var(--label-color);margin-bottom:var(--label-margin-bottom);-webkit-user-select:none;user-select:none}.ad-label .required-indicator{color:var(--label-required-color);margin-left:var(--space-0-5)}.ad-label.has-error{color:var(--color-error-600)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
1580
+ }
1581
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdLabelComponent, decorators: [{
1582
+ type: Component,
1583
+ args: [{ selector: 'ad-label', standalone: true, imports: [CommonModule], template: "<label [attr.for]=\"for\" class=\"ad-label\" [class.has-error]=\"error\">\r\n {{ text }}\r\n <span *ngIf=\"required\" class=\"required-indicator\" aria-hidden=\"true\">*</span>\r\n</label>", styles: [".ad-label{display:block;font-size:var(--label-font-size);font-weight:var(--label-font-weight);color:var(--label-color);margin-bottom:var(--label-margin-bottom);-webkit-user-select:none;user-select:none}.ad-label .required-indicator{color:var(--label-required-color);margin-left:var(--space-0-5)}.ad-label.has-error{color:var(--color-error-600)}\n"] }]
1584
+ }], propDecorators: { text: [{
1585
+ type: Input
1586
+ }], for: [{
285
1587
  type: Input
286
1588
  }], required: [{
287
1589
  type: Input
288
1590
  }], error: [{
289
1591
  type: Input
290
- }], for: [{
291
- type: Input
292
1592
  }] } });
293
1593
 
294
- class CcSearchBarComponent {
295
- constructor() {
296
- this.placeholder = 'Buscar...';
297
- this.debounce = 300;
298
- this.loading = false;
299
- this.variant = 'standalone';
300
- this.search = new EventEmitter();
301
- this.searchQuery = '';
302
- this.searchSubject = new Subject();
303
- this.subscription = new Subscription();
1594
+ class AdminSectionCardComponent {
1595
+ // Input Resource
1596
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
1597
+ title = computed(() => this.resource().title, ...(ngDevMode ? [{ debugName: "title" }] : []));
1598
+ accentedTitle = computed(() => this.resource().accentedTitle, ...(ngDevMode ? [{ debugName: "accentedTitle" }] : []));
1599
+ cardAction = computed(() => this.resource().action, ...(ngDevMode ? [{ debugName: "cardAction" }] : []));
1600
+ loading = computed(() => this.resource().loading ?? false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1601
+ // Outputs
1602
+ action = output();
1603
+ onAction() {
1604
+ if (!this.loading()) {
1605
+ this.action.emit();
1606
+ // Also call the callback if it exists
1607
+ this.cardAction()?.['onClick']?.();
1608
+ }
304
1609
  }
1610
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdminSectionCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1611
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdminSectionCardComponent, isStandalone: true, selector: "ad-admin-section-card", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { action: "action" }, ngImport: i0, template: "<div\r\n class=\"bg-white dark:bg-cerca-primary-active rounded-xl shadow-sm border border-slate-200 dark:border-cerca-primary hover:shadow-md transition-shadow duration-300 overflow-hidden\">\r\n <!-- Header -->\r\n <div\r\n class=\"px-6 py-4 border-b border-slate-100 dark:border-cerca-primary flex justify-between items-center bg-slate-50/50 dark:bg-cerca-primary/50\">\r\n <!-- Title Section -->\r\n <div class=\"flex items-center gap-2\">\r\n <h2 class=\"text-lg font-medium text-cerca-secondary dark:text-slate-300\">\r\n {{ title() }} <span class=\"accent-text font-bold\">{{ accentedTitle() }}</span>\r\n </h2>\r\n </div>\r\n\r\n <!-- Actions -->\r\n @if (cardAction()?.label) {\r\n <ad-button (click)=\"onAction()\" [disabled]=\"loading()\" [loading]=\"loading()\" [icon]=\"cardAction()?.icon\">\r\n {{ cardAction()?.label }}\r\n </ad-button>\r\n }\r\n </div>\r\n\r\n <!-- Content Slot -->\r\n <div class=\"p-6 bg-slate-50 dark:bg-cerca-primary/20 text-cerca-secondary dark:text-slate-300\">\r\n <ng-content></ng-content>\r\n </div>\r\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AdButtonComponent, selector: "ad-button", inputs: ["variant", "type", "disabled", "loading", "icon", "size", "block"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1612
+ }
1613
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdminSectionCardComponent, decorators: [{
1614
+ type: Component,
1615
+ args: [{ selector: 'ad-admin-section-card', standalone: true, imports: [CommonModule, AdButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\r\n class=\"bg-white dark:bg-cerca-primary-active rounded-xl shadow-sm border border-slate-200 dark:border-cerca-primary hover:shadow-md transition-shadow duration-300 overflow-hidden\">\r\n <!-- Header -->\r\n <div\r\n class=\"px-6 py-4 border-b border-slate-100 dark:border-cerca-primary flex justify-between items-center bg-slate-50/50 dark:bg-cerca-primary/50\">\r\n <!-- Title Section -->\r\n <div class=\"flex items-center gap-2\">\r\n <h2 class=\"text-lg font-medium text-cerca-secondary dark:text-slate-300\">\r\n {{ title() }} <span class=\"accent-text font-bold\">{{ accentedTitle() }}</span>\r\n </h2>\r\n </div>\r\n\r\n <!-- Actions -->\r\n @if (cardAction()?.label) {\r\n <ad-button (click)=\"onAction()\" [disabled]=\"loading()\" [loading]=\"loading()\" [icon]=\"cardAction()?.icon\">\r\n {{ cardAction()?.label }}\r\n </ad-button>\r\n }\r\n </div>\r\n\r\n <!-- Content Slot -->\r\n <div class=\"p-6 bg-slate-50 dark:bg-cerca-primary/20 text-cerca-secondary dark:text-slate-300\">\r\n <ng-content></ng-content>\r\n </div>\r\n</div>" }]
1616
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], action: [{ type: i0.Output, args: ["action"] }] } });
1617
+
1618
+ const AdminSectionCardActionSchema = z.object({
1619
+ label: z.string(),
1620
+ icon: z.string().optional(),
1621
+ onClick: z.custom().optional(),
1622
+ });
1623
+ const AdminSectionCardResourceSchema = z.object({
1624
+ title: z.string(),
1625
+ accentedTitle: z.string(),
1626
+ action: AdminSectionCardActionSchema.optional(),
1627
+ loading: z.boolean().default(false).optional(),
1628
+ });
1629
+
1630
+ class AdCardComponent {
1631
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
1632
+ title = computed(() => this.resource().title, ...(ngDevMode ? [{ debugName: "title" }] : []));
1633
+ accentedTitle = computed(() => this.resource().accentedTitle, ...(ngDevMode ? [{ debugName: "accentedTitle" }] : []));
1634
+ actionLabel = computed(() => this.resource().actionLabel, ...(ngDevMode ? [{ debugName: "actionLabel" }] : []));
1635
+ actionIcon = computed(() => this.resource().actionIcon || 'plus', ...(ngDevMode ? [{ debugName: "actionIcon" }] : []));
1636
+ loading = computed(() => this.resource().loading || false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1637
+ bordered = computed(() => this.resource().bordered ?? true, ...(ngDevMode ? [{ debugName: "bordered" }] : []));
1638
+ // Convert padding to string if it's a number (e.g., 24 -> '24px')
1639
+ paddingStyle = computed(() => {
1640
+ const p = this.resource().padding;
1641
+ if (typeof p === 'number')
1642
+ return `${p}px`;
1643
+ return p || '24px';
1644
+ }, ...(ngDevMode ? [{ debugName: "paddingStyle" }] : []));
1645
+ action = output();
1646
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1647
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdCardComponent, isStandalone: true, selector: "ad-card", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { action: "action" }, ngImport: i0, template: "<div class=\"bg-white overflow-hidden rounded-lg transition-all duration-200\" [class.shadow-md]=\"bordered()\"\r\n [class.border]=\"bordered()\" [class.border-slate-200]=\"bordered()\" [class.shadow-none]=\"!bordered()\">\r\n\r\n @if (title() || actionLabel()) {\r\n <div class=\"px-4 py-3 sm:px-6 relative flex justify-between items-center min-h-[48px]\">\r\n <!-- Title -->\r\n <h3 class=\"text-lg font-bold text-slate-900 flex items-center\">\r\n {{ title() }}\r\n @if (accentedTitle()) {\r\n <span class=\"accent-text\">\r\n {{ accentedTitle() }}\r\n </span>\r\n }\r\n </h3>\r\n\r\n <!-- Action -->\r\n @if (actionLabel()) {\r\n <ad-button variant=\"primary\" [icon]=\"actionIcon()\" (click)=\"action.emit()\">\r\n {{ actionLabel() }}\r\n </ad-button>\r\n }\r\n\r\n <!-- Gradient bottom border for header -->\r\n <div class=\"absolute bottom-0 left-0 w-full h-[1px] bg-gradient-to-r from-sky-600 to-sky-400\"></div>\r\n </div>\r\n }\r\n\r\n <div class=\"px-4 py-5 sm:p-6\" [class.opacity-50]=\"loading()\">\r\n @if (loading()) {\r\n <div class=\"flex justify-center py-10\">\r\n <ad-loading size=\"lg\"></ad-loading>\r\n </div>\r\n } @else {\r\n <ng-content></ng-content>\r\n }\r\n </div>\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AdButtonComponent, selector: "ad-button", inputs: ["variant", "type", "disabled", "loading", "icon", "size", "block"] }, { kind: "component", type: AdLoadingComponent, selector: "ad-loading", inputs: ["size", "color"] }] });
1648
+ }
1649
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdCardComponent, decorators: [{
1650
+ type: Component,
1651
+ args: [{ selector: 'ad-card', standalone: true, imports: [CommonModule, AdButtonComponent, AdLoadingComponent], template: "<div class=\"bg-white overflow-hidden rounded-lg transition-all duration-200\" [class.shadow-md]=\"bordered()\"\r\n [class.border]=\"bordered()\" [class.border-slate-200]=\"bordered()\" [class.shadow-none]=\"!bordered()\">\r\n\r\n @if (title() || actionLabel()) {\r\n <div class=\"px-4 py-3 sm:px-6 relative flex justify-between items-center min-h-[48px]\">\r\n <!-- Title -->\r\n <h3 class=\"text-lg font-bold text-slate-900 flex items-center\">\r\n {{ title() }}\r\n @if (accentedTitle()) {\r\n <span class=\"accent-text\">\r\n {{ accentedTitle() }}\r\n </span>\r\n }\r\n </h3>\r\n\r\n <!-- Action -->\r\n @if (actionLabel()) {\r\n <ad-button variant=\"primary\" [icon]=\"actionIcon()\" (click)=\"action.emit()\">\r\n {{ actionLabel() }}\r\n </ad-button>\r\n }\r\n\r\n <!-- Gradient bottom border for header -->\r\n <div class=\"absolute bottom-0 left-0 w-full h-[1px] bg-gradient-to-r from-sky-600 to-sky-400\"></div>\r\n </div>\r\n }\r\n\r\n <div class=\"px-4 py-5 sm:p-6\" [class.opacity-50]=\"loading()\">\r\n @if (loading()) {\r\n <div class=\"flex justify-center py-10\">\r\n <ad-loading size=\"lg\"></ad-loading>\r\n </div>\r\n } @else {\r\n <ng-content></ng-content>\r\n }\r\n </div>\r\n</div>" }]
1652
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], action: [{ type: i0.Output, args: ["action"] }] } });
1653
+
1654
+ const CardResourceSchema = z.object({
1655
+ title: z.string(),
1656
+ accentedTitle: z.string().optional(),
1657
+ actionLabel: z.string().optional(),
1658
+ actionIcon: z.string().default('plus').optional(),
1659
+ loading: z.boolean().default(false).optional(),
1660
+ bordered: z.boolean().default(true).optional(),
1661
+ padding: z.union([z.string(), z.number()]).default('24px').optional(),
1662
+ });
1663
+
1664
+ class AdModalTriggerComponent {
1665
+ // Inputs (Signals) based on US-DEV-007
1666
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
1667
+ screenResource = computed(() => this.resource().resource, ...(ngDevMode ? [{ debugName: "screenResource" }] : []));
1668
+ data = computed(() => this.resource().data, ...(ngDevMode ? [{ debugName: "data" }] : []));
1669
+ triggerLabel = computed(() => this.resource().triggerLabel, ...(ngDevMode ? [{ debugName: "triggerLabel" }] : []));
1670
+ triggerIcon = computed(() => this.resource().triggerIcon, ...(ngDevMode ? [{ debugName: "triggerIcon" }] : []));
1671
+ loading = computed(() => this.resource().loading || false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1672
+ variant = computed(() => this.resource().variant || 'primary', ...(ngDevMode ? [{ debugName: "variant" }] : []));
1673
+ disabled = computed(() => this.resource().disabled || false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1674
+ // Outputs
1675
+ confirm = output();
1676
+ cancel = output();
1677
+ modalService = inject(AdModalService);
1678
+ openModal() {
1679
+ this.modalService.open(this.screenResource(), this.data()).subscribe(result => {
1680
+ if (result) {
1681
+ this.confirm.emit(result);
1682
+ }
1683
+ else {
1684
+ this.cancel.emit();
1685
+ }
1686
+ });
1687
+ }
1688
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdModalTriggerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1689
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.4", type: AdModalTriggerComponent, isStandalone: true, selector: "ad-modal-trigger", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { confirm: "confirm", cancel: "cancel" }, ngImport: i0, template: "<!-- Bot\u00F3n Disparador -->\r\n<ad-button (click)=\"openModal()\" [variant]=\"variant()\" [disabled]=\"disabled()\" [loading]=\"loading()\"\r\n [icon]=\"triggerIcon()\" [size]=\"'default'\">\r\n {{ triggerLabel() }}\r\n</ad-button>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AdButtonComponent, selector: "ad-button", inputs: ["variant", "type", "disabled", "loading", "icon", "size", "block"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1690
+ }
1691
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdModalTriggerComponent, decorators: [{
1692
+ type: Component,
1693
+ args: [{ selector: 'ad-modal-trigger', standalone: true, imports: [CommonModule, AdButtonComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Bot\u00F3n Disparador -->\r\n<ad-button (click)=\"openModal()\" [variant]=\"variant()\" [disabled]=\"disabled()\" [loading]=\"loading()\"\r\n [icon]=\"triggerIcon()\" [size]=\"'default'\">\r\n {{ triggerLabel() }}\r\n</ad-button>" }]
1694
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], confirm: [{ type: i0.Output, args: ["confirm"] }], cancel: [{ type: i0.Output, args: ["cancel"] }] } });
1695
+
1696
+ /**
1697
+ * Componente Molecular Description Header
1698
+ *
1699
+ * Molécula que compone múltiples átomos (títulos, botones, iconos) para
1700
+ * crear un header descriptivo reutilizable con títulos acentuados,
1701
+ * subtítulos y botones de acción dinámicos.
1702
+ *
1703
+ * @example
1704
+ * ```html
1705
+ * <ad-description-header [resource]="headerResource"></ad-description-header>
1706
+ * ```
1707
+ */
1708
+ class AdDescriptionHeaderComponent {
1709
+ /** Recurso de configuración del header */
1710
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
1711
+ title = computed(() => this.resource().title, ...(ngDevMode ? [{ debugName: "title" }] : []));
1712
+ accentedTitle = computed(() => this.resource().accentedTitle, ...(ngDevMode ? [{ debugName: "accentedTitle" }] : []));
1713
+ subtitle = computed(() => this.resource().subtitle, ...(ngDevMode ? [{ debugName: "subtitle" }] : []));
1714
+ buttons = computed(() => this.resource().buttons, ...(ngDevMode ? [{ debugName: "buttons" }] : []));
1715
+ showDivider = computed(() => this.resource().showDivider, ...(ngDevMode ? [{ debugName: "showDivider" }] : []));
1716
+ getModalTriggerResource(button) {
1717
+ return {
1718
+ resource: button.modalResource,
1719
+ data: button.modalData,
1720
+ triggerLabel: button.label,
1721
+ triggerIcon: button.icon,
1722
+ variant: button.variant,
1723
+ disabled: button.disabled
1724
+ };
1725
+ }
1726
+ /**
1727
+ * Maneja el clic en un botón
1728
+ * @param onClick Callback del botón
1729
+ */
1730
+ handleButtonClick(onClick) {
1731
+ if (onClick) {
1732
+ onClick();
1733
+ }
1734
+ }
1735
+ /**
1736
+ * Maneja la confirmación de un modal
1737
+ * @param onConfirm Callback de confirmación
1738
+ * @param result Resultado del modal
1739
+ */
1740
+ handleModalConfirm(onConfirm, result) {
1741
+ if (onConfirm) {
1742
+ onConfirm(result);
1743
+ }
1744
+ }
1745
+ /**
1746
+ * Maneja la cancelación de un modal
1747
+ * @param onCancel Callback de cancelación
1748
+ */
1749
+ handleModalCancel(onCancel) {
1750
+ if (onCancel) {
1751
+ onCancel();
1752
+ }
1753
+ }
1754
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdDescriptionHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1755
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdDescriptionHeaderComponent, isStandalone: true, selector: "ad-description-header", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"premium-header-card\">\r\n <div class=\"header-main\">\r\n <div class=\"title-group\">\r\n <h1 class=\"premium-title\">\r\n {{ title() }}\r\n @if (accentedTitle()) {\r\n <span class=\"accent-text\">\r\n {{ accentedTitle() }}\r\n </span>\r\n }\r\n </h1>\r\n @if (subtitle()) {\r\n <p class=\"premium-subtitle\">\r\n {{ subtitle() }}\r\n </p>\r\n }\r\n </div>\r\n @if (buttons() && buttons()!.length > 0) {\r\n <div class=\"header-actions\">\r\n @for (button of buttons(); track $index) {\r\n @if (button.isModalTrigger && button.modalResource) {\r\n <ad-modal-trigger [resource]=\"getModalTriggerResource(button)\"\r\n (confirm)=\"handleModalConfirm(button.onModalConfirm, $event)\"\r\n (cancel)=\"handleModalCancel(button.onModalCancel)\">\r\n </ad-modal-trigger>\r\n } @else {\r\n <ad-button [variant]=\"button.variant || 'primary'\" [type]=\"button.type || 'button'\"\r\n [disabled]=\"button.disabled || false\" (click)=\"handleButtonClick(button.onClick)\" [icon]=\"button.icon\">\r\n {{ button.label }}\r\n </ad-button>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n\r\n<!-- Divider is no longer needed with the card style -->\r\n@if (showDivider() && false) {\r\n<div class=\"ad-description-header__divider\"></div>\r\n}", styles: [":root{--color-primary: #002855;--color-primary-hover: #003366;--color-primary-active: #001a38;--color-primary-light: #F1F5F9;--color-primary-accent: #5BC2E7;--color-background: #F8FAFC;--color-surface: #FFFFFF;--color-border: #F1F5F9;--color-secondary: #475569;--color-secondary-light: #94A3B8;--color-success: #A2D033;--color-success-bg: rgba(162, 208, 51, .05);--color-success-text: #7A9F26;--color-alert: #EF4444;--color-alert-bg: rgba(239, 68, 68, .05);--color-alert-text: #DC2626;--color-warning: #F59E0B;--color-warning-bg: rgba(245, 158, 11, .05);--color-warning-text: #D97706;--color-slate-900: #0f172a;--color-slate-800: #1e293b;--color-slate-700: #334155;--color-slate-500: #64748b;--color-slate-400: #94a3b8;--color-slate-200: #e2e8f0;--color-slate-100: #f1f5f9;--color-slate-50: #f8fafc;--color-white: #ffffff;--radius-cerca: 1.25rem;--radius-cerca-sm: .75rem;--radius-cerca-lg: 2rem;--shadow-premium: 0 20px 25px -5px rgba(0, 0, 0, .02), 0 8px 10px -6px rgba(0, 0, 0, .02);--shadow-premium-hover: 0 30px 40px -5px rgba(0, 0, 0, .05), 0 15px 20px -5px rgba(0, 0, 0, .03);--shadow-glass: 0 8px 32px 0 rgba(31, 38, 135, .07);--shadow-sidebar: 4px 0 24px 0 rgba(0, 0, 0, .05);--shadow-glow-primary: 0 0 20px rgba(91, 194, 231, .15);--gradient-premium: linear-gradient(135deg, #002855 0%, #001a38 100%);--gradient-glass: linear-gradient(135deg, rgba(255, 255, 255, .1), rgba(255, 255, 255, .05));--gradient-accent: linear-gradient(135deg, #5BC2E7 0%, #002855 100%);--ant-primary-color: var(--color-primary);--ant-primary-color-hover: var(--color-primary-hover);--ant-primary-color-active: var(--color-primary-active);--ant-primary-color-outline: rgba(0, 40, 85, .2);--ant-success-color: var(--color-success);--ant-success-color-hover: #b3e040;--ant-success-color-active: #8fb82b;--ant-success-color-outline: rgba(162, 208, 51, .2);--ant-info-color: var(--color-primary);--ant-link-color: var(--color-primary-accent);--ant-link-color-hover: #4db3d9;--ant-link-color-active: var(--color-primary)}:root{--font-sans: \"Inter\", system-ui, sans-serif;--font-display: \"Outfit\", sans-serif}:root,[data-theme=light]{--color-bg-primary: var(--color-surface);--color-bg-secondary: var(--color-background);--color-text-primary: var(--color-slate-900);--color-text-secondary: var(--color-secondary);--color-text-muted: var(--color-secondary-light);--color-border-subtle: var(--color-slate-200);--color-border-strong: var(--color-slate-300);--color-brand: var(--color-primary);--color-brand-hover: var(--color-primary-hover);--color-focus-ring: var(--ant-primary-color-outline);--color-success: var(--color-success);--color-danger: var(--color-alert);--surface-glass-bg: rgba(255, 255, 255, .7);--surface-glass-border: rgba(255, 255, 255, .3);--surface-glass-blur: 12px;--surface-glass-shadow: var(--shadow-glass);--font-heading-xl: 32px;--font-heading-lg: 24px;--font-heading-md: 20px;--font-body-lg: 18px;--font-body-md: 16px;--font-caption: 12px;--font-family-base: var(--font-sans);--font-weight-regular: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--radius-sm: var(--radius-cerca-sm);--radius-md: var(--radius-cerca);--radius-lg: var(--radius-cerca-lg);--radius-xl: 3rem;--radius-full: 9999px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .1);--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, .1)}[data-theme=dark]{--color-bg-primary: var(--color-slate-900);--color-bg-secondary: var(--color-slate-800);--color-text-primary: var(--color-white);--color-text-secondary: var(--color-slate-400);--color-text-muted: var(--color-slate-500);--color-border-subtle: var(--color-slate-700);--color-border-strong: var(--color-slate-600);--color-brand: var(--color-primary-light);--color-brand-hover: var(--color-primary-accent);--color-focus-ring: rgba(59, 130, 246, .5);--surface-glass-bg: rgba(15, 23, 42, .8);--surface-glass-border: rgba(255, 255, 255, .1);--surface-glass-blur: 16px;--surface-glass-shadow: 0 10px 15px -3px rgba(0, 0, 0, .3)}:root{--h1-size: var(--font-size-h1);--h1-weight: var(--font-weight-semibold);--h2-size: var(--font-size-h2);--h2-weight: var(--font-weight-semibold);--h3-size: var(--font-size-h3);--h3-weight: var(--font-weight-semibold);--body-size: var(--font-size-body);--body-weight: var(--font-weight-regular);--sm-size: var(--font-size-sm);--sm-weight: var(--font-weight-regular);--caption-size: var(--font-size-caption);--caption-weight: var(--font-weight-regular)}:root{--btn-height-md: 44px;--btn-radius: var(--radius-md);--btn-font-weight: var(--font-weight-medium);--btn-bg-primary: var(--color-brand);--btn-text-primary: #FFFFFF;--btn-shadow-default: var(--shadow-sm);--btn-shadow-hover: var(--shadow-md);--btn-transition: .15s ease;--btn-focus-ring: 0 0 0 2px var(--color-focus-ring)}:root{--card-bg: var(--color-bg-primary);--card-radius: var(--radius-lg);--card-shadow: var(--shadow-sm);--card-shadow-hover: var(--shadow-md)}:root{--input-height-md: 44px;--input-bg: var(--color-bg-primary);--input-radius: var(--radius-md);--input-border-default: var(--color-border-subtle);--input-border-hover: var(--color-border-strong);--input-border-focus: var(--color-brand);--input-border-error: var(--color-danger);--input-transition: .12s ease-in-out;--input-focus-ring: 0 0 0 3px var(--color-focus-ring);--input-error-ring: 0 0 0 3px rgba(239, 68, 68, .15)}.ad-badge-tokens{--badge-radius: var(--radius-sm);--badge-padding-v: var(--space-1);--badge-padding-h: var(--space-2);--badge-font-size: var(--font-size-xs);--badge-font-weight: var(--font-weight-medium);--badge-success-bg: #D1FAE5;--badge-success-text: #065F46;--badge-success-border: #A7F3D0;--badge-warning-bg: #FEF3C7;--badge-warning-text: #92400E;--badge-warning-border: #FDE68A;--badge-error-bg: #FFE4E6;--badge-error-text: #9F1239;--badge-error-border: #FECDD3;--badge-info-bg: var(--color-info-50);--badge-info-text: var(--color-info-700);--badge-info-border: var(--color-info-200);--badge-neutral-bg: var(--color-slate-100);--badge-neutral-text: var(--color-slate-700);--badge-neutral-border: var(--color-slate-200)}.ad-label-tokens{--label-font-size: var(--font-size-sm);--label-font-weight: var(--font-weight-medium);--label-color: var(--color-text-secondary);--label-required-color: var(--color-error-500);--label-margin-bottom: var(--space-2)}.ad-select-tokens{--select-bg: var(--color-bg-primary);--select-border: var(--color-border-subtle);--select-border-hover: var(--color-border-strong);--select-border-focus: var(--color-brand-primary);--select-shadow-focus: var(--shadow-focus);--select-radius: var(--radius-md);--select-height: 44px;--select-padding-h: var(--space-4);--select-dropdown-bg: var(--color-bg-primary);--select-dropdown-shadow: var(--shadow-md);--select-dropdown-max-height: 240px;--select-option-padding: var(--space-3) var(--space-4);--select-option-hover: var(--color-bg-secondary);--select-option-selected-bg: var(--color-brand-50);--select-option-selected-text: var(--color-brand-primary)}.ad-form-field-tokens{--form-field-margin-bottom: var(--space-6);--form-field-label-margin: var(--space-2);--form-field-message-margin: var(--space-1);--form-field-message-font-size: var(--font-size-xs);--form-field-message-color: var(--color-text-muted);--form-field-error-color: var(--color-error-600)}.ad-header-tokens{--header-height: 72px;--header-bg: var(--color-surface);--header-border-color: var(--color-border);--header-padding: 0 var(--space-6);--header-shadow: 0 1px 2px rgba(0, 0, 0, .05);--header-z-index: 100;--header-logo-height: 32px;--header-user-gap: var(--space-4)}.ad-sidebar-tokens{--sidebar-width: 280px;--sidebar-collapsed-width: 80px;--sidebar-bg: var(--color-slate-900);--sidebar-border-color: var(--color-slate-800);--sidebar-padding: var(--space-4);--sidebar-z-index: 101;--sidebar-transition: width .3s cubic-bezier(.4, 0, .2, 1);--sidebar-item-height: 48px;--sidebar-item-radius: var(--radius-lg);--sidebar-item-padding: 0 var(--space-4);--sidebar-item-gap: var(--space-3);--sidebar-accent-color: var(--color-primary);--sidebar-text-color: var(--color-surface);--sidebar-text-muted: var(--color-slate-400)}.ad-data-table-tokens{--table-bg: var(--color-bg-primary);--table-header-bg: var(--color-bg-secondary);--table-border-color: var(--color-border-subtle);--table-header-color: var(--color-text-muted);--table-row-hover: rgba(var(--color-brand-primary-rgb), .04);--table-cell-padding: var(--space-4);--table-font-size: var(--font-size-sm);--table-radius: var(--radius-lg)}:root{--modal-bg: var(--color-surface);--modal-overlay-bg: rgba(0, 0, 0, .5);--modal-radius: var(--radius-cerca);--modal-shadow: var(--shadow-premium);--modal-z-index: 1000;--modal-header-padding: 12px 24px;--modal-body-padding: 24px;--modal-footer-padding: 16px 24px;--modal-sm-width: 400px;--modal-md-width: 600px;--modal-lg-width: 900px}.premium-header-card{background:#fff;padding:1.5rem 2rem;border-radius:16px;box-shadow:var(--shadow-premium, 0 4px 20px -2px rgba(0, 0, 0, .1));margin-bottom:2rem;position:relative;overflow:hidden;border:1px solid rgba(0,0,0,.03)}.premium-header-card:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:4px;background:linear-gradient(to right,var(--color-primary),var(--color-primary-accent, #00d2ff))}.header-main{display:flex;justify-content:space-between;align-items:center;gap:1.5rem;flex-wrap:wrap}@media(max-width:768px){.header-main{flex-direction:column;align-items:stretch}}.title-group{display:flex;flex-direction:column;gap:.25rem}.premium-title{font-size:1.5rem;font-weight:800;letter-spacing:-.04em;margin:0;color:var(--color-slate-900, #1e293b);line-height:1.2}.premium-title .accent-text{background:linear-gradient(135deg,var(--color-primary) 0%,var(--color-primary-accent, #00d2ff) 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;margin-left:.3rem}.premium-subtitle{margin-top:0rem;color:var(--color-slate-500, #64748b);font-size:.9rem;font-weight:500;letter-spacing:-.01em}.header-actions{display:flex;gap:var(--spacing-sm);align-items:center}@media(max-width:768px){.header-actions{width:100%;justify-content:flex-start}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AdButtonComponent, selector: "ad-button", inputs: ["variant", "type", "disabled", "loading", "icon", "size", "block"] }, { kind: "component", type: AdModalTriggerComponent, selector: "ad-modal-trigger", inputs: ["resource"], outputs: ["confirm", "cancel"] }] });
1756
+ }
1757
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdDescriptionHeaderComponent, decorators: [{
1758
+ type: Component,
1759
+ args: [{ selector: 'ad-description-header', standalone: true, imports: [CommonModule, AdButtonComponent, AdModalTriggerComponent], template: "<div class=\"premium-header-card\">\r\n <div class=\"header-main\">\r\n <div class=\"title-group\">\r\n <h1 class=\"premium-title\">\r\n {{ title() }}\r\n @if (accentedTitle()) {\r\n <span class=\"accent-text\">\r\n {{ accentedTitle() }}\r\n </span>\r\n }\r\n </h1>\r\n @if (subtitle()) {\r\n <p class=\"premium-subtitle\">\r\n {{ subtitle() }}\r\n </p>\r\n }\r\n </div>\r\n @if (buttons() && buttons()!.length > 0) {\r\n <div class=\"header-actions\">\r\n @for (button of buttons(); track $index) {\r\n @if (button.isModalTrigger && button.modalResource) {\r\n <ad-modal-trigger [resource]=\"getModalTriggerResource(button)\"\r\n (confirm)=\"handleModalConfirm(button.onModalConfirm, $event)\"\r\n (cancel)=\"handleModalCancel(button.onModalCancel)\">\r\n </ad-modal-trigger>\r\n } @else {\r\n <ad-button [variant]=\"button.variant || 'primary'\" [type]=\"button.type || 'button'\"\r\n [disabled]=\"button.disabled || false\" (click)=\"handleButtonClick(button.onClick)\" [icon]=\"button.icon\">\r\n {{ button.label }}\r\n </ad-button>\r\n }\r\n }\r\n </div>\r\n }\r\n </div>\r\n</div>\r\n\r\n<!-- Divider is no longer needed with the card style -->\r\n@if (showDivider() && false) {\r\n<div class=\"ad-description-header__divider\"></div>\r\n}", styles: [":root{--color-primary: #002855;--color-primary-hover: #003366;--color-primary-active: #001a38;--color-primary-light: #F1F5F9;--color-primary-accent: #5BC2E7;--color-background: #F8FAFC;--color-surface: #FFFFFF;--color-border: #F1F5F9;--color-secondary: #475569;--color-secondary-light: #94A3B8;--color-success: #A2D033;--color-success-bg: rgba(162, 208, 51, .05);--color-success-text: #7A9F26;--color-alert: #EF4444;--color-alert-bg: rgba(239, 68, 68, .05);--color-alert-text: #DC2626;--color-warning: #F59E0B;--color-warning-bg: rgba(245, 158, 11, .05);--color-warning-text: #D97706;--color-slate-900: #0f172a;--color-slate-800: #1e293b;--color-slate-700: #334155;--color-slate-500: #64748b;--color-slate-400: #94a3b8;--color-slate-200: #e2e8f0;--color-slate-100: #f1f5f9;--color-slate-50: #f8fafc;--color-white: #ffffff;--radius-cerca: 1.25rem;--radius-cerca-sm: .75rem;--radius-cerca-lg: 2rem;--shadow-premium: 0 20px 25px -5px rgba(0, 0, 0, .02), 0 8px 10px -6px rgba(0, 0, 0, .02);--shadow-premium-hover: 0 30px 40px -5px rgba(0, 0, 0, .05), 0 15px 20px -5px rgba(0, 0, 0, .03);--shadow-glass: 0 8px 32px 0 rgba(31, 38, 135, .07);--shadow-sidebar: 4px 0 24px 0 rgba(0, 0, 0, .05);--shadow-glow-primary: 0 0 20px rgba(91, 194, 231, .15);--gradient-premium: linear-gradient(135deg, #002855 0%, #001a38 100%);--gradient-glass: linear-gradient(135deg, rgba(255, 255, 255, .1), rgba(255, 255, 255, .05));--gradient-accent: linear-gradient(135deg, #5BC2E7 0%, #002855 100%);--ant-primary-color: var(--color-primary);--ant-primary-color-hover: var(--color-primary-hover);--ant-primary-color-active: var(--color-primary-active);--ant-primary-color-outline: rgba(0, 40, 85, .2);--ant-success-color: var(--color-success);--ant-success-color-hover: #b3e040;--ant-success-color-active: #8fb82b;--ant-success-color-outline: rgba(162, 208, 51, .2);--ant-info-color: var(--color-primary);--ant-link-color: var(--color-primary-accent);--ant-link-color-hover: #4db3d9;--ant-link-color-active: var(--color-primary)}:root{--font-sans: \"Inter\", system-ui, sans-serif;--font-display: \"Outfit\", sans-serif}:root,[data-theme=light]{--color-bg-primary: var(--color-surface);--color-bg-secondary: var(--color-background);--color-text-primary: var(--color-slate-900);--color-text-secondary: var(--color-secondary);--color-text-muted: var(--color-secondary-light);--color-border-subtle: var(--color-slate-200);--color-border-strong: var(--color-slate-300);--color-brand: var(--color-primary);--color-brand-hover: var(--color-primary-hover);--color-focus-ring: var(--ant-primary-color-outline);--color-success: var(--color-success);--color-danger: var(--color-alert);--surface-glass-bg: rgba(255, 255, 255, .7);--surface-glass-border: rgba(255, 255, 255, .3);--surface-glass-blur: 12px;--surface-glass-shadow: var(--shadow-glass);--font-heading-xl: 32px;--font-heading-lg: 24px;--font-heading-md: 20px;--font-body-lg: 18px;--font-body-md: 16px;--font-caption: 12px;--font-family-base: var(--font-sans);--font-weight-regular: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--radius-sm: var(--radius-cerca-sm);--radius-md: var(--radius-cerca);--radius-lg: var(--radius-cerca-lg);--radius-xl: 3rem;--radius-full: 9999px;--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, .1);--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, .1)}[data-theme=dark]{--color-bg-primary: var(--color-slate-900);--color-bg-secondary: var(--color-slate-800);--color-text-primary: var(--color-white);--color-text-secondary: var(--color-slate-400);--color-text-muted: var(--color-slate-500);--color-border-subtle: var(--color-slate-700);--color-border-strong: var(--color-slate-600);--color-brand: var(--color-primary-light);--color-brand-hover: var(--color-primary-accent);--color-focus-ring: rgba(59, 130, 246, .5);--surface-glass-bg: rgba(15, 23, 42, .8);--surface-glass-border: rgba(255, 255, 255, .1);--surface-glass-blur: 16px;--surface-glass-shadow: 0 10px 15px -3px rgba(0, 0, 0, .3)}:root{--h1-size: var(--font-size-h1);--h1-weight: var(--font-weight-semibold);--h2-size: var(--font-size-h2);--h2-weight: var(--font-weight-semibold);--h3-size: var(--font-size-h3);--h3-weight: var(--font-weight-semibold);--body-size: var(--font-size-body);--body-weight: var(--font-weight-regular);--sm-size: var(--font-size-sm);--sm-weight: var(--font-weight-regular);--caption-size: var(--font-size-caption);--caption-weight: var(--font-weight-regular)}:root{--btn-height-md: 44px;--btn-radius: var(--radius-md);--btn-font-weight: var(--font-weight-medium);--btn-bg-primary: var(--color-brand);--btn-text-primary: #FFFFFF;--btn-shadow-default: var(--shadow-sm);--btn-shadow-hover: var(--shadow-md);--btn-transition: .15s ease;--btn-focus-ring: 0 0 0 2px var(--color-focus-ring)}:root{--card-bg: var(--color-bg-primary);--card-radius: var(--radius-lg);--card-shadow: var(--shadow-sm);--card-shadow-hover: var(--shadow-md)}:root{--input-height-md: 44px;--input-bg: var(--color-bg-primary);--input-radius: var(--radius-md);--input-border-default: var(--color-border-subtle);--input-border-hover: var(--color-border-strong);--input-border-focus: var(--color-brand);--input-border-error: var(--color-danger);--input-transition: .12s ease-in-out;--input-focus-ring: 0 0 0 3px var(--color-focus-ring);--input-error-ring: 0 0 0 3px rgba(239, 68, 68, .15)}.ad-badge-tokens{--badge-radius: var(--radius-sm);--badge-padding-v: var(--space-1);--badge-padding-h: var(--space-2);--badge-font-size: var(--font-size-xs);--badge-font-weight: var(--font-weight-medium);--badge-success-bg: #D1FAE5;--badge-success-text: #065F46;--badge-success-border: #A7F3D0;--badge-warning-bg: #FEF3C7;--badge-warning-text: #92400E;--badge-warning-border: #FDE68A;--badge-error-bg: #FFE4E6;--badge-error-text: #9F1239;--badge-error-border: #FECDD3;--badge-info-bg: var(--color-info-50);--badge-info-text: var(--color-info-700);--badge-info-border: var(--color-info-200);--badge-neutral-bg: var(--color-slate-100);--badge-neutral-text: var(--color-slate-700);--badge-neutral-border: var(--color-slate-200)}.ad-label-tokens{--label-font-size: var(--font-size-sm);--label-font-weight: var(--font-weight-medium);--label-color: var(--color-text-secondary);--label-required-color: var(--color-error-500);--label-margin-bottom: var(--space-2)}.ad-select-tokens{--select-bg: var(--color-bg-primary);--select-border: var(--color-border-subtle);--select-border-hover: var(--color-border-strong);--select-border-focus: var(--color-brand-primary);--select-shadow-focus: var(--shadow-focus);--select-radius: var(--radius-md);--select-height: 44px;--select-padding-h: var(--space-4);--select-dropdown-bg: var(--color-bg-primary);--select-dropdown-shadow: var(--shadow-md);--select-dropdown-max-height: 240px;--select-option-padding: var(--space-3) var(--space-4);--select-option-hover: var(--color-bg-secondary);--select-option-selected-bg: var(--color-brand-50);--select-option-selected-text: var(--color-brand-primary)}.ad-form-field-tokens{--form-field-margin-bottom: var(--space-6);--form-field-label-margin: var(--space-2);--form-field-message-margin: var(--space-1);--form-field-message-font-size: var(--font-size-xs);--form-field-message-color: var(--color-text-muted);--form-field-error-color: var(--color-error-600)}.ad-header-tokens{--header-height: 72px;--header-bg: var(--color-surface);--header-border-color: var(--color-border);--header-padding: 0 var(--space-6);--header-shadow: 0 1px 2px rgba(0, 0, 0, .05);--header-z-index: 100;--header-logo-height: 32px;--header-user-gap: var(--space-4)}.ad-sidebar-tokens{--sidebar-width: 280px;--sidebar-collapsed-width: 80px;--sidebar-bg: var(--color-slate-900);--sidebar-border-color: var(--color-slate-800);--sidebar-padding: var(--space-4);--sidebar-z-index: 101;--sidebar-transition: width .3s cubic-bezier(.4, 0, .2, 1);--sidebar-item-height: 48px;--sidebar-item-radius: var(--radius-lg);--sidebar-item-padding: 0 var(--space-4);--sidebar-item-gap: var(--space-3);--sidebar-accent-color: var(--color-primary);--sidebar-text-color: var(--color-surface);--sidebar-text-muted: var(--color-slate-400)}.ad-data-table-tokens{--table-bg: var(--color-bg-primary);--table-header-bg: var(--color-bg-secondary);--table-border-color: var(--color-border-subtle);--table-header-color: var(--color-text-muted);--table-row-hover: rgba(var(--color-brand-primary-rgb), .04);--table-cell-padding: var(--space-4);--table-font-size: var(--font-size-sm);--table-radius: var(--radius-lg)}:root{--modal-bg: var(--color-surface);--modal-overlay-bg: rgba(0, 0, 0, .5);--modal-radius: var(--radius-cerca);--modal-shadow: var(--shadow-premium);--modal-z-index: 1000;--modal-header-padding: 12px 24px;--modal-body-padding: 24px;--modal-footer-padding: 16px 24px;--modal-sm-width: 400px;--modal-md-width: 600px;--modal-lg-width: 900px}.premium-header-card{background:#fff;padding:1.5rem 2rem;border-radius:16px;box-shadow:var(--shadow-premium, 0 4px 20px -2px rgba(0, 0, 0, .1));margin-bottom:2rem;position:relative;overflow:hidden;border:1px solid rgba(0,0,0,.03)}.premium-header-card:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:4px;background:linear-gradient(to right,var(--color-primary),var(--color-primary-accent, #00d2ff))}.header-main{display:flex;justify-content:space-between;align-items:center;gap:1.5rem;flex-wrap:wrap}@media(max-width:768px){.header-main{flex-direction:column;align-items:stretch}}.title-group{display:flex;flex-direction:column;gap:.25rem}.premium-title{font-size:1.5rem;font-weight:800;letter-spacing:-.04em;margin:0;color:var(--color-slate-900, #1e293b);line-height:1.2}.premium-title .accent-text{background:linear-gradient(135deg,var(--color-primary) 0%,var(--color-primary-accent, #00d2ff) 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;margin-left:.3rem}.premium-subtitle{margin-top:0rem;color:var(--color-slate-500, #64748b);font-size:.9rem;font-weight:500;letter-spacing:-.01em}.header-actions{display:flex;gap:var(--spacing-sm);align-items:center}@media(max-width:768px){.header-actions{width:100%;justify-content:flex-start}}\n"] }]
1760
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }] } });
1761
+
1762
+ const DescriptionHeaderButtonSchema = z.object({
1763
+ label: z.string(),
1764
+ variant: z.enum(['primary', 'secondary', 'ghost', 'outline', 'danger']).optional(),
1765
+ type: z.enum(['button', 'submit', 'reset']).optional(),
1766
+ icon: z.string().optional(),
1767
+ onClick: z.custom().optional(),
1768
+ disabled: z.boolean().optional(),
1769
+ isModalTrigger: z.boolean().optional(),
1770
+ modalResource: z.custom().optional(),
1771
+ modalData: z.any().optional(),
1772
+ onModalConfirm: z.custom().optional(),
1773
+ onModalCancel: z.custom().optional(),
1774
+ });
1775
+ const DescriptionHeaderResourceSchema = z.object({
1776
+ title: z.string(),
1777
+ accentedTitle: z.string().optional(),
1778
+ subtitle: z.string().optional(),
1779
+ buttons: z.array(DescriptionHeaderButtonSchema).optional(),
1780
+ showDivider: z.boolean().optional(),
1781
+ });
1782
+
1783
+ class AdFormFieldComponent {
1784
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
1785
+ label = computed(() => this.resource().label || '', ...(ngDevMode ? [{ debugName: "label" }] : []));
1786
+ hint = computed(() => this.resource().hint || '', ...(ngDevMode ? [{ debugName: "hint" }] : []));
1787
+ errorMessage = computed(() => this.resource().errorMessage || null, ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
1788
+ required = computed(() => this.resource().required || false, ...(ngDevMode ? [{ debugName: "required" }] : []));
1789
+ error = computed(() => this.resource().error || false, ...(ngDevMode ? [{ debugName: "error" }] : []));
1790
+ forAttr = computed(() => this.resource().for || '', ...(ngDevMode ? [{ debugName: "forAttr" }] : []));
1791
+ hasError = computed(() => !!this.errorMessage(), ...(ngDevMode ? [{ debugName: "hasError" }] : []));
1792
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdFormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1793
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdFormFieldComponent, isStandalone: true, selector: "ad-form-field", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"ad-form-field\" [class.has-error]=\"hasError()\">\r\n @if (label()) {\r\n <ad-label [text]=\"label()\" [for]=\"forAttr()\" [required]=\"required()\" [error]=\"hasError()\">\r\n </ad-label>\r\n }\r\n\r\n <div class=\"ad-form-field-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n @if (hint() || errorMessage()) {\r\n <div class=\"ad-form-field-info\">\r\n @if (errorMessage()) {\r\n <span class=\"ad-form-field-error\">{{ errorMessage() }}</span>\r\n }\r\n @if (hint() && !errorMessage()) {\r\n <span class=\"ad-form-field-hint\">{{ hint() }}</span>\r\n }\r\n </div>\r\n }\r\n</div>", styles: [".ad-form-field{display:flex;flex-direction:column;margin-bottom:var(--form-field-margin-bottom);width:100%}.ad-form-field .ad-form-field-content{position:relative;display:flex;flex-direction:column}.ad-form-field .ad-form-field-info{margin-top:var(--form-field-message-margin);min-height:1.25rem}.ad-form-field .ad-form-field-error{color:var(--form-field-error-color);font-size:var(--form-field-message-font-size);font-weight:var(--font-weight-medium);display:block;animation:fadeIn .2s ease-out}.ad-form-field .ad-form-field-hint{color:var(--form-field-message-color);font-size:var(--form-field-message-font-size);display:block}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AdLabelComponent, selector: "ad-label", inputs: ["text", "for", "required", "error"] }] });
1794
+ }
1795
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdFormFieldComponent, decorators: [{
1796
+ type: Component,
1797
+ args: [{ selector: 'ad-form-field', standalone: true, imports: [CommonModule, AdLabelComponent], template: "<div class=\"ad-form-field\" [class.has-error]=\"hasError()\">\r\n @if (label()) {\r\n <ad-label [text]=\"label()\" [for]=\"forAttr()\" [required]=\"required()\" [error]=\"hasError()\">\r\n </ad-label>\r\n }\r\n\r\n <div class=\"ad-form-field-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n @if (hint() || errorMessage()) {\r\n <div class=\"ad-form-field-info\">\r\n @if (errorMessage()) {\r\n <span class=\"ad-form-field-error\">{{ errorMessage() }}</span>\r\n }\r\n @if (hint() && !errorMessage()) {\r\n <span class=\"ad-form-field-hint\">{{ hint() }}</span>\r\n }\r\n </div>\r\n }\r\n</div>", styles: [".ad-form-field{display:flex;flex-direction:column;margin-bottom:var(--form-field-margin-bottom);width:100%}.ad-form-field .ad-form-field-content{position:relative;display:flex;flex-direction:column}.ad-form-field .ad-form-field-info{margin-top:var(--form-field-message-margin);min-height:1.25rem}.ad-form-field .ad-form-field-error{color:var(--form-field-error-color);font-size:var(--form-field-message-font-size);font-weight:var(--font-weight-medium);display:block;animation:fadeIn .2s ease-out}.ad-form-field .ad-form-field-hint{color:var(--form-field-message-color);font-size:var(--form-field-message-font-size);display:block}@keyframes fadeIn{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
1798
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }] } });
1799
+
1800
+ const FormFieldResourceSchema = z.object({
1801
+ label: z.string().optional(),
1802
+ hint: z.string().optional(),
1803
+ errorMessage: z.string().nullable().optional(),
1804
+ required: z.boolean().default(false).optional(),
1805
+ error: z.boolean().default(false).optional(),
1806
+ for: z.string().optional()
1807
+ });
1808
+
1809
+ const ModalTriggerResourceSchema = z.object({
1810
+ resource: z.any(), // Assuming ScreenResource for now
1811
+ data: z.any().optional(),
1812
+ triggerLabel: z.string(),
1813
+ triggerIcon: z.string().optional(),
1814
+ loading: z.boolean().default(false).optional(),
1815
+ variant: z.enum(['primary', 'secondary', 'ghost', 'outline', 'danger']).default('primary').optional(),
1816
+ disabled: z.boolean().default(false).optional()
1817
+ });
1818
+
1819
+ class AdSearchBarComponent {
1820
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
1821
+ placeholder = computed(() => this.resource().placeholder || 'Buscar...', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
1822
+ debounce = computed(() => this.resource().debounce ?? 300, ...(ngDevMode ? [{ debugName: "debounce" }] : []));
1823
+ loading = computed(() => this.resource().loading || false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1824
+ variant = computed(() => this.resource().variant || 'standalone', ...(ngDevMode ? [{ debugName: "variant" }] : []));
1825
+ search = output();
1826
+ searchQuery = '';
1827
+ searchSubject = new Subject();
1828
+ subscription = new Subscription();
305
1829
  ngOnInit() {
306
1830
  this.subscription = this.searchSubject
307
- .pipe(debounceTime(this.debounce), distinctUntilChanged())
1831
+ .pipe(debounceTime(this.debounce()), distinctUntilChanged())
308
1832
  .subscribe(query => {
309
1833
  this.search.emit(query);
310
1834
  });
@@ -319,138 +1843,82 @@ class CcSearchBarComponent {
319
1843
  ngOnDestroy() {
320
1844
  this.subscription.unsubscribe();
321
1845
  }
322
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcSearchBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
323
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcSearchBarComponent, isStandalone: true, selector: "cc-search-bar", inputs: { placeholder: "placeholder", debounce: "debounce", loading: "loading", variant: "variant" }, outputs: { search: "search" }, ngImport: i0, template: "<div class=\"cc-search-bar\" [ngClass]=\"variant\">\r\n <div class=\"cc-search-icon-wrapper\">\r\n <cc-icon name=\"search\" size=\"sm\" *ngIf=\"!loading\"></cc-icon>\r\n <div class=\"cc-search-loader\" *ngIf=\"loading\"></div>\r\n </div>\r\n\r\n <input type=\"text\" class=\"cc-search-input\" [placeholder]=\"placeholder\" [(ngModel)]=\"searchQuery\"\r\n (ngModelChange)=\"onQueryChange()\">\r\n\r\n <button class=\"cc-search-clear\" *ngIf=\"searchQuery && !loading\" (click)=\"clear()\" type=\"button\">\r\n <cc-icon name=\"close\" size=\"xs\"></cc-icon>\r\n </button>\r\n</div>", styles: [".cc-search-bar{display:flex;align-items:center;gap:var(--space-2);height:var(--input-height-md);padding:0 var(--space-3);border-radius:var(--radius-md);transition:all .15s ease-in-out;width:100%}.cc-search-bar.standalone{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);box-shadow:var(--shadow-sm)}.cc-search-bar.standalone:focus-within{border-color:var(--color-brand-primary);box-shadow:var(--shadow-focus)}.cc-search-bar.header{background-color:#ffffff1a;border:1px solid rgba(255,255,255,.2);color:#fff}.cc-search-bar.header .cc-search-input{color:#fff}.cc-search-bar.header .cc-search-input::placeholder{color:#fff9}.cc-search-bar.header .cc-search-icon-wrapper{color:#fffc}.cc-search-icon-wrapper{display:flex;color:var(--color-text-muted)}.cc-search-input{flex:1;border:none;background:transparent;font-size:var(--font-size-md);color:var(--color-text-primary);outline:none;padding:0}.cc-search-input::placeholder{color:var(--color-text-muted)}.cc-search-clear{display:flex;background:transparent;border:none;color:var(--color-text-muted);cursor:pointer;padding:var(--space-1);border-radius:var(--radius-full);transition:background-color .15s ease}.cc-search-clear:hover{background-color:var(--color-bg-secondary);color:var(--color-text-primary)}.cc-search-loader{width:18px;height:18px;border:2px solid currentColor;border-top-color:transparent;border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CcIconComponent, selector: "cc-icon", inputs: ["name", "size", "color"] }] }); }
1846
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdSearchBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1847
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdSearchBarComponent, isStandalone: true, selector: "ad-search-bar", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { search: "search" }, ngImport: i0, template: "<div class=\"ad-search-bar\" [ngClass]=\"variant()\">\r\n <div class=\"ad-search-icon-wrapper\">\r\n @if (!loading()) {\r\n <ad-icon name=\"search\" size=\"sm\"></ad-icon>\r\n }\r\n @if (loading()) {\r\n <div class=\"ad-search-loader\"></div>\r\n }\r\n </div>\r\n\r\n <input type=\"text\" class=\"ad-search-input\" [placeholder]=\"placeholder()\" [(ngModel)]=\"searchQuery\"\r\n (ngModelChange)=\"onQueryChange()\">\r\n\r\n @if (searchQuery && !loading()) {\r\n <button class=\"ad-search-clear\" (click)=\"clear()\" type=\"button\">\r\n <ad-icon name=\"close\" size=\"xs\"></ad-icon>\r\n </button>\r\n }\r\n</div>", styles: [".ad-search-bar{display:flex;align-items:center;gap:var(--space-2);height:var(--input-height-md);padding:0 var(--space-3);border-radius:var(--radius-md);transition:all .15s ease-in-out;width:100%}.ad-search-bar.standalone{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);box-shadow:var(--shadow-sm)}.ad-search-bar.standalone:focus-within{border-color:var(--color-brand-primary);box-shadow:var(--shadow-focus)}.ad-search-bar.header{background-color:#ffffff1a;border:1px solid rgba(255,255,255,.2);color:#fff}.ad-search-bar.header .ad-search-input{color:#fff}.ad-search-bar.header .ad-search-input::placeholder{color:#fff9}.ad-search-bar.header .ad-search-icon-wrapper{color:#fffc}.ad-search-icon-wrapper{display:flex;color:var(--color-text-muted)}.ad-search-input{flex:1;border:none;background:transparent;font-size:var(--font-size-md);color:var(--color-text-primary);outline:none;padding:0}.ad-search-input::placeholder{color:var(--color-text-muted)}.ad-search-clear{display:flex;background:transparent;border:none;color:var(--color-text-muted);cursor:pointer;padding:var(--space-1);border-radius:var(--radius-full);transition:background-color .15s ease}.ad-search-clear:hover{background-color:var(--color-bg-secondary);color:var(--color-text-primary)}.ad-search-loader{width:18px;height:18px;border:2px solid currentColor;border-top-color:transparent;border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: AdIconComponent, selector: "ad-icon", inputs: ["name", "size", "color"] }] });
324
1848
  }
325
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcSearchBarComponent, decorators: [{
1849
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdSearchBarComponent, decorators: [{
326
1850
  type: Component,
327
- args: [{ selector: 'cc-search-bar', standalone: true, imports: [CommonModule, FormsModule, CcIconComponent], template: "<div class=\"cc-search-bar\" [ngClass]=\"variant\">\r\n <div class=\"cc-search-icon-wrapper\">\r\n <cc-icon name=\"search\" size=\"sm\" *ngIf=\"!loading\"></cc-icon>\r\n <div class=\"cc-search-loader\" *ngIf=\"loading\"></div>\r\n </div>\r\n\r\n <input type=\"text\" class=\"cc-search-input\" [placeholder]=\"placeholder\" [(ngModel)]=\"searchQuery\"\r\n (ngModelChange)=\"onQueryChange()\">\r\n\r\n <button class=\"cc-search-clear\" *ngIf=\"searchQuery && !loading\" (click)=\"clear()\" type=\"button\">\r\n <cc-icon name=\"close\" size=\"xs\"></cc-icon>\r\n </button>\r\n</div>", styles: [".cc-search-bar{display:flex;align-items:center;gap:var(--space-2);height:var(--input-height-md);padding:0 var(--space-3);border-radius:var(--radius-md);transition:all .15s ease-in-out;width:100%}.cc-search-bar.standalone{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);box-shadow:var(--shadow-sm)}.cc-search-bar.standalone:focus-within{border-color:var(--color-brand-primary);box-shadow:var(--shadow-focus)}.cc-search-bar.header{background-color:#ffffff1a;border:1px solid rgba(255,255,255,.2);color:#fff}.cc-search-bar.header .cc-search-input{color:#fff}.cc-search-bar.header .cc-search-input::placeholder{color:#fff9}.cc-search-bar.header .cc-search-icon-wrapper{color:#fffc}.cc-search-icon-wrapper{display:flex;color:var(--color-text-muted)}.cc-search-input{flex:1;border:none;background:transparent;font-size:var(--font-size-md);color:var(--color-text-primary);outline:none;padding:0}.cc-search-input::placeholder{color:var(--color-text-muted)}.cc-search-clear{display:flex;background:transparent;border:none;color:var(--color-text-muted);cursor:pointer;padding:var(--space-1);border-radius:var(--radius-full);transition:background-color .15s ease}.cc-search-clear:hover{background-color:var(--color-bg-secondary);color:var(--color-text-primary)}.cc-search-loader{width:18px;height:18px;border:2px solid currentColor;border-top-color:transparent;border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}\n"] }]
328
- }], propDecorators: { placeholder: [{
329
- type: Input
330
- }], debounce: [{
331
- type: Input
332
- }], loading: [{
333
- type: Input
334
- }], variant: [{
335
- type: Input
336
- }], search: [{
337
- type: Output
338
- }] } });
1851
+ args: [{ selector: 'ad-search-bar', standalone: true, imports: [CommonModule, FormsModule, AdIconComponent], template: "<div class=\"ad-search-bar\" [ngClass]=\"variant()\">\r\n <div class=\"ad-search-icon-wrapper\">\r\n @if (!loading()) {\r\n <ad-icon name=\"search\" size=\"sm\"></ad-icon>\r\n }\r\n @if (loading()) {\r\n <div class=\"ad-search-loader\"></div>\r\n }\r\n </div>\r\n\r\n <input type=\"text\" class=\"ad-search-input\" [placeholder]=\"placeholder()\" [(ngModel)]=\"searchQuery\"\r\n (ngModelChange)=\"onQueryChange()\">\r\n\r\n @if (searchQuery && !loading()) {\r\n <button class=\"ad-search-clear\" (click)=\"clear()\" type=\"button\">\r\n <ad-icon name=\"close\" size=\"xs\"></ad-icon>\r\n </button>\r\n }\r\n</div>", styles: [".ad-search-bar{display:flex;align-items:center;gap:var(--space-2);height:var(--input-height-md);padding:0 var(--space-3);border-radius:var(--radius-md);transition:all .15s ease-in-out;width:100%}.ad-search-bar.standalone{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);box-shadow:var(--shadow-sm)}.ad-search-bar.standalone:focus-within{border-color:var(--color-brand-primary);box-shadow:var(--shadow-focus)}.ad-search-bar.header{background-color:#ffffff1a;border:1px solid rgba(255,255,255,.2);color:#fff}.ad-search-bar.header .ad-search-input{color:#fff}.ad-search-bar.header .ad-search-input::placeholder{color:#fff9}.ad-search-bar.header .ad-search-icon-wrapper{color:#fffc}.ad-search-icon-wrapper{display:flex;color:var(--color-text-muted)}.ad-search-input{flex:1;border:none;background:transparent;font-size:var(--font-size-md);color:var(--color-text-primary);outline:none;padding:0}.ad-search-input::placeholder{color:var(--color-text-muted)}.ad-search-clear{display:flex;background:transparent;border:none;color:var(--color-text-muted);cursor:pointer;padding:var(--space-1);border-radius:var(--radius-full);transition:background-color .15s ease}.ad-search-clear:hover{background-color:var(--color-bg-secondary);color:var(--color-text-primary)}.ad-search-loader{width:18px;height:18px;border:2px solid currentColor;border-top-color:transparent;border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}\n"] }]
1852
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], search: [{ type: i0.Output, args: ["search"] }] } });
339
1853
 
340
- class CcHeaderComponent {
341
- constructor() {
342
- this.notificationsCount = 0;
343
- this.showMenuButton = true;
344
- this.hasLogoContent = true; // Added missing property
345
- this.toggleSidebar = new EventEmitter();
346
- this.userClick = new EventEmitter();
347
- this.notificationClick = new EventEmitter();
348
- this.userAction = new EventEmitter();
349
- }
350
- onUserClick() {
351
- this.userClick.emit();
352
- this.userAction.emit('profile');
353
- }
354
- get initials() {
355
- if (!this.user?.name)
356
- return '?';
357
- return this.user.name
358
- .split(' ')
359
- .map(n => n[0])
360
- .join('')
361
- .toUpperCase()
362
- .slice(0, 2);
363
- }
364
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
365
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcHeaderComponent, isStandalone: true, selector: "cc-header", inputs: { user: "user", notificationsCount: "notificationsCount", showMenuButton: "showMenuButton", hasLogoContent: "hasLogoContent" }, outputs: { toggleSidebar: "toggleSidebar", userClick: "userClick", notificationClick: "notificationClick", userAction: "userAction" }, ngImport: i0, template: "<header class=\"cc-header\">\r\n <div class=\"cc-header-left\">\r\n <button *ngIf=\"showMenuButton\" class=\"cc-header-menu-btn\" (click)=\"toggleSidebar.emit()\" type=\"button\">\r\n <cc-icon name=\"menu\" size=\"md\"></cc-icon>\r\n </button>\r\n\r\n <div class=\"cc-header-logo\">\r\n <ng-content select=\"[logo]\"></ng-content>\r\n <span class=\"cc-header-logo-fallback\" *ngIf=\"!hasLogoContent\">\r\n CERCA\r\n </span>\r\n </div>\r\n\r\n <div class=\"cc-header-breadcrumb\">\r\n <ng-content select=\"[breadcrumb]\"></ng-content>\r\n </div>\r\n </div>\r\n\r\n <div class=\"cc-header-right\">\r\n <button class=\"cc-header-action-btn\" (click)=\"notificationClick.emit()\">\r\n <cc-icon name=\"notifications\" size=\"md\"></cc-icon>\r\n <cc-badge *ngIf=\"notificationsCount > 0\" variant=\"error\" type=\"filled\" class=\"cc-header-badge\">\r\n {{ notificationsCount > 99 ? '99+' : notificationsCount }}\r\n </cc-badge>\r\n </button>\r\n\r\n <div class=\"cc-header-divider\"></div>\r\n\r\n <div class=\"cc-header-user\" (click)=\"onUserClick()\" *ngIf=\"user\">\r\n <div class=\"cc-header-user-info\">\r\n <span class=\"cc-header-user-name\">{{ user.name }}</span>\r\n <span class=\"cc-header-user-role\">{{ user.role }}</span>\r\n </div>\r\n\r\n <div class=\"cc-header-avatar\">\r\n <img *ngIf=\"user.avatarUrl\" [src]=\"user.avatarUrl\" [alt]=\"user.name\">\r\n <span *ngIf=\"!user.avatarUrl\">{{ initials }}</span>\r\n </div>\r\n\r\n <cc-icon name=\"expand_more\" size=\"sm\" class=\"cc-header-user-arrow\"></cc-icon>\r\n </div>\r\n </div>\r\n</header>", styles: [":root,[data-theme=light]{--color-bg-primary: #FFFFFF;--color-bg-secondary: #FAFAF9;--color-text-primary: #1C1917;--color-text-secondary: #57534E;--color-text-muted: #A8A29E;--color-border-subtle: #E7E5E4;--color-border-strong: #D6D3D1;--color-brand: #0284C7;--color-brand-hover: #0369A1;--color-focus-ring: rgba(2, 132, 199, .2);--color-success: #10B981;--color-danger: #F43F5E;--surface-glass-bg: rgba(255, 255, 255, .7);--surface-glass-border: rgba(255, 255, 255, .3);--surface-glass-blur: 12px;--surface-glass-shadow: 0 4px 6px -1px rgba(0, 0, 0, .1);--font-heading-xl: 32px;--font-heading-lg: 24px;--font-heading-md: 20px;--font-body-lg: 18px;--font-body-md: 16px;--font-caption: 12px;--font-family-base: Inter, sans-serif;--font-weight-regular: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--radius-sm: 6px;--radius-md: 8px;--radius-lg: 14px;--radius-xl: 18px;--radius-full: 9999px;--font-size-xs: 12px;--font-size-sm: 14px;--font-size-md: 16px;--font-size-lg: 18px;--font-size-xl: 20px;--font-size-2xl: 24px;--font-size-3xl: 32px;--space-1: 4px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-6: 24px;--space-8: calc(var(--space-4) * 2);--shadow-sm: 0 1px 2px rgba(0, 0, 0, .06);--shadow-md: 0 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0 12px 32px rgba(0, 0, 0, .12)}[data-theme=dark]{--color-bg-primary: #1C1917;--color-bg-secondary: #292524;--color-text-primary: #FFFFFF;--color-text-secondary: #A8A29E;--color-text-muted: #78716C;--color-border-subtle: #44403C;--color-border-strong: #57534E;--color-brand: #0EA5E9;--color-brand-hover: #7DD3FC;--color-focus-ring: rgba(59, 130, 246, .5);--surface-glass-bg: rgba(15, 23, 42, .8);--surface-glass-border: rgba(255, 255, 255, .1);--surface-glass-blur: 16px;--surface-glass-shadow: 0 10px 15px -3px rgba(0, 0, 0, .3)}:root{--h1-size: var(--font-size-h1);--h1-weight: var(--font-weight-semibold);--h2-size: var(--font-size-h2);--h2-weight: var(--font-weight-semibold);--h3-size: var(--font-size-h3);--h3-weight: var(--font-weight-semibold);--body-size: var(--font-size-body);--body-weight: var(--font-weight-regular);--sm-size: var(--font-size-sm);--sm-weight: var(--font-weight-regular);--caption-size: var(--font-size-caption);--caption-weight: var(--font-weight-regular)}:root{--btn-height-md: 44px;--btn-radius: var(--radius-md);--btn-font-weight: var(--font-weight-medium);--btn-bg-primary: var(--color-brand);--btn-text-primary: #FFFFFF;--btn-shadow-default: var(--shadow-sm);--btn-shadow-hover: var(--shadow-md);--btn-transition: .15s ease;--btn-focus-ring: 0 0 0 2px var(--color-focus-ring)}:root{--card-bg: var(--color-bg-primary);--card-radius: var(--radius-lg);--card-shadow: var(--shadow-sm);--card-shadow-hover: var(--shadow-md)}:root{--input-height-md: 44px;--input-bg: var(--color-bg-primary);--input-radius: var(--radius-md);--input-border-default: var(--color-border-subtle);--input-border-hover: var(--color-border-strong);--input-border-focus: var(--color-brand);--input-border-error: var(--color-danger);--input-transition: .12s ease-in-out;--input-focus-ring: 0 0 0 3px var(--color-focus-ring);--input-error-ring: 0 0 0 3px rgba(239, 68, 68, .15)}.cc-badge-tokens{--badge-radius: var(--radius-sm);--badge-padding-v: var(--space-1);--badge-padding-h: var(--space-2);--badge-font-size: var(--font-size-xs);--badge-font-weight: var(--font-weight-medium);--badge-success-bg: #D1FAE5;--badge-success-text: #065F46;--badge-success-border: #A7F3D0;--badge-warning-bg: #FEF3C7;--badge-warning-text: #92400E;--badge-warning-border: #FDE68A;--badge-error-bg: #FFE4E6;--badge-error-text: #9F1239;--badge-error-border: #FECDD3;--badge-info-bg: var(--color-info-50);--badge-info-text: var(--color-info-700);--badge-info-border: var(--color-info-200);--badge-neutral-bg: #F5F5F4;--badge-neutral-text: #44403C;--badge-neutral-border: #E7E5E4}.cc-label-tokens{--label-font-size: var(--font-size-sm);--label-font-weight: var(--font-weight-medium);--label-color: var(--color-text-secondary);--label-required-color: var(--color-error-500);--label-margin-bottom: var(--space-2)}.cc-select-tokens{--select-bg: var(--color-bg-primary);--select-border: var(--color-border-subtle);--select-border-hover: var(--color-border-strong);--select-border-focus: var(--color-brand-primary);--select-shadow-focus: var(--shadow-focus);--select-radius: var(--radius-md);--select-height: 44px;--select-padding-h: var(--space-4);--select-dropdown-bg: var(--color-bg-primary);--select-dropdown-shadow: var(--shadow-md);--select-dropdown-max-height: 240px;--select-option-padding: var(--space-3) var(--space-4);--select-option-hover: var(--color-bg-secondary);--select-option-selected-bg: var(--color-brand-50);--select-option-selected-text: var(--color-brand-primary)}.cc-form-field-tokens{--form-field-margin-bottom: var(--space-6);--form-field-label-margin: var(--space-2);--form-field-message-margin: var(--space-1);--form-field-message-font-size: var(--font-size-xs);--form-field-message-color: var(--color-text-muted);--form-field-error-color: var(--color-error-600)}.cc-header-tokens{--header-height: 72px;--header-bg: #FFFFFF;--header-border-color: #F5F5F4;--header-padding: 0 var(--space-6);--header-shadow: 0 1px 2px rgba(0, 0, 0, .05);--header-z-index: 100;--header-logo-height: 32px;--header-user-gap: var(--space-4)}.cc-sidebar-tokens{--sidebar-width: 280px;--sidebar-collapsed-width: 80px;--sidebar-bg: #1C1917;--sidebar-border-color: #292524;--sidebar-padding: var(--space-4);--sidebar-z-index: 101;--sidebar-transition: width .3s cubic-bezier(.4, 0, .2, 1);--sidebar-item-height: 48px;--sidebar-item-radius: var(--radius-lg);--sidebar-item-padding: 0 var(--space-4);--sidebar-item-gap: var(--space-3);--sidebar-accent-color: #0EA5E9;--sidebar-text-color: #FFFFFF;--sidebar-text-muted: #A8A29E}.cc-data-table-tokens{--table-bg: var(--color-bg-primary);--table-header-bg: var(--color-bg-secondary);--table-border-color: var(--color-border-subtle);--table-header-color: var(--color-text-muted);--table-row-hover: rgba(var(--color-brand-primary-rgb), .04);--table-cell-padding: var(--space-4);--table-font-size: var(--font-size-sm);--table-radius: var(--radius-lg)}.cc-modal-tokens{--modal-bg: var(--color-bg-primary);--modal-overlay-bg: rgba(0, 0, 0, .5);--modal-radius: var(--radius-xl);--modal-shadow: var(--shadow-xl);--modal-z-index: 1000;--modal-header-padding: var(--space-6);--modal-body-padding: var(--space-6);--modal-footer-padding: var(--space-4) var(--space-6);--modal-sm-width: 400px;--modal-md-width: 600px;--modal-lg-width: 900px}.cc-header{height:var(--header-height);background:var(--surface-glass-bg);backdrop-filter:blur(var(--surface-glass-blur));-webkit-backdrop-filter:blur(var(--surface-glass-blur));border-bottom:1px solid var(--surface-glass-border);padding:var(--header-padding);display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100;box-shadow:var(--surface-glass-shadow);transition:all .3s ease}.cc-header-left,.cc-header-right{display:flex;align-items:center;gap:var(--space-4)}.cc-header-menu-btn{background:transparent;border:none;color:var(--color-text-primary);cursor:pointer;padding:var(--space-2);border-radius:var(--radius-md);display:flex;transition:background-color .15s ease}.cc-header-menu-btn:hover{background-color:var(--color-bg-secondary)}@media(min-width:1024px){.cc-header-menu-btn{display:none}}.cc-header-logo{display:flex;align-items:center;height:var(--header-logo-height)}.cc-header-logo .cc-header-logo-fallback{font-weight:var(--font-weight-bold);font-size:var(--font-size-xl);letter-spacing:-.025em;color:var(--color-brand-primary)}.cc-header-action-btn{position:relative;background:transparent;border:none;color:var(--color-text-muted);cursor:pointer;padding:var(--space-2);border-radius:var(--radius-full);display:flex;transition:all .15s ease}.cc-header-action-btn:hover{background-color:var(--color-bg-secondary);color:var(--color-text-primary)}.cc-header-action-btn .cc-header-badge{position:absolute;top:4px;right:4px;font-size:10px;padding:2px 4px;min-width:16px;height:16px;display:flex;align-items:center;justify-content:center}.cc-header-divider{width:1px;height:24px;background-color:var(--color-border-subtle);margin:0 var(--space-2)}.cc-header-user{display:flex;align-items:center;gap:var(--space-3);cursor:pointer;padding:var(--space-1) var(--space-2);border-radius:var(--radius-lg);transition:background-color .15s ease}.cc-header-user:hover{background-color:var(--color-bg-secondary)}.cc-header-user-info{display:none;flex-direction:column;text-align:right}@media(min-width:768px){.cc-header-user-info{display:flex}}.cc-header-user-info .cc-header-user-name{font-size:var(--font-size-sm);font-weight:var(--font-weight-semibold);color:var(--color-text-primary);line-height:1.2}.cc-header-user-info .cc-header-user-role{font-size:var(--font-size-xs);color:var(--color-text-muted)}.cc-header-avatar{width:36px;height:36px;border-radius:var(--radius-full);background:#0ea5e9;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:var(--font-weight-bold);font-size:var(--font-size-sm);overflow:hidden;box-shadow:0 0 0 2px var(--header-bg),0 0 0 4px var(--color-border-subtle)}.cc-header-avatar img{width:100%;height:100%;object-fit:cover}.cc-header-user-arrow{color:var(--color-text-muted)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CcIconComponent, selector: "cc-icon", inputs: ["name", "size", "color"] }, { kind: "component", type: CcBadgeComponent, selector: "cc-badge", inputs: ["variant", "type"] }] }); }
366
- }
367
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcHeaderComponent, decorators: [{
368
- type: Component,
369
- args: [{ selector: 'cc-header', standalone: true, imports: [CommonModule, CcIconComponent, CcBadgeComponent], template: "<header class=\"cc-header\">\r\n <div class=\"cc-header-left\">\r\n <button *ngIf=\"showMenuButton\" class=\"cc-header-menu-btn\" (click)=\"toggleSidebar.emit()\" type=\"button\">\r\n <cc-icon name=\"menu\" size=\"md\"></cc-icon>\r\n </button>\r\n\r\n <div class=\"cc-header-logo\">\r\n <ng-content select=\"[logo]\"></ng-content>\r\n <span class=\"cc-header-logo-fallback\" *ngIf=\"!hasLogoContent\">\r\n CERCA\r\n </span>\r\n </div>\r\n\r\n <div class=\"cc-header-breadcrumb\">\r\n <ng-content select=\"[breadcrumb]\"></ng-content>\r\n </div>\r\n </div>\r\n\r\n <div class=\"cc-header-right\">\r\n <button class=\"cc-header-action-btn\" (click)=\"notificationClick.emit()\">\r\n <cc-icon name=\"notifications\" size=\"md\"></cc-icon>\r\n <cc-badge *ngIf=\"notificationsCount > 0\" variant=\"error\" type=\"filled\" class=\"cc-header-badge\">\r\n {{ notificationsCount > 99 ? '99+' : notificationsCount }}\r\n </cc-badge>\r\n </button>\r\n\r\n <div class=\"cc-header-divider\"></div>\r\n\r\n <div class=\"cc-header-user\" (click)=\"onUserClick()\" *ngIf=\"user\">\r\n <div class=\"cc-header-user-info\">\r\n <span class=\"cc-header-user-name\">{{ user.name }}</span>\r\n <span class=\"cc-header-user-role\">{{ user.role }}</span>\r\n </div>\r\n\r\n <div class=\"cc-header-avatar\">\r\n <img *ngIf=\"user.avatarUrl\" [src]=\"user.avatarUrl\" [alt]=\"user.name\">\r\n <span *ngIf=\"!user.avatarUrl\">{{ initials }}</span>\r\n </div>\r\n\r\n <cc-icon name=\"expand_more\" size=\"sm\" class=\"cc-header-user-arrow\"></cc-icon>\r\n </div>\r\n </div>\r\n</header>", styles: [":root,[data-theme=light]{--color-bg-primary: #FFFFFF;--color-bg-secondary: #FAFAF9;--color-text-primary: #1C1917;--color-text-secondary: #57534E;--color-text-muted: #A8A29E;--color-border-subtle: #E7E5E4;--color-border-strong: #D6D3D1;--color-brand: #0284C7;--color-brand-hover: #0369A1;--color-focus-ring: rgba(2, 132, 199, .2);--color-success: #10B981;--color-danger: #F43F5E;--surface-glass-bg: rgba(255, 255, 255, .7);--surface-glass-border: rgba(255, 255, 255, .3);--surface-glass-blur: 12px;--surface-glass-shadow: 0 4px 6px -1px rgba(0, 0, 0, .1);--font-heading-xl: 32px;--font-heading-lg: 24px;--font-heading-md: 20px;--font-body-lg: 18px;--font-body-md: 16px;--font-caption: 12px;--font-family-base: Inter, sans-serif;--font-weight-regular: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--radius-sm: 6px;--radius-md: 8px;--radius-lg: 14px;--radius-xl: 18px;--radius-full: 9999px;--font-size-xs: 12px;--font-size-sm: 14px;--font-size-md: 16px;--font-size-lg: 18px;--font-size-xl: 20px;--font-size-2xl: 24px;--font-size-3xl: 32px;--space-1: 4px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-6: 24px;--space-8: calc(var(--space-4) * 2);--shadow-sm: 0 1px 2px rgba(0, 0, 0, .06);--shadow-md: 0 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0 12px 32px rgba(0, 0, 0, .12)}[data-theme=dark]{--color-bg-primary: #1C1917;--color-bg-secondary: #292524;--color-text-primary: #FFFFFF;--color-text-secondary: #A8A29E;--color-text-muted: #78716C;--color-border-subtle: #44403C;--color-border-strong: #57534E;--color-brand: #0EA5E9;--color-brand-hover: #7DD3FC;--color-focus-ring: rgba(59, 130, 246, .5);--surface-glass-bg: rgba(15, 23, 42, .8);--surface-glass-border: rgba(255, 255, 255, .1);--surface-glass-blur: 16px;--surface-glass-shadow: 0 10px 15px -3px rgba(0, 0, 0, .3)}:root{--h1-size: var(--font-size-h1);--h1-weight: var(--font-weight-semibold);--h2-size: var(--font-size-h2);--h2-weight: var(--font-weight-semibold);--h3-size: var(--font-size-h3);--h3-weight: var(--font-weight-semibold);--body-size: var(--font-size-body);--body-weight: var(--font-weight-regular);--sm-size: var(--font-size-sm);--sm-weight: var(--font-weight-regular);--caption-size: var(--font-size-caption);--caption-weight: var(--font-weight-regular)}:root{--btn-height-md: 44px;--btn-radius: var(--radius-md);--btn-font-weight: var(--font-weight-medium);--btn-bg-primary: var(--color-brand);--btn-text-primary: #FFFFFF;--btn-shadow-default: var(--shadow-sm);--btn-shadow-hover: var(--shadow-md);--btn-transition: .15s ease;--btn-focus-ring: 0 0 0 2px var(--color-focus-ring)}:root{--card-bg: var(--color-bg-primary);--card-radius: var(--radius-lg);--card-shadow: var(--shadow-sm);--card-shadow-hover: var(--shadow-md)}:root{--input-height-md: 44px;--input-bg: var(--color-bg-primary);--input-radius: var(--radius-md);--input-border-default: var(--color-border-subtle);--input-border-hover: var(--color-border-strong);--input-border-focus: var(--color-brand);--input-border-error: var(--color-danger);--input-transition: .12s ease-in-out;--input-focus-ring: 0 0 0 3px var(--color-focus-ring);--input-error-ring: 0 0 0 3px rgba(239, 68, 68, .15)}.cc-badge-tokens{--badge-radius: var(--radius-sm);--badge-padding-v: var(--space-1);--badge-padding-h: var(--space-2);--badge-font-size: var(--font-size-xs);--badge-font-weight: var(--font-weight-medium);--badge-success-bg: #D1FAE5;--badge-success-text: #065F46;--badge-success-border: #A7F3D0;--badge-warning-bg: #FEF3C7;--badge-warning-text: #92400E;--badge-warning-border: #FDE68A;--badge-error-bg: #FFE4E6;--badge-error-text: #9F1239;--badge-error-border: #FECDD3;--badge-info-bg: var(--color-info-50);--badge-info-text: var(--color-info-700);--badge-info-border: var(--color-info-200);--badge-neutral-bg: #F5F5F4;--badge-neutral-text: #44403C;--badge-neutral-border: #E7E5E4}.cc-label-tokens{--label-font-size: var(--font-size-sm);--label-font-weight: var(--font-weight-medium);--label-color: var(--color-text-secondary);--label-required-color: var(--color-error-500);--label-margin-bottom: var(--space-2)}.cc-select-tokens{--select-bg: var(--color-bg-primary);--select-border: var(--color-border-subtle);--select-border-hover: var(--color-border-strong);--select-border-focus: var(--color-brand-primary);--select-shadow-focus: var(--shadow-focus);--select-radius: var(--radius-md);--select-height: 44px;--select-padding-h: var(--space-4);--select-dropdown-bg: var(--color-bg-primary);--select-dropdown-shadow: var(--shadow-md);--select-dropdown-max-height: 240px;--select-option-padding: var(--space-3) var(--space-4);--select-option-hover: var(--color-bg-secondary);--select-option-selected-bg: var(--color-brand-50);--select-option-selected-text: var(--color-brand-primary)}.cc-form-field-tokens{--form-field-margin-bottom: var(--space-6);--form-field-label-margin: var(--space-2);--form-field-message-margin: var(--space-1);--form-field-message-font-size: var(--font-size-xs);--form-field-message-color: var(--color-text-muted);--form-field-error-color: var(--color-error-600)}.cc-header-tokens{--header-height: 72px;--header-bg: #FFFFFF;--header-border-color: #F5F5F4;--header-padding: 0 var(--space-6);--header-shadow: 0 1px 2px rgba(0, 0, 0, .05);--header-z-index: 100;--header-logo-height: 32px;--header-user-gap: var(--space-4)}.cc-sidebar-tokens{--sidebar-width: 280px;--sidebar-collapsed-width: 80px;--sidebar-bg: #1C1917;--sidebar-border-color: #292524;--sidebar-padding: var(--space-4);--sidebar-z-index: 101;--sidebar-transition: width .3s cubic-bezier(.4, 0, .2, 1);--sidebar-item-height: 48px;--sidebar-item-radius: var(--radius-lg);--sidebar-item-padding: 0 var(--space-4);--sidebar-item-gap: var(--space-3);--sidebar-accent-color: #0EA5E9;--sidebar-text-color: #FFFFFF;--sidebar-text-muted: #A8A29E}.cc-data-table-tokens{--table-bg: var(--color-bg-primary);--table-header-bg: var(--color-bg-secondary);--table-border-color: var(--color-border-subtle);--table-header-color: var(--color-text-muted);--table-row-hover: rgba(var(--color-brand-primary-rgb), .04);--table-cell-padding: var(--space-4);--table-font-size: var(--font-size-sm);--table-radius: var(--radius-lg)}.cc-modal-tokens{--modal-bg: var(--color-bg-primary);--modal-overlay-bg: rgba(0, 0, 0, .5);--modal-radius: var(--radius-xl);--modal-shadow: var(--shadow-xl);--modal-z-index: 1000;--modal-header-padding: var(--space-6);--modal-body-padding: var(--space-6);--modal-footer-padding: var(--space-4) var(--space-6);--modal-sm-width: 400px;--modal-md-width: 600px;--modal-lg-width: 900px}.cc-header{height:var(--header-height);background:var(--surface-glass-bg);backdrop-filter:blur(var(--surface-glass-blur));-webkit-backdrop-filter:blur(var(--surface-glass-blur));border-bottom:1px solid var(--surface-glass-border);padding:var(--header-padding);display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100;box-shadow:var(--surface-glass-shadow);transition:all .3s ease}.cc-header-left,.cc-header-right{display:flex;align-items:center;gap:var(--space-4)}.cc-header-menu-btn{background:transparent;border:none;color:var(--color-text-primary);cursor:pointer;padding:var(--space-2);border-radius:var(--radius-md);display:flex;transition:background-color .15s ease}.cc-header-menu-btn:hover{background-color:var(--color-bg-secondary)}@media(min-width:1024px){.cc-header-menu-btn{display:none}}.cc-header-logo{display:flex;align-items:center;height:var(--header-logo-height)}.cc-header-logo .cc-header-logo-fallback{font-weight:var(--font-weight-bold);font-size:var(--font-size-xl);letter-spacing:-.025em;color:var(--color-brand-primary)}.cc-header-action-btn{position:relative;background:transparent;border:none;color:var(--color-text-muted);cursor:pointer;padding:var(--space-2);border-radius:var(--radius-full);display:flex;transition:all .15s ease}.cc-header-action-btn:hover{background-color:var(--color-bg-secondary);color:var(--color-text-primary)}.cc-header-action-btn .cc-header-badge{position:absolute;top:4px;right:4px;font-size:10px;padding:2px 4px;min-width:16px;height:16px;display:flex;align-items:center;justify-content:center}.cc-header-divider{width:1px;height:24px;background-color:var(--color-border-subtle);margin:0 var(--space-2)}.cc-header-user{display:flex;align-items:center;gap:var(--space-3);cursor:pointer;padding:var(--space-1) var(--space-2);border-radius:var(--radius-lg);transition:background-color .15s ease}.cc-header-user:hover{background-color:var(--color-bg-secondary)}.cc-header-user-info{display:none;flex-direction:column;text-align:right}@media(min-width:768px){.cc-header-user-info{display:flex}}.cc-header-user-info .cc-header-user-name{font-size:var(--font-size-sm);font-weight:var(--font-weight-semibold);color:var(--color-text-primary);line-height:1.2}.cc-header-user-info .cc-header-user-role{font-size:var(--font-size-xs);color:var(--color-text-muted)}.cc-header-avatar{width:36px;height:36px;border-radius:var(--radius-full);background:#0ea5e9;display:flex;align-items:center;justify-content:center;color:#fff;font-weight:var(--font-weight-bold);font-size:var(--font-size-sm);overflow:hidden;box-shadow:0 0 0 2px var(--header-bg),0 0 0 4px var(--color-border-subtle)}.cc-header-avatar img{width:100%;height:100%;object-fit:cover}.cc-header-user-arrow{color:var(--color-text-muted)}\n"] }]
370
- }], propDecorators: { user: [{
371
- type: Input
372
- }], notificationsCount: [{
373
- type: Input
374
- }], showMenuButton: [{
375
- type: Input
376
- }], hasLogoContent: [{
377
- type: Input
378
- }], toggleSidebar: [{
379
- type: Output
380
- }], userClick: [{
381
- type: Output
382
- }], notificationClick: [{
383
- type: Output
384
- }], userAction: [{
385
- type: Output
386
- }] } });
1854
+ const SearchBarResourceSchema = z.object({
1855
+ placeholder: z.string().default('Buscar...').optional(),
1856
+ debounce: z.number().default(300).optional(),
1857
+ loading: z.boolean().default(false).optional(),
1858
+ variant: z.enum(['standalone', 'header']).default('standalone').optional(),
1859
+ });
387
1860
 
388
- class CcSidebarComponent {
389
- constructor() {
390
- this.menuItems = [];
391
- this.collapsed = false;
392
- this.activeRoute = '';
393
- this.navigate = new EventEmitter();
394
- this.toggleCollapse = new EventEmitter();
395
- }
396
- onItemClick(item) {
397
- this.navigate.emit(item);
398
- }
399
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
400
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcSidebarComponent, isStandalone: true, selector: "cc-sidebar", inputs: { menuItems: "menuItems", collapsed: "collapsed", activeRoute: "activeRoute" }, outputs: { navigate: "navigate", toggleCollapse: "toggleCollapse" }, ngImport: i0, template: "<aside class=\"cc-sidebar\" [class.collapsed]=\"collapsed\">\r\n <div class=\"cc-sidebar-header\">\r\n <div class=\"cc-sidebar-logo\">\r\n <ng-content select=\"[logo]\"></ng-content>\r\n </div>\r\n <button class=\"cc-sidebar-toggle\" (click)=\"toggleCollapse.emit()\" type=\"button\">\r\n <cc-icon [name]=\"collapsed ? 'chevron_right' : 'chevron_left'\" size=\"sm\"></cc-icon>\r\n </button>\r\n </div>\r\n\r\n <nav class=\"cc-sidebar-nav\">\r\n <div class=\"cc-sidebar-group\" *ngFor=\"let item of menuItems\">\r\n <a class=\"cc-sidebar-item\" [routerLink]=\"item.route\" routerLinkActive=\"active\"\r\n [routerLinkActiveOptions]=\"{ exact: item.exact || false }\" [title]=\"collapsed ? item.label : ''\"\r\n (click)=\"onItemClick(item)\">\r\n\r\n <cc-icon [name]=\"item.icon\" size=\"md\" class=\"cc-sidebar-item-icon\"></cc-icon>\r\n <span class=\"cc-sidebar-item-label\" *ngIf=\"!collapsed\">{{ item.label }}</span>\r\n\r\n <span class=\"cc-sidebar-item-badge\" *ngIf=\"item.badge && !collapsed\">\r\n {{ item.badge }}\r\n </span>\r\n </a>\r\n </div>\r\n </nav>\r\n\r\n <div class=\"cc-sidebar-footer\">\r\n <ng-content select=\"[footer]\"></ng-content>\r\n </div>\r\n</aside>", styles: [":root,[data-theme=light]{--color-bg-primary: #FFFFFF;--color-bg-secondary: #FAFAF9;--color-text-primary: #1C1917;--color-text-secondary: #57534E;--color-text-muted: #A8A29E;--color-border-subtle: #E7E5E4;--color-border-strong: #D6D3D1;--color-brand: #0284C7;--color-brand-hover: #0369A1;--color-focus-ring: rgba(2, 132, 199, .2);--color-success: #10B981;--color-danger: #F43F5E;--surface-glass-bg: rgba(255, 255, 255, .7);--surface-glass-border: rgba(255, 255, 255, .3);--surface-glass-blur: 12px;--surface-glass-shadow: 0 4px 6px -1px rgba(0, 0, 0, .1);--font-heading-xl: 32px;--font-heading-lg: 24px;--font-heading-md: 20px;--font-body-lg: 18px;--font-body-md: 16px;--font-caption: 12px;--font-family-base: Inter, sans-serif;--font-weight-regular: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--radius-sm: 6px;--radius-md: 8px;--radius-lg: 14px;--radius-xl: 18px;--radius-full: 9999px;--font-size-xs: 12px;--font-size-sm: 14px;--font-size-md: 16px;--font-size-lg: 18px;--font-size-xl: 20px;--font-size-2xl: 24px;--font-size-3xl: 32px;--space-1: 4px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-6: 24px;--space-8: calc(var(--space-4) * 2);--shadow-sm: 0 1px 2px rgba(0, 0, 0, .06);--shadow-md: 0 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0 12px 32px rgba(0, 0, 0, .12)}[data-theme=dark]{--color-bg-primary: #1C1917;--color-bg-secondary: #292524;--color-text-primary: #FFFFFF;--color-text-secondary: #A8A29E;--color-text-muted: #78716C;--color-border-subtle: #44403C;--color-border-strong: #57534E;--color-brand: #0EA5E9;--color-brand-hover: #7DD3FC;--color-focus-ring: rgba(59, 130, 246, .5);--surface-glass-bg: rgba(15, 23, 42, .8);--surface-glass-border: rgba(255, 255, 255, .1);--surface-glass-blur: 16px;--surface-glass-shadow: 0 10px 15px -3px rgba(0, 0, 0, .3)}:root{--h1-size: var(--font-size-h1);--h1-weight: var(--font-weight-semibold);--h2-size: var(--font-size-h2);--h2-weight: var(--font-weight-semibold);--h3-size: var(--font-size-h3);--h3-weight: var(--font-weight-semibold);--body-size: var(--font-size-body);--body-weight: var(--font-weight-regular);--sm-size: var(--font-size-sm);--sm-weight: var(--font-weight-regular);--caption-size: var(--font-size-caption);--caption-weight: var(--font-weight-regular)}:root{--btn-height-md: 44px;--btn-radius: var(--radius-md);--btn-font-weight: var(--font-weight-medium);--btn-bg-primary: var(--color-brand);--btn-text-primary: #FFFFFF;--btn-shadow-default: var(--shadow-sm);--btn-shadow-hover: var(--shadow-md);--btn-transition: .15s ease;--btn-focus-ring: 0 0 0 2px var(--color-focus-ring)}:root{--card-bg: var(--color-bg-primary);--card-radius: var(--radius-lg);--card-shadow: var(--shadow-sm);--card-shadow-hover: var(--shadow-md)}:root{--input-height-md: 44px;--input-bg: var(--color-bg-primary);--input-radius: var(--radius-md);--input-border-default: var(--color-border-subtle);--input-border-hover: var(--color-border-strong);--input-border-focus: var(--color-brand);--input-border-error: var(--color-danger);--input-transition: .12s ease-in-out;--input-focus-ring: 0 0 0 3px var(--color-focus-ring);--input-error-ring: 0 0 0 3px rgba(239, 68, 68, .15)}.cc-badge-tokens{--badge-radius: var(--radius-sm);--badge-padding-v: var(--space-1);--badge-padding-h: var(--space-2);--badge-font-size: var(--font-size-xs);--badge-font-weight: var(--font-weight-medium);--badge-success-bg: #D1FAE5;--badge-success-text: #065F46;--badge-success-border: #A7F3D0;--badge-warning-bg: #FEF3C7;--badge-warning-text: #92400E;--badge-warning-border: #FDE68A;--badge-error-bg: #FFE4E6;--badge-error-text: #9F1239;--badge-error-border: #FECDD3;--badge-info-bg: var(--color-info-50);--badge-info-text: var(--color-info-700);--badge-info-border: var(--color-info-200);--badge-neutral-bg: #F5F5F4;--badge-neutral-text: #44403C;--badge-neutral-border: #E7E5E4}.cc-label-tokens{--label-font-size: var(--font-size-sm);--label-font-weight: var(--font-weight-medium);--label-color: var(--color-text-secondary);--label-required-color: var(--color-error-500);--label-margin-bottom: var(--space-2)}.cc-select-tokens{--select-bg: var(--color-bg-primary);--select-border: var(--color-border-subtle);--select-border-hover: var(--color-border-strong);--select-border-focus: var(--color-brand-primary);--select-shadow-focus: var(--shadow-focus);--select-radius: var(--radius-md);--select-height: 44px;--select-padding-h: var(--space-4);--select-dropdown-bg: var(--color-bg-primary);--select-dropdown-shadow: var(--shadow-md);--select-dropdown-max-height: 240px;--select-option-padding: var(--space-3) var(--space-4);--select-option-hover: var(--color-bg-secondary);--select-option-selected-bg: var(--color-brand-50);--select-option-selected-text: var(--color-brand-primary)}.cc-form-field-tokens{--form-field-margin-bottom: var(--space-6);--form-field-label-margin: var(--space-2);--form-field-message-margin: var(--space-1);--form-field-message-font-size: var(--font-size-xs);--form-field-message-color: var(--color-text-muted);--form-field-error-color: var(--color-error-600)}.cc-header-tokens{--header-height: 72px;--header-bg: #FFFFFF;--header-border-color: #F5F5F4;--header-padding: 0 var(--space-6);--header-shadow: 0 1px 2px rgba(0, 0, 0, .05);--header-z-index: 100;--header-logo-height: 32px;--header-user-gap: var(--space-4)}.cc-sidebar-tokens{--sidebar-width: 280px;--sidebar-collapsed-width: 80px;--sidebar-bg: #1C1917;--sidebar-border-color: #292524;--sidebar-padding: var(--space-4);--sidebar-z-index: 101;--sidebar-transition: width .3s cubic-bezier(.4, 0, .2, 1);--sidebar-item-height: 48px;--sidebar-item-radius: var(--radius-lg);--sidebar-item-padding: 0 var(--space-4);--sidebar-item-gap: var(--space-3);--sidebar-accent-color: #0EA5E9;--sidebar-text-color: #FFFFFF;--sidebar-text-muted: #A8A29E}.cc-data-table-tokens{--table-bg: var(--color-bg-primary);--table-header-bg: var(--color-bg-secondary);--table-border-color: var(--color-border-subtle);--table-header-color: var(--color-text-muted);--table-row-hover: rgba(var(--color-brand-primary-rgb), .04);--table-cell-padding: var(--space-4);--table-font-size: var(--font-size-sm);--table-radius: var(--radius-lg)}.cc-modal-tokens{--modal-bg: var(--color-bg-primary);--modal-overlay-bg: rgba(0, 0, 0, .5);--modal-radius: var(--radius-xl);--modal-shadow: var(--shadow-xl);--modal-z-index: 1000;--modal-header-padding: var(--space-6);--modal-body-padding: var(--space-6);--modal-footer-padding: var(--space-4) var(--space-6);--modal-sm-width: 400px;--modal-md-width: 600px;--modal-lg-width: 900px}.cc-sidebar{width:var(--sidebar-width);height:100vh;background:var(--neutral-900)}@supports (backdrop-filter: blur(1px)){.cc-sidebar{background:var(--surface-glass-bg);backdrop-filter:blur(var(--surface-glass-blur));-webkit-backdrop-filter:blur(var(--surface-glass-blur))}}.cc-sidebar{border-right:1px solid var(--surface-glass-border);display:flex;flex-direction:column;transition:var(--sidebar-transition);overflow-x:hidden;position:sticky;top:0;z-index:110}.cc-sidebar.collapsed{width:var(--sidebar-collapsed-width)}.cc-sidebar.collapsed .cc-sidebar-header{padding:var(--space-4) 0;justify-content:center}.cc-sidebar.collapsed .cc-sidebar-logo{display:none}.cc-sidebar.collapsed .cc-sidebar-toggle{position:static}.cc-sidebar.collapsed .cc-sidebar-item{justify-content:center;padding:0}.cc-sidebar-header{height:var(--header-height);padding:0 var(--space-6);display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--surface-glass-border);position:relative;background:transparent}.cc-sidebar-logo{display:flex;align-items:center}.cc-sidebar-toggle{background:var(--color-bg-secondary);border:1px solid var(--color-border-subtle);color:var(--color-text-muted);width:24px;height:24px;border-radius:var(--radius-full);display:flex;align-items:center;justify-content:center;cursor:pointer;position:absolute;right:-12px;top:calc(var(--header-height) / 2 - 12px);z-index:2;transition:all .15s ease}.cc-sidebar-toggle:hover{background-color:var(--color-brand);border-color:var(--color-brand);color:#fff}.cc-sidebar-nav{flex:1;padding:var(--space-4);display:flex;flex-direction:column;gap:var(--space-2);overflow-y:auto}.cc-sidebar-item{height:48px;padding:0 var(--space-4);display:flex;align-items:center;gap:var(--space-3);border-radius:var(--radius-lg);color:var(--color-text-secondary);text-decoration:none;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);transition:all .2s cubic-bezier(.4,0,.2,1);position:relative}.cc-sidebar-item:hover{background-color:var(--color-bg-secondary);color:var(--color-text-primary)}.cc-sidebar-item.active{background-color:var(--color-brand);color:#fff;box-shadow:0 4px 12px rgba(var(--brand-600),.2)}.cc-sidebar-item.active .cc-sidebar-item-icon{color:#fff}.cc-sidebar-item.active:after{content:\"\";position:absolute;left:-4px;top:25%;height:50%;width:4px;background:#fff;border-radius:0 4px 4px 0}.cc-sidebar-item-icon{flex-shrink:0;color:inherit;font-size:24px}.cc-sidebar-item-label{white-space:nowrap;opacity:1;transition:opacity .2s ease}.cc-sidebar-item-badge{margin-left:auto;background-color:var(--color-danger);color:#fff;font-size:var(--font-size-xs);padding:2px 6px;border-radius:var(--radius-full)}.cc-sidebar-footer{padding:var(--space-4);border-top:1px solid var(--surface-glass-border)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: CcIconComponent, selector: "cc-icon", inputs: ["name", "size", "color"] }] }); }
1861
+ const StatCardColorSchema = z.enum(['blue', 'green', 'red', 'yellow', 'purple', 'orange']);
1862
+ const StatCardResourceSchema = z.object({
1863
+ title: z.string(),
1864
+ value: z.union([z.string(), z.number()]),
1865
+ icon: z.string().optional(),
1866
+ color: StatCardColorSchema.optional(),
1867
+ loading: z.boolean().default(false).optional(),
1868
+ });
1869
+ const STAT_CARD_COLOR_MAP = {
1870
+ blue: { bg: 'bg-blue-50', label: 'text-blue-500' },
1871
+ green: { bg: 'bg-green-50', label: 'text-green-500' },
1872
+ red: { bg: 'bg-red-50', label: 'text-red-500' },
1873
+ yellow: { bg: 'bg-yellow-50', label: 'text-yellow-600' },
1874
+ purple: { bg: 'bg-purple-50', label: 'text-purple-500' },
1875
+ orange: { bg: 'bg-orange-50', label: 'text-orange-500' },
1876
+ };
1877
+
1878
+ class AdStatCardComponent {
1879
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
1880
+ title = computed(() => this.resource().title, ...(ngDevMode ? [{ debugName: "title" }] : []));
1881
+ value = computed(() => this.resource().value, ...(ngDevMode ? [{ debugName: "value" }] : []));
1882
+ icon = computed(() => this.resource().icon, ...(ngDevMode ? [{ debugName: "icon" }] : []));
1883
+ colorClass = computed(() => {
1884
+ const color = this.resource().color ?? 'blue';
1885
+ return STAT_CARD_COLOR_MAP[color].bg;
1886
+ }, ...(ngDevMode ? [{ debugName: "colorClass" }] : []));
1887
+ labelColorClass = computed(() => {
1888
+ const color = this.resource().color ?? 'blue';
1889
+ return STAT_CARD_COLOR_MAP[color].label;
1890
+ }, ...(ngDevMode ? [{ debugName: "labelColorClass" }] : []));
1891
+ isLoading = computed(() => this.resource().loading ?? false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
1892
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdStatCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1893
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdStatCardComponent, isStandalone: true, selector: "ad-stat-card", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"bg-white rounded-2xl shadow-sm border border-slate-100 p-4 min-w-[160px]\">\r\n <div class=\"rounded-xl p-4 flex flex-col gap-3\" [ngClass]=\"colorClass()\">\r\n\r\n <!-- T\u00EDtulo -->\r\n <span class=\"text-[11px] font-semibold tracking-widest uppercase\" [ngClass]=\"labelColorClass()\">\r\n {{ title() }}\r\n </span>\r\n\r\n <!-- Icono + Valor (alineados a la derecha) -->\r\n @if (isLoading()) {\r\n <div class=\"h-9 w-20 rounded-lg animate-pulse opacity-30\" [ngClass]=\"labelColorClass()\"></div>\r\n } @else {\r\n <div class=\"flex items-center justify-between gap-2\">\r\n @if (icon()) {\r\n <ad-icon [name]=\"icon()!\" size=\"md\" [ngClass]=\"labelColorClass()\"></ad-icon>\r\n }\r\n <span class=\"text-3xl font-bold text-slate-800 leading-none ml-auto\">\r\n {{ value() }}\r\n </span>\r\n </div>\r\n }\r\n\r\n </div>\r\n</div>", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AdIconComponent, selector: "ad-icon", inputs: ["name", "size", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
401
1894
  }
402
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcSidebarComponent, decorators: [{
1895
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdStatCardComponent, decorators: [{
403
1896
  type: Component,
404
- args: [{ selector: 'cc-sidebar', standalone: true, imports: [CommonModule, RouterLink, RouterLinkActive, CcIconComponent], template: "<aside class=\"cc-sidebar\" [class.collapsed]=\"collapsed\">\r\n <div class=\"cc-sidebar-header\">\r\n <div class=\"cc-sidebar-logo\">\r\n <ng-content select=\"[logo]\"></ng-content>\r\n </div>\r\n <button class=\"cc-sidebar-toggle\" (click)=\"toggleCollapse.emit()\" type=\"button\">\r\n <cc-icon [name]=\"collapsed ? 'chevron_right' : 'chevron_left'\" size=\"sm\"></cc-icon>\r\n </button>\r\n </div>\r\n\r\n <nav class=\"cc-sidebar-nav\">\r\n <div class=\"cc-sidebar-group\" *ngFor=\"let item of menuItems\">\r\n <a class=\"cc-sidebar-item\" [routerLink]=\"item.route\" routerLinkActive=\"active\"\r\n [routerLinkActiveOptions]=\"{ exact: item.exact || false }\" [title]=\"collapsed ? item.label : ''\"\r\n (click)=\"onItemClick(item)\">\r\n\r\n <cc-icon [name]=\"item.icon\" size=\"md\" class=\"cc-sidebar-item-icon\"></cc-icon>\r\n <span class=\"cc-sidebar-item-label\" *ngIf=\"!collapsed\">{{ item.label }}</span>\r\n\r\n <span class=\"cc-sidebar-item-badge\" *ngIf=\"item.badge && !collapsed\">\r\n {{ item.badge }}\r\n </span>\r\n </a>\r\n </div>\r\n </nav>\r\n\r\n <div class=\"cc-sidebar-footer\">\r\n <ng-content select=\"[footer]\"></ng-content>\r\n </div>\r\n</aside>", styles: [":root,[data-theme=light]{--color-bg-primary: #FFFFFF;--color-bg-secondary: #FAFAF9;--color-text-primary: #1C1917;--color-text-secondary: #57534E;--color-text-muted: #A8A29E;--color-border-subtle: #E7E5E4;--color-border-strong: #D6D3D1;--color-brand: #0284C7;--color-brand-hover: #0369A1;--color-focus-ring: rgba(2, 132, 199, .2);--color-success: #10B981;--color-danger: #F43F5E;--surface-glass-bg: rgba(255, 255, 255, .7);--surface-glass-border: rgba(255, 255, 255, .3);--surface-glass-blur: 12px;--surface-glass-shadow: 0 4px 6px -1px rgba(0, 0, 0, .1);--font-heading-xl: 32px;--font-heading-lg: 24px;--font-heading-md: 20px;--font-body-lg: 18px;--font-body-md: 16px;--font-caption: 12px;--font-family-base: Inter, sans-serif;--font-weight-regular: 400;--font-weight-medium: 500;--font-weight-semibold: 600;--font-weight-bold: 700;--radius-sm: 6px;--radius-md: 8px;--radius-lg: 14px;--radius-xl: 18px;--radius-full: 9999px;--font-size-xs: 12px;--font-size-sm: 14px;--font-size-md: 16px;--font-size-lg: 18px;--font-size-xl: 20px;--font-size-2xl: 24px;--font-size-3xl: 32px;--space-1: 4px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-6: 24px;--space-8: calc(var(--space-4) * 2);--shadow-sm: 0 1px 2px rgba(0, 0, 0, .06);--shadow-md: 0 4px 12px rgba(0, 0, 0, .08);--shadow-lg: 0 12px 32px rgba(0, 0, 0, .12)}[data-theme=dark]{--color-bg-primary: #1C1917;--color-bg-secondary: #292524;--color-text-primary: #FFFFFF;--color-text-secondary: #A8A29E;--color-text-muted: #78716C;--color-border-subtle: #44403C;--color-border-strong: #57534E;--color-brand: #0EA5E9;--color-brand-hover: #7DD3FC;--color-focus-ring: rgba(59, 130, 246, .5);--surface-glass-bg: rgba(15, 23, 42, .8);--surface-glass-border: rgba(255, 255, 255, .1);--surface-glass-blur: 16px;--surface-glass-shadow: 0 10px 15px -3px rgba(0, 0, 0, .3)}:root{--h1-size: var(--font-size-h1);--h1-weight: var(--font-weight-semibold);--h2-size: var(--font-size-h2);--h2-weight: var(--font-weight-semibold);--h3-size: var(--font-size-h3);--h3-weight: var(--font-weight-semibold);--body-size: var(--font-size-body);--body-weight: var(--font-weight-regular);--sm-size: var(--font-size-sm);--sm-weight: var(--font-weight-regular);--caption-size: var(--font-size-caption);--caption-weight: var(--font-weight-regular)}:root{--btn-height-md: 44px;--btn-radius: var(--radius-md);--btn-font-weight: var(--font-weight-medium);--btn-bg-primary: var(--color-brand);--btn-text-primary: #FFFFFF;--btn-shadow-default: var(--shadow-sm);--btn-shadow-hover: var(--shadow-md);--btn-transition: .15s ease;--btn-focus-ring: 0 0 0 2px var(--color-focus-ring)}:root{--card-bg: var(--color-bg-primary);--card-radius: var(--radius-lg);--card-shadow: var(--shadow-sm);--card-shadow-hover: var(--shadow-md)}:root{--input-height-md: 44px;--input-bg: var(--color-bg-primary);--input-radius: var(--radius-md);--input-border-default: var(--color-border-subtle);--input-border-hover: var(--color-border-strong);--input-border-focus: var(--color-brand);--input-border-error: var(--color-danger);--input-transition: .12s ease-in-out;--input-focus-ring: 0 0 0 3px var(--color-focus-ring);--input-error-ring: 0 0 0 3px rgba(239, 68, 68, .15)}.cc-badge-tokens{--badge-radius: var(--radius-sm);--badge-padding-v: var(--space-1);--badge-padding-h: var(--space-2);--badge-font-size: var(--font-size-xs);--badge-font-weight: var(--font-weight-medium);--badge-success-bg: #D1FAE5;--badge-success-text: #065F46;--badge-success-border: #A7F3D0;--badge-warning-bg: #FEF3C7;--badge-warning-text: #92400E;--badge-warning-border: #FDE68A;--badge-error-bg: #FFE4E6;--badge-error-text: #9F1239;--badge-error-border: #FECDD3;--badge-info-bg: var(--color-info-50);--badge-info-text: var(--color-info-700);--badge-info-border: var(--color-info-200);--badge-neutral-bg: #F5F5F4;--badge-neutral-text: #44403C;--badge-neutral-border: #E7E5E4}.cc-label-tokens{--label-font-size: var(--font-size-sm);--label-font-weight: var(--font-weight-medium);--label-color: var(--color-text-secondary);--label-required-color: var(--color-error-500);--label-margin-bottom: var(--space-2)}.cc-select-tokens{--select-bg: var(--color-bg-primary);--select-border: var(--color-border-subtle);--select-border-hover: var(--color-border-strong);--select-border-focus: var(--color-brand-primary);--select-shadow-focus: var(--shadow-focus);--select-radius: var(--radius-md);--select-height: 44px;--select-padding-h: var(--space-4);--select-dropdown-bg: var(--color-bg-primary);--select-dropdown-shadow: var(--shadow-md);--select-dropdown-max-height: 240px;--select-option-padding: var(--space-3) var(--space-4);--select-option-hover: var(--color-bg-secondary);--select-option-selected-bg: var(--color-brand-50);--select-option-selected-text: var(--color-brand-primary)}.cc-form-field-tokens{--form-field-margin-bottom: var(--space-6);--form-field-label-margin: var(--space-2);--form-field-message-margin: var(--space-1);--form-field-message-font-size: var(--font-size-xs);--form-field-message-color: var(--color-text-muted);--form-field-error-color: var(--color-error-600)}.cc-header-tokens{--header-height: 72px;--header-bg: #FFFFFF;--header-border-color: #F5F5F4;--header-padding: 0 var(--space-6);--header-shadow: 0 1px 2px rgba(0, 0, 0, .05);--header-z-index: 100;--header-logo-height: 32px;--header-user-gap: var(--space-4)}.cc-sidebar-tokens{--sidebar-width: 280px;--sidebar-collapsed-width: 80px;--sidebar-bg: #1C1917;--sidebar-border-color: #292524;--sidebar-padding: var(--space-4);--sidebar-z-index: 101;--sidebar-transition: width .3s cubic-bezier(.4, 0, .2, 1);--sidebar-item-height: 48px;--sidebar-item-radius: var(--radius-lg);--sidebar-item-padding: 0 var(--space-4);--sidebar-item-gap: var(--space-3);--sidebar-accent-color: #0EA5E9;--sidebar-text-color: #FFFFFF;--sidebar-text-muted: #A8A29E}.cc-data-table-tokens{--table-bg: var(--color-bg-primary);--table-header-bg: var(--color-bg-secondary);--table-border-color: var(--color-border-subtle);--table-header-color: var(--color-text-muted);--table-row-hover: rgba(var(--color-brand-primary-rgb), .04);--table-cell-padding: var(--space-4);--table-font-size: var(--font-size-sm);--table-radius: var(--radius-lg)}.cc-modal-tokens{--modal-bg: var(--color-bg-primary);--modal-overlay-bg: rgba(0, 0, 0, .5);--modal-radius: var(--radius-xl);--modal-shadow: var(--shadow-xl);--modal-z-index: 1000;--modal-header-padding: var(--space-6);--modal-body-padding: var(--space-6);--modal-footer-padding: var(--space-4) var(--space-6);--modal-sm-width: 400px;--modal-md-width: 600px;--modal-lg-width: 900px}.cc-sidebar{width:var(--sidebar-width);height:100vh;background:var(--neutral-900)}@supports (backdrop-filter: blur(1px)){.cc-sidebar{background:var(--surface-glass-bg);backdrop-filter:blur(var(--surface-glass-blur));-webkit-backdrop-filter:blur(var(--surface-glass-blur))}}.cc-sidebar{border-right:1px solid var(--surface-glass-border);display:flex;flex-direction:column;transition:var(--sidebar-transition);overflow-x:hidden;position:sticky;top:0;z-index:110}.cc-sidebar.collapsed{width:var(--sidebar-collapsed-width)}.cc-sidebar.collapsed .cc-sidebar-header{padding:var(--space-4) 0;justify-content:center}.cc-sidebar.collapsed .cc-sidebar-logo{display:none}.cc-sidebar.collapsed .cc-sidebar-toggle{position:static}.cc-sidebar.collapsed .cc-sidebar-item{justify-content:center;padding:0}.cc-sidebar-header{height:var(--header-height);padding:0 var(--space-6);display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--surface-glass-border);position:relative;background:transparent}.cc-sidebar-logo{display:flex;align-items:center}.cc-sidebar-toggle{background:var(--color-bg-secondary);border:1px solid var(--color-border-subtle);color:var(--color-text-muted);width:24px;height:24px;border-radius:var(--radius-full);display:flex;align-items:center;justify-content:center;cursor:pointer;position:absolute;right:-12px;top:calc(var(--header-height) / 2 - 12px);z-index:2;transition:all .15s ease}.cc-sidebar-toggle:hover{background-color:var(--color-brand);border-color:var(--color-brand);color:#fff}.cc-sidebar-nav{flex:1;padding:var(--space-4);display:flex;flex-direction:column;gap:var(--space-2);overflow-y:auto}.cc-sidebar-item{height:48px;padding:0 var(--space-4);display:flex;align-items:center;gap:var(--space-3);border-radius:var(--radius-lg);color:var(--color-text-secondary);text-decoration:none;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);transition:all .2s cubic-bezier(.4,0,.2,1);position:relative}.cc-sidebar-item:hover{background-color:var(--color-bg-secondary);color:var(--color-text-primary)}.cc-sidebar-item.active{background-color:var(--color-brand);color:#fff;box-shadow:0 4px 12px rgba(var(--brand-600),.2)}.cc-sidebar-item.active .cc-sidebar-item-icon{color:#fff}.cc-sidebar-item.active:after{content:\"\";position:absolute;left:-4px;top:25%;height:50%;width:4px;background:#fff;border-radius:0 4px 4px 0}.cc-sidebar-item-icon{flex-shrink:0;color:inherit;font-size:24px}.cc-sidebar-item-label{white-space:nowrap;opacity:1;transition:opacity .2s ease}.cc-sidebar-item-badge{margin-left:auto;background-color:var(--color-danger);color:#fff;font-size:var(--font-size-xs);padding:2px 6px;border-radius:var(--radius-full)}.cc-sidebar-footer{padding:var(--space-4);border-top:1px solid var(--surface-glass-border)}\n"] }]
405
- }], propDecorators: { menuItems: [{
406
- type: Input
407
- }], collapsed: [{
408
- type: Input
409
- }], activeRoute: [{
410
- type: Input
411
- }], navigate: [{
412
- type: Output
413
- }], toggleCollapse: [{
414
- type: Output
415
- }] } });
1897
+ args: [{ selector: 'ad-stat-card', standalone: true, imports: [NgClass, AdIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"bg-white rounded-2xl shadow-sm border border-slate-100 p-4 min-w-[160px]\">\r\n <div class=\"rounded-xl p-4 flex flex-col gap-3\" [ngClass]=\"colorClass()\">\r\n\r\n <!-- T\u00EDtulo -->\r\n <span class=\"text-[11px] font-semibold tracking-widest uppercase\" [ngClass]=\"labelColorClass()\">\r\n {{ title() }}\r\n </span>\r\n\r\n <!-- Icono + Valor (alineados a la derecha) -->\r\n @if (isLoading()) {\r\n <div class=\"h-9 w-20 rounded-lg animate-pulse opacity-30\" [ngClass]=\"labelColorClass()\"></div>\r\n } @else {\r\n <div class=\"flex items-center justify-between gap-2\">\r\n @if (icon()) {\r\n <ad-icon [name]=\"icon()!\" size=\"md\" [ngClass]=\"labelColorClass()\"></ad-icon>\r\n }\r\n <span class=\"text-3xl font-bold text-slate-800 leading-none ml-auto\">\r\n {{ value() }}\r\n </span>\r\n </div>\r\n }\r\n\r\n </div>\r\n</div>" }]
1898
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }] } });
416
1899
 
417
- class CcDataTableComponent {
418
- constructor() {
419
- this.data = [];
420
- this.columns = [];
421
- this.loading = false;
422
- this.showSearch = true;
423
- this.searchPlaceholder = 'Buscar en la tabla...';
424
- this.rowClick = new EventEmitter();
425
- this.search = new EventEmitter();
426
- this.actionClick = new EventEmitter();
427
- }
1900
+ class AdDataTableComponent {
1901
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
1902
+ data = computed(() => this.resource().data || [], ...(ngDevMode ? [{ debugName: "data" }] : []));
1903
+ columns = computed(() => this.resource().columns || [], ...(ngDevMode ? [{ debugName: "columns" }] : []));
1904
+ loading = computed(() => this.resource().loading || false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
1905
+ showSearch = computed(() => this.resource().showSearch ?? true, ...(ngDevMode ? [{ debugName: "showSearch" }] : []));
1906
+ searchPlaceholder = computed(() => this.resource().searchPlaceholder || 'Buscar en la tabla...', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : []));
1907
+ rowClick = output();
1908
+ search = output();
1909
+ actionClick = output();
1910
+ customCellTemplate;
1911
+ rowActionsTemplate; // Fixed missing ContentChild
428
1912
  get skeletonRows() {
429
1913
  return Array(5).fill(0);
430
1914
  }
431
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcDataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
432
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcDataTableComponent, isStandalone: true, selector: "cc-data-table", inputs: { data: "data", columns: "columns", loading: "loading", showSearch: "showSearch", searchPlaceholder: "searchPlaceholder" }, outputs: { rowClick: "rowClick", search: "search", actionClick: "actionClick" }, queries: [{ propertyName: "customCellTemplate", first: true, predicate: ["customCell"], descendants: true }, { propertyName: "rowActionsTemplate", first: true, predicate: ["rowActions"], descendants: true }], ngImport: i0, template: "<div class=\"cc-data-table-container\">\r\n <div class=\"cc-data-table-wrapper\">\r\n <table class=\"cc-data-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let col of columns\">\r\n {{ col.label }}\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n <tr *ngFor=\"let row of data\">\r\n <td *ngFor=\"let col of columns\">\r\n {{ row[col.key] }}\r\n </td>\r\n </tr>\r\n\r\n <tr *ngIf=\"data.length === 0\">\r\n <td [attr.colspan]=\"columns.length\">\r\n No se encontraron resultados\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n</div>", styles: [".cc-data-table-container{display:flex;flex-direction:column;gap:var(--space-4);width:100%}.cc-data-table-header{display:flex;justify-content:space-between;align-items:center;gap:var(--space-4)}.cc-data-table-wrapper{background-color:var(--table-bg);border:1px solid var(--table-border-color);border-radius:var(--table-radius);overflow:hidden;box-shadow:var(--shadow-sm)}.cc-data-table{width:100%;border-collapse:collapse;text-align:left;font-size:var(--table-font-size)}.cc-data-table thead{background-color:var(--color-bg-secondary)}.cc-data-table thead th{padding:var(--space-4) var(--space-6);font-weight:var(--font-weight-bold);font-size:var(--font-size-xs);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--color-border-subtle)}.cc-data-table thead th.sortable{cursor:pointer}.cc-data-table thead th.sortable:hover{color:var(--color-text-primary)}.cc-data-table tbody tr{border-bottom:1px solid var(--color-border-subtle);transition:all .2s ease;cursor:pointer;height:52px}.cc-data-table tbody tr:last-child{border-bottom:none}.cc-data-table tbody tr:hover{background-color:rgba(var(--brand-600),.02)}.cc-data-table tbody tr:hover td{color:var(--color-brand)}.cc-data-table tbody tr.active{background-color:var(--color-bg-secondary);box-shadow:inset 3px 0 0 0 var(--color-brand)}.cc-data-table tbody td{padding:var(--space-3) var(--space-6);color:var(--color-text-primary);font-size:var(--font-size-sm)}.cc-table-th-content{display:flex;align-items:center;gap:var(--space-2)}.cc-table-empty-content{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--space-12);color:var(--color-text-muted);gap:var(--space-4)}.cc-table-empty-content p{font-size:var(--font-size-lg);font-weight:var(--font-weight-medium)}.cc-table-skeleton-bar{height:12px;background:linear-gradient(90deg,var(--color-bg-secondary) 25%,var(--color-border-subtle) 50%,var(--color-bg-secondary) 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite;border-radius:var(--radius-sm);width:100%}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
1915
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdDataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1916
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdDataTableComponent, isStandalone: true, selector: "ad-data-table", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { rowClick: "rowClick", search: "search", actionClick: "actionClick" }, queries: [{ propertyName: "customCellTemplate", first: true, predicate: ["customCell"], descendants: true }, { propertyName: "rowActionsTemplate", first: true, predicate: ["rowActions"], descendants: true }], ngImport: i0, template: "<div class=\"ad-data-table-container\">\r\n <div class=\"ad-data-table-wrapper\">\r\n <table class=\"ad-data-table\">\r\n <thead>\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <th>\r\n {{ col.label }}\r\n </th>\r\n }\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of data(); track $index) {\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <td>\r\n {{ row[col.key] }}\r\n </td>\r\n }\r\n </tr>\r\n } @empty {\r\n <tr>\r\n <td [attr.colspan]=\"columns().length\">\r\n No se encontraron resultados\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n</div>", styles: [".ad-data-table-container{display:flex;flex-direction:column;gap:var(--space-4);width:100%}.ad-data-table-header{display:flex;justify-content:space-between;align-items:center;gap:var(--space-4)}.ad-data-table-wrapper{background-color:var(--table-bg);border:1px solid var(--table-border-color);border-radius:var(--table-radius);overflow:hidden;box-shadow:var(--shadow-sm)}.ad-data-table{width:100%;border-collapse:collapse;text-align:left;font-size:var(--table-font-size)}.ad-data-table thead{background-color:var(--color-bg-secondary)}.ad-data-table thead th{padding:var(--space-4) var(--space-6);font-weight:var(--font-weight-bold);font-size:var(--font-size-xs);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--color-border-subtle)}.ad-data-table thead th.sortable{cursor:pointer}.ad-data-table thead th.sortable:hover{color:var(--color-text-primary)}.ad-data-table tbody tr{border-bottom:1px solid var(--color-border-subtle);transition:all .2s ease;cursor:pointer;height:52px}.ad-data-table tbody tr:last-child{border-bottom:none}.ad-data-table tbody tr:hover{background-color:rgba(var(--brand-600),.02)}.ad-data-table tbody tr:hover td{color:var(--color-brand)}.ad-data-table tbody tr.active{background-color:var(--color-bg-secondary);box-shadow:inset 3px 0 0 0 var(--color-brand)}.ad-data-table tbody td{padding:var(--space-3) var(--space-6);color:var(--color-text-primary);font-size:var(--font-size-sm)}.ad-table-th-content{display:flex;align-items:center;gap:var(--space-2)}.ad-table-empty-content{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--space-12);color:var(--color-text-muted);gap:var(--space-4)}.ad-table-empty-content p{font-size:var(--font-size-lg);font-weight:var(--font-weight-medium)}.ad-table-skeleton-bar{height:12px;background:linear-gradient(90deg,var(--color-bg-secondary) 25%,var(--color-border-subtle) 50%,var(--color-bg-secondary) 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite;border-radius:var(--radius-sm);width:100%}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
433
1917
  }
434
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcDataTableComponent, decorators: [{
1918
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdDataTableComponent, decorators: [{
435
1919
  type: Component,
436
- args: [{ selector: 'cc-data-table', standalone: true, imports: [CommonModule], template: "<div class=\"cc-data-table-container\">\r\n <div class=\"cc-data-table-wrapper\">\r\n <table class=\"cc-data-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let col of columns\">\r\n {{ col.label }}\r\n </th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n <tr *ngFor=\"let row of data\">\r\n <td *ngFor=\"let col of columns\">\r\n {{ row[col.key] }}\r\n </td>\r\n </tr>\r\n\r\n <tr *ngIf=\"data.length === 0\">\r\n <td [attr.colspan]=\"columns.length\">\r\n No se encontraron resultados\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n </div>\r\n</div>", styles: [".cc-data-table-container{display:flex;flex-direction:column;gap:var(--space-4);width:100%}.cc-data-table-header{display:flex;justify-content:space-between;align-items:center;gap:var(--space-4)}.cc-data-table-wrapper{background-color:var(--table-bg);border:1px solid var(--table-border-color);border-radius:var(--table-radius);overflow:hidden;box-shadow:var(--shadow-sm)}.cc-data-table{width:100%;border-collapse:collapse;text-align:left;font-size:var(--table-font-size)}.cc-data-table thead{background-color:var(--color-bg-secondary)}.cc-data-table thead th{padding:var(--space-4) var(--space-6);font-weight:var(--font-weight-bold);font-size:var(--font-size-xs);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--color-border-subtle)}.cc-data-table thead th.sortable{cursor:pointer}.cc-data-table thead th.sortable:hover{color:var(--color-text-primary)}.cc-data-table tbody tr{border-bottom:1px solid var(--color-border-subtle);transition:all .2s ease;cursor:pointer;height:52px}.cc-data-table tbody tr:last-child{border-bottom:none}.cc-data-table tbody tr:hover{background-color:rgba(var(--brand-600),.02)}.cc-data-table tbody tr:hover td{color:var(--color-brand)}.cc-data-table tbody tr.active{background-color:var(--color-bg-secondary);box-shadow:inset 3px 0 0 0 var(--color-brand)}.cc-data-table tbody td{padding:var(--space-3) var(--space-6);color:var(--color-text-primary);font-size:var(--font-size-sm)}.cc-table-th-content{display:flex;align-items:center;gap:var(--space-2)}.cc-table-empty-content{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--space-12);color:var(--color-text-muted);gap:var(--space-4)}.cc-table-empty-content p{font-size:var(--font-size-lg);font-weight:var(--font-weight-medium)}.cc-table-skeleton-bar{height:12px;background:linear-gradient(90deg,var(--color-bg-secondary) 25%,var(--color-border-subtle) 50%,var(--color-bg-secondary) 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite;border-radius:var(--radius-sm);width:100%}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"] }]
437
- }], propDecorators: { data: [{
438
- type: Input
439
- }], columns: [{
440
- type: Input
441
- }], loading: [{
442
- type: Input
443
- }], showSearch: [{
444
- type: Input
445
- }], searchPlaceholder: [{
446
- type: Input
447
- }], rowClick: [{
448
- type: Output
449
- }], search: [{
450
- type: Output
451
- }], actionClick: [{
452
- type: Output
453
- }], customCellTemplate: [{
1920
+ args: [{ selector: 'ad-data-table', standalone: true, imports: [CommonModule], template: "<div class=\"ad-data-table-container\">\r\n <div class=\"ad-data-table-wrapper\">\r\n <table class=\"ad-data-table\">\r\n <thead>\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <th>\r\n {{ col.label }}\r\n </th>\r\n }\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of data(); track $index) {\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <td>\r\n {{ row[col.key] }}\r\n </td>\r\n }\r\n </tr>\r\n } @empty {\r\n <tr>\r\n <td [attr.colspan]=\"columns().length\">\r\n No se encontraron resultados\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n</div>", styles: [".ad-data-table-container{display:flex;flex-direction:column;gap:var(--space-4);width:100%}.ad-data-table-header{display:flex;justify-content:space-between;align-items:center;gap:var(--space-4)}.ad-data-table-wrapper{background-color:var(--table-bg);border:1px solid var(--table-border-color);border-radius:var(--table-radius);overflow:hidden;box-shadow:var(--shadow-sm)}.ad-data-table{width:100%;border-collapse:collapse;text-align:left;font-size:var(--table-font-size)}.ad-data-table thead{background-color:var(--color-bg-secondary)}.ad-data-table thead th{padding:var(--space-4) var(--space-6);font-weight:var(--font-weight-bold);font-size:var(--font-size-xs);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--color-border-subtle)}.ad-data-table thead th.sortable{cursor:pointer}.ad-data-table thead th.sortable:hover{color:var(--color-text-primary)}.ad-data-table tbody tr{border-bottom:1px solid var(--color-border-subtle);transition:all .2s ease;cursor:pointer;height:52px}.ad-data-table tbody tr:last-child{border-bottom:none}.ad-data-table tbody tr:hover{background-color:rgba(var(--brand-600),.02)}.ad-data-table tbody tr:hover td{color:var(--color-brand)}.ad-data-table tbody tr.active{background-color:var(--color-bg-secondary);box-shadow:inset 3px 0 0 0 var(--color-brand)}.ad-data-table tbody td{padding:var(--space-3) var(--space-6);color:var(--color-text-primary);font-size:var(--font-size-sm)}.ad-table-th-content{display:flex;align-items:center;gap:var(--space-2)}.ad-table-empty-content{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:var(--space-12);color:var(--color-text-muted);gap:var(--space-4)}.ad-table-empty-content p{font-size:var(--font-size-lg);font-weight:var(--font-weight-medium)}.ad-table-skeleton-bar{height:12px;background:linear-gradient(90deg,var(--color-bg-secondary) 25%,var(--color-border-subtle) 50%,var(--color-bg-secondary) 75%);background-size:200% 100%;animation:loading-shimmer 1.5s infinite;border-radius:var(--radius-sm);width:100%}@keyframes loading-shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}\n"] }]
1921
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], search: [{ type: i0.Output, args: ["search"] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }], customCellTemplate: [{
454
1922
  type: ContentChild,
455
1923
  args: ['customCell']
456
1924
  }], rowActionsTemplate: [{
@@ -458,65 +1926,104 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
458
1926
  args: ['rowActions']
459
1927
  }] } });
460
1928
 
461
- class CcModalComponent {
462
- constructor() {
463
- this.isOpen = false;
464
- this.title = '';
465
- this.size = 'md';
466
- this.closeOnOverlay = true;
467
- this.showFooter = true;
468
- this.close = new EventEmitter();
1929
+ const DataTableColumnSchema = z.object({
1930
+ key: z.string(),
1931
+ label: z.string(),
1932
+ type: z.enum(['text', 'number', 'date', 'badge', 'custom']).optional(),
1933
+ sortable: z.boolean().optional(),
1934
+ });
1935
+ const DataTableResourceSchema = z.object({
1936
+ data: z.array(z.any()).default([]),
1937
+ columns: z.array(DataTableColumnSchema).default([]),
1938
+ loading: z.boolean().default(false).optional(),
1939
+ showSearch: z.boolean().default(true).optional(),
1940
+ searchPlaceholder: z.string().default('Buscar en la tabla...').optional(),
1941
+ });
1942
+
1943
+ class AdHeaderComponent {
1944
+ // Inputs
1945
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
1946
+ user = computed(() => this.resource().user, ...(ngDevMode ? [{ debugName: "user" }] : []));
1947
+ notificationsCount = computed(() => this.resource().notificationsCount ?? 0, ...(ngDevMode ? [{ debugName: "notificationsCount" }] : []));
1948
+ // Outputs
1949
+ toggleSidebar = output();
1950
+ toggleMobileMenu = output();
1951
+ logout = output();
1952
+ navigateProfile = output();
1953
+ toggleTheme = output();
1954
+ // State
1955
+ isUserMenuOpen = signal(false, ...(ngDevMode ? [{ debugName: "isUserMenuOpen" }] : []));
1956
+ isDarkMode = signal(false, ...(ngDevMode ? [{ debugName: "isDarkMode" }] : []));
1957
+ onToggleSidebar() {
1958
+ this.toggleSidebar.emit();
469
1959
  }
470
- onOverlayClick(event) {
471
- if (this.closeOnOverlay && event.target.classList.contains('cc-modal-overlay')) {
472
- this.close.emit();
473
- }
1960
+ onToggleMobileMenu() {
1961
+ this.toggleMobileMenu.emit();
474
1962
  }
475
- onEscape() {
476
- if (this.isOpen) {
477
- this.close.emit();
1963
+ toggleUserMenu() {
1964
+ this.isUserMenuOpen.update(v => !v);
1965
+ }
1966
+ closeUserMenu() {
1967
+ this.isUserMenuOpen.set(false);
1968
+ }
1969
+ onLogoutClick() {
1970
+ this.logout.emit();
1971
+ this.closeUserMenu();
1972
+ }
1973
+ onProfileClick() {
1974
+ this.navigateProfile.emit();
1975
+ this.closeUserMenu();
1976
+ }
1977
+ onToggleThemeClick() {
1978
+ this.isDarkMode.update(v => !v);
1979
+ const isDark = this.isDarkMode();
1980
+ if (isDark) {
1981
+ document.documentElement.classList.add('dark');
478
1982
  }
1983
+ else {
1984
+ document.documentElement.classList.remove('dark');
1985
+ }
1986
+ this.toggleTheme.emit(isDark);
1987
+ this.closeUserMenu();
479
1988
  }
480
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
481
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcModalComponent, isStandalone: true, selector: "cc-modal", inputs: { isOpen: "isOpen", title: "title", size: "size", closeOnOverlay: "closeOnOverlay", showFooter: "showFooter" }, outputs: { close: "close" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "<div class=\"cc-modal-overlay\" *ngIf=\"isOpen\" (click)=\"onOverlayClick($event)\">\r\n\r\n <div class=\"cc-modal\" [ngClass]=\"'size-' + size\" role=\"dialog\" aria-modal=\"true\">\r\n\r\n <header class=\"cc-modal-header\">\r\n <h3 class=\"cc-modal-title\">{{ title }}</h3>\r\n <button class=\"cc-modal-close\" (click)=\"close.emit()\" type=\"button\">\r\n <cc-icon name=\"close\" size=\"md\"></cc-icon>\r\n </button>\r\n </header>\r\n\r\n <div class=\"cc-modal-body\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n <footer class=\"cc-modal-footer\" *ngIf=\"showFooter\">\r\n <ng-content select=\"[footer]\"></ng-content>\r\n </footer>\r\n </div>\r\n</div>", styles: [".cc-modal-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:var(--modal-overlay-bg);display:flex;align-items:center;justify-content:center;z-index:var(--modal-z-index);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);padding:var(--space-4)}.cc-modal{background-color:var(--modal-bg);border-radius:var(--modal-radius);box-shadow:var(--modal-shadow);display:flex;flex-direction:column;max-height:90vh;width:100%;animation:modalScaleUp .2s ease-out;overflow:hidden}.cc-modal.size-sm{max-width:var(--modal-sm-width)}.cc-modal.size-md{max-width:var(--modal-md-width)}.cc-modal.size-lg{max-width:var(--modal-lg-width)}.cc-modal-header{padding:var(--modal-header-padding);display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--color-border-subtle)}.cc-modal-title{font-size:var(--font-size-lg);font-weight:var(--font-weight-bold);color:var(--color-text-primary);margin:0}.cc-modal-close{background:transparent;border:none;color:var(--color-text-muted);cursor:pointer;padding:var(--space-1);border-radius:var(--radius-md);display:flex;transition:all .15s ease}.cc-modal-close:hover{background-color:var(--color-bg-secondary);color:var(--color-text-primary)}.cc-modal-body{padding:var(--modal-body-padding);overflow-y:auto;flex:1}.cc-modal-footer{padding:var(--modal-footer-padding);border-top:1px solid var(--color-border-subtle);display:flex;justify-content:flex-end;gap:var(--space-3);background-color:var(--color-bg-secondary)}@keyframes modalScaleUp{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CcIconComponent, selector: "cc-icon", inputs: ["name", "size", "color"] }] }); }
1989
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1990
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdHeaderComponent, isStandalone: true, selector: "ad-header", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { toggleSidebar: "toggleSidebar", toggleMobileMenu: "toggleMobileMenu", logout: "logout", navigateProfile: "navigateProfile", toggleTheme: "toggleTheme" }, ngImport: i0, template: "<header class=\"sticky top-0 z-20 flex items-center justify-between px-6 h-16 \r\n bg-white/80 backdrop-blur-xl border-b border-white/20\r\n shadow-[0_4px_30px_rgba(0,0,0,0.05)] transition-all duration-300\">\r\n <div class=\"flex items-center gap-4 flex-1\">\r\n <!-- Mobile Menu -->\r\n <button (click)=\"onToggleMobileMenu()\"\r\n class=\"md:hidden p-2 text-slate-600 hover:bg-slate-100 rounded-xl transition-all active:scale-95 shadow-sm bg-white border border-slate-100\">\r\n <span class=\"material-icons-outlined\">menu</span>\r\n </button>\r\n\r\n <!-- Desktop Toggle -->\r\n <button (click)=\"onToggleSidebar()\"\r\n class=\"hidden md:flex p-2 text-slate-600 hover:bg-slate-100 rounded-xl transition-all active:scale-95 shadow-sm bg-white border border-slate-100\">\r\n <span class=\"material-icons-outlined\">menu_open</span>\r\n </button>\r\n\r\n <!-- Search Bar -->\r\n <div\r\n class=\"relative flex items-center transition-all duration-300 w-48 md:w-64 focus-within:w-full focus-within:max-w-md\">\r\n <span\r\n class=\"material-icons-outlined absolute left-3 transition-colors text-slate-400 group-focus-within:text-blue-500\">search</span>\r\n <input type=\"text\" placeholder=\"Buscar en Cerca...\"\r\n class=\"w-full bg-slate-50 border border-slate-200 rounded-xl py-2 pl-10 pr-4 text-sm focus:outline-none focus:ring-4 focus:ring-blue-500/10 focus:bg-white transition-all shadow-inner placeholder:text-slate-400 text-slate-600\" />\r\n </div>\r\n </div>\r\n\r\n <!-- Header Right -->\r\n <div class=\"flex items-center gap-3\">\r\n <!-- Notifications -->\r\n <button\r\n class=\"relative p-2.5 text-slate-500 hover:bg-slate-100 rounded-xl transition-all bg-white border border-slate-100 shadow-sm group\">\r\n <span class=\"material-icons-outlined group-hover:text-blue-500 transition-colors\">notifications</span>\r\n @if (notificationsCount() > 0) {\r\n <span class=\"absolute top-2 right-2 w-2.5 h-2.5 bg-red-500 rounded-full border-2 border-white\"></span>\r\n }\r\n </button>\r\n\r\n <div class=\"h-8 w-[1px] bg-slate-200 mx-1\"></div>\r\n\r\n <!-- User Profile -->\r\n <div class=\"flex items-center gap-3 pl-1 group cursor-pointer\" (click)=\"toggleUserMenu()\">\r\n <div class=\"text-right hidden sm:block\">\r\n <p class=\"text-sm font-bold text-slate-700 leading-none group-hover:text-blue-600 transition-colors\">\r\n {{ user().name }}</p>\r\n <p class=\"text-[10px] text-slate-400 font-bold mt-1 tracking-tighter uppercase\">{{ user().role\r\n }}</p>\r\n </div>\r\n <!-- Gradient Avatar -->\r\n <div\r\n class=\"h-10 w-10 rounded-xl bg-gradient-to-tr from-blue-600 to-blue-400 flex items-center justify-center text-white shadow-lg shadow-blue-200 transition-transform group-hover:scale-105\">\r\n @if (user().avatarUrl) {\r\n <img [src]=\"user().avatarUrl\" alt=\"Avatar\"\r\n class=\"h-full w-full rounded-xl object-cover opacity-90 hover:opacity-100\">\r\n } @else {\r\n <span class=\"material-icons-outlined text-sm\">person</span>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown Menu (Existing logic) -->\r\n @if (isUserMenuOpen()) {\r\n <div class=\"fixed inset-0 z-40\" (click)=\"closeUserMenu()\"></div>\r\n <div\r\n class=\"absolute top-16 right-6 w-48 bg-white dark:bg-cerca-navy rounded-xl shadow-xl py-1 border border-slate-100 ring-1 ring-black ring-opacity-5 animate-fade-in-down z-50\">\r\n <button (click)=\"onProfileClick()\"\r\n class=\"w-full text-left px-4 py-2 text-sm text-slate-700 hover:bg-slate-50 hover:text-blue-600 transition-colors flex items-center font-medium\">\r\n <span class=\"material-icons-outlined text-lg mr-2\">person</span> Perfil\r\n </button>\r\n <button (click)=\"onToggleThemeClick()\"\r\n class=\"w-full text-left px-4 py-2 text-sm text-slate-700 hover:bg-slate-50 hover:text-blue-600 transition-colors flex items-center font-medium\">\r\n <span class=\"material-icons-outlined text-lg mr-2\">{{ isDarkMode() ? 'light_mode' : 'dark_mode'\r\n }}</span> {{ isDarkMode() ? 'Modo Claro' : 'Modo Oscuro' }}\r\n </button>\r\n <div class=\"border-t border-slate-100 my-1\"></div>\r\n <button (click)=\"onLogoutClick()\"\r\n class=\"w-full text-left px-4 py-2 text-sm text-rose-600 hover:bg-rose-50 transition-colors flex items-center font-medium\">\r\n <span class=\"material-icons-outlined text-lg mr-2\">logout</span> Cerrar Sesi\u00F3n\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n</header>", dependencies: [{ kind: "ngmodule", type: CommonModule }] });
482
1991
  }
483
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcModalComponent, decorators: [{
1992
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdHeaderComponent, decorators: [{
484
1993
  type: Component,
485
- args: [{ selector: 'cc-modal', standalone: true, imports: [CommonModule, CcIconComponent], template: "<div class=\"cc-modal-overlay\" *ngIf=\"isOpen\" (click)=\"onOverlayClick($event)\">\r\n\r\n <div class=\"cc-modal\" [ngClass]=\"'size-' + size\" role=\"dialog\" aria-modal=\"true\">\r\n\r\n <header class=\"cc-modal-header\">\r\n <h3 class=\"cc-modal-title\">{{ title }}</h3>\r\n <button class=\"cc-modal-close\" (click)=\"close.emit()\" type=\"button\">\r\n <cc-icon name=\"close\" size=\"md\"></cc-icon>\r\n </button>\r\n </header>\r\n\r\n <div class=\"cc-modal-body\">\r\n <ng-content></ng-content>\r\n </div>\r\n\r\n <footer class=\"cc-modal-footer\" *ngIf=\"showFooter\">\r\n <ng-content select=\"[footer]\"></ng-content>\r\n </footer>\r\n </div>\r\n</div>", styles: [".cc-modal-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:var(--modal-overlay-bg);display:flex;align-items:center;justify-content:center;z-index:var(--modal-z-index);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);padding:var(--space-4)}.cc-modal{background-color:var(--modal-bg);border-radius:var(--modal-radius);box-shadow:var(--modal-shadow);display:flex;flex-direction:column;max-height:90vh;width:100%;animation:modalScaleUp .2s ease-out;overflow:hidden}.cc-modal.size-sm{max-width:var(--modal-sm-width)}.cc-modal.size-md{max-width:var(--modal-md-width)}.cc-modal.size-lg{max-width:var(--modal-lg-width)}.cc-modal-header{padding:var(--modal-header-padding);display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--color-border-subtle)}.cc-modal-title{font-size:var(--font-size-lg);font-weight:var(--font-weight-bold);color:var(--color-text-primary);margin:0}.cc-modal-close{background:transparent;border:none;color:var(--color-text-muted);cursor:pointer;padding:var(--space-1);border-radius:var(--radius-md);display:flex;transition:all .15s ease}.cc-modal-close:hover{background-color:var(--color-bg-secondary);color:var(--color-text-primary)}.cc-modal-body{padding:var(--modal-body-padding);overflow-y:auto;flex:1}.cc-modal-footer{padding:var(--modal-footer-padding);border-top:1px solid var(--color-border-subtle);display:flex;justify-content:flex-end;gap:var(--space-3);background-color:var(--color-bg-secondary)}@keyframes modalScaleUp{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}\n"] }]
486
- }], propDecorators: { isOpen: [{
487
- type: Input
488
- }], title: [{
489
- type: Input
490
- }], size: [{
491
- type: Input
492
- }], closeOnOverlay: [{
493
- type: Input
494
- }], showFooter: [{
495
- type: Input
496
- }], close: [{
497
- type: Output
498
- }], onEscape: [{
499
- type: HostListener,
500
- args: ['document:keydown.escape']
501
- }] } });
1994
+ args: [{ selector: 'ad-header', standalone: true, imports: [CommonModule], template: "<header class=\"sticky top-0 z-20 flex items-center justify-between px-6 h-16 \r\n bg-white/80 backdrop-blur-xl border-b border-white/20\r\n shadow-[0_4px_30px_rgba(0,0,0,0.05)] transition-all duration-300\">\r\n <div class=\"flex items-center gap-4 flex-1\">\r\n <!-- Mobile Menu -->\r\n <button (click)=\"onToggleMobileMenu()\"\r\n class=\"md:hidden p-2 text-slate-600 hover:bg-slate-100 rounded-xl transition-all active:scale-95 shadow-sm bg-white border border-slate-100\">\r\n <span class=\"material-icons-outlined\">menu</span>\r\n </button>\r\n\r\n <!-- Desktop Toggle -->\r\n <button (click)=\"onToggleSidebar()\"\r\n class=\"hidden md:flex p-2 text-slate-600 hover:bg-slate-100 rounded-xl transition-all active:scale-95 shadow-sm bg-white border border-slate-100\">\r\n <span class=\"material-icons-outlined\">menu_open</span>\r\n </button>\r\n\r\n <!-- Search Bar -->\r\n <div\r\n class=\"relative flex items-center transition-all duration-300 w-48 md:w-64 focus-within:w-full focus-within:max-w-md\">\r\n <span\r\n class=\"material-icons-outlined absolute left-3 transition-colors text-slate-400 group-focus-within:text-blue-500\">search</span>\r\n <input type=\"text\" placeholder=\"Buscar en Cerca...\"\r\n class=\"w-full bg-slate-50 border border-slate-200 rounded-xl py-2 pl-10 pr-4 text-sm focus:outline-none focus:ring-4 focus:ring-blue-500/10 focus:bg-white transition-all shadow-inner placeholder:text-slate-400 text-slate-600\" />\r\n </div>\r\n </div>\r\n\r\n <!-- Header Right -->\r\n <div class=\"flex items-center gap-3\">\r\n <!-- Notifications -->\r\n <button\r\n class=\"relative p-2.5 text-slate-500 hover:bg-slate-100 rounded-xl transition-all bg-white border border-slate-100 shadow-sm group\">\r\n <span class=\"material-icons-outlined group-hover:text-blue-500 transition-colors\">notifications</span>\r\n @if (notificationsCount() > 0) {\r\n <span class=\"absolute top-2 right-2 w-2.5 h-2.5 bg-red-500 rounded-full border-2 border-white\"></span>\r\n }\r\n </button>\r\n\r\n <div class=\"h-8 w-[1px] bg-slate-200 mx-1\"></div>\r\n\r\n <!-- User Profile -->\r\n <div class=\"flex items-center gap-3 pl-1 group cursor-pointer\" (click)=\"toggleUserMenu()\">\r\n <div class=\"text-right hidden sm:block\">\r\n <p class=\"text-sm font-bold text-slate-700 leading-none group-hover:text-blue-600 transition-colors\">\r\n {{ user().name }}</p>\r\n <p class=\"text-[10px] text-slate-400 font-bold mt-1 tracking-tighter uppercase\">{{ user().role\r\n }}</p>\r\n </div>\r\n <!-- Gradient Avatar -->\r\n <div\r\n class=\"h-10 w-10 rounded-xl bg-gradient-to-tr from-blue-600 to-blue-400 flex items-center justify-center text-white shadow-lg shadow-blue-200 transition-transform group-hover:scale-105\">\r\n @if (user().avatarUrl) {\r\n <img [src]=\"user().avatarUrl\" alt=\"Avatar\"\r\n class=\"h-full w-full rounded-xl object-cover opacity-90 hover:opacity-100\">\r\n } @else {\r\n <span class=\"material-icons-outlined text-sm\">person</span>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Dropdown Menu (Existing logic) -->\r\n @if (isUserMenuOpen()) {\r\n <div class=\"fixed inset-0 z-40\" (click)=\"closeUserMenu()\"></div>\r\n <div\r\n class=\"absolute top-16 right-6 w-48 bg-white dark:bg-cerca-navy rounded-xl shadow-xl py-1 border border-slate-100 ring-1 ring-black ring-opacity-5 animate-fade-in-down z-50\">\r\n <button (click)=\"onProfileClick()\"\r\n class=\"w-full text-left px-4 py-2 text-sm text-slate-700 hover:bg-slate-50 hover:text-blue-600 transition-colors flex items-center font-medium\">\r\n <span class=\"material-icons-outlined text-lg mr-2\">person</span> Perfil\r\n </button>\r\n <button (click)=\"onToggleThemeClick()\"\r\n class=\"w-full text-left px-4 py-2 text-sm text-slate-700 hover:bg-slate-50 hover:text-blue-600 transition-colors flex items-center font-medium\">\r\n <span class=\"material-icons-outlined text-lg mr-2\">{{ isDarkMode() ? 'light_mode' : 'dark_mode'\r\n }}</span> {{ isDarkMode() ? 'Modo Claro' : 'Modo Oscuro' }}\r\n </button>\r\n <div class=\"border-t border-slate-100 my-1\"></div>\r\n <button (click)=\"onLogoutClick()\"\r\n class=\"w-full text-left px-4 py-2 text-sm text-rose-600 hover:bg-rose-50 transition-colors flex items-center font-medium\">\r\n <span class=\"material-icons-outlined text-lg mr-2\">logout</span> Cerrar Sesi\u00F3n\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n</header>" }]
1995
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], toggleSidebar: [{ type: i0.Output, args: ["toggleSidebar"] }], toggleMobileMenu: [{ type: i0.Output, args: ["toggleMobileMenu"] }], logout: [{ type: i0.Output, args: ["logout"] }], navigateProfile: [{ type: i0.Output, args: ["navigateProfile"] }], toggleTheme: [{ type: i0.Output, args: ["toggleTheme"] }] } });
502
1996
 
503
- class CcLoginComponent {
504
- constructor() {
505
- this.fb = inject(FormBuilder);
506
- this.title = 'Bienvenido';
507
- this.subtitle = 'Inicia sesión para continuar';
508
- this.loading = false;
509
- this.errorMessage = null;
510
- this.supportEmail = 'soporte@cerca.com.co';
511
- this.forgotPasswordLabel = '¿Olvidaste tu clave?';
512
- this.loginSubmit = new EventEmitter();
513
- this.forgotPasswordClick = new EventEmitter();
514
- this.loginForm = this.fb.group({
515
- email: ['', [Validators.required, Validators.email]],
516
- password: ['', [Validators.required]],
517
- remember: [true]
518
- });
519
- }
1997
+ const UserSchema = z.object({
1998
+ name: z.string(),
1999
+ role: z.string(),
2000
+ avatarUrl: z.string().optional(),
2001
+ });
2002
+ const HeaderResourceSchema = z.object({
2003
+ user: UserSchema,
2004
+ notificationsCount: z.number().default(0).optional(),
2005
+ });
2006
+
2007
+ class AdLoginComponent {
2008
+ fb = inject(FormBuilder);
2009
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
2010
+ title = computed(() => this.resource().title ?? 'Bienvenido', ...(ngDevMode ? [{ debugName: "title" }] : []));
2011
+ titleAccent = computed(() => this.resource().titleAccent, ...(ngDevMode ? [{ debugName: "titleAccent" }] : []));
2012
+ subtitle = computed(() => this.resource().subtitle ?? 'Inicia sesión para continuar', ...(ngDevMode ? [{ debugName: "subtitle" }] : []));
2013
+ logo = computed(() => this.resource().logo, ...(ngDevMode ? [{ debugName: "logo" }] : []));
2014
+ icon = computed(() => this.resource().icon, ...(ngDevMode ? [{ debugName: "icon" }] : []));
2015
+ loading = computed(() => this.resource().loading ?? false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
2016
+ errorMessage = computed(() => this.resource().errorMessage ?? null, ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
2017
+ supportEmail = computed(() => this.resource().supportEmail ?? 'soporte@cerca.com.co', ...(ngDevMode ? [{ debugName: "supportEmail" }] : []));
2018
+ recoverPasswordUrl = computed(() => this.resource().recoverPasswordUrl, ...(ngDevMode ? [{ debugName: "recoverPasswordUrl" }] : []));
2019
+ forgotPasswordLabel = computed(() => this.resource().forgotPasswordLabel ?? '¿Olvidaste tu clave?', ...(ngDevMode ? [{ debugName: "forgotPasswordLabel" }] : []));
2020
+ loginSubmit = output();
2021
+ forgotPasswordClick = output();
2022
+ loginForm = this.fb.group({
2023
+ email: ['', [Validators.required, Validators.email]],
2024
+ password: ['', [Validators.required]],
2025
+ remember: [true]
2026
+ });
520
2027
  submitForm() {
521
2028
  if (this.loginForm.valid) {
522
2029
  const { email, password, remember } = this.loginForm.getRawValue();
@@ -535,127 +2042,445 @@ class CcLoginComponent {
535
2042
  const control = this.loginForm.get(field);
536
2043
  return (control && control.invalid && (control.dirty || control.touched)) || false;
537
2044
  }
538
- onForgotPassword() {
539
- this.forgotPasswordClick.emit();
540
- }
541
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcLoginComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
542
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: CcLoginComponent, isStandalone: true, selector: "cc-login", inputs: { title: "title", titleAccent: "titleAccent", subtitle: "subtitle", logoUrl: "logoUrl", icon: "icon", loading: "loading", errorMessage: "errorMessage", supportEmail: "supportEmail", recoverPasswordUrl: "recoverPasswordUrl", forgotPasswordLabel: "forgotPasswordLabel" }, outputs: { loginSubmit: "loginSubmit", forgotPasswordClick: "forgotPasswordClick" }, ngImport: i0, template: "<div class=\"login-container\">\r\n <div class=\"login-card\">\r\n <div class=\"login-header\">\r\n @if (logoUrl) {\r\n <img [src]=\"logoUrl\" alt=\"Logo\" class=\"logo\" />\r\n } @else if (icon) {\r\n <div class=\"logo-box\">\r\n <span nz-icon [nzType]=\"icon\" nzTheme=\"fill\"></span>\r\n </div>\r\n }\r\n <h2 class=\"title\">\r\n {{ title }}\r\n @if (titleAccent) {\r\n <span class=\"accent\">{{ titleAccent }}</span>\r\n }\r\n </h2>\r\n <p class=\"subtitle text-uppercase\">{{ subtitle }}</p>\r\n </div>\r\n\r\n @if (errorMessage) {\r\n <nz-alert nzType=\"error\" [nzMessage]=\"errorMessage\" nzShowIcon class=\"error-alert\"></nz-alert>\r\n }\r\n\r\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"submitForm()\" class=\"login-form\">\r\n <div class=\"form-group\">\r\n <cc-input formControlName=\"email\" placeholder=\"correo@ejemplo.com\" label=\"Correo Electr\u00F3nico\"\r\n type=\"email\" prefix=\"mail\" [error]=\"fieldInvalid('email')\">\r\n </cc-input>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <cc-input formControlName=\"password\" placeholder=\"********\" label=\"Contrase\u00F1a\" type=\"password\"\r\n prefix=\"lock\" [error]=\"fieldInvalid('password')\">\r\n </cc-input>\r\n </div>\r\n\r\n <div class=\"form-actions-row\">\r\n <label nz-checkbox formControlName=\"remember\">Recordarme</label>\r\n @if (recoverPasswordUrl) {\r\n <a [href]=\"recoverPasswordUrl\" class=\"forgot-password\">{{ forgotPasswordLabel }}</a>\r\n } @else {\r\n <a class=\"forgot-password\" (click)=\"forgotPasswordClick.emit()\">{{ forgotPasswordLabel }}</a>\r\n }\r\n </div>\r\n\r\n <cc-button [loading]=\"loading\" variant=\"primary\" type=\"submit\" class=\"submit-button\"\r\n [disabled]=\"loginForm.invalid || loading\">\r\n Iniciar Sesi\u00F3n\r\n </cc-button>\r\n </form>\r\n\r\n <div class=\"login-footer\">\r\n <p>\u00BFNecesitas ayuda? Contacta a <a [href]=\"'mailto:' + supportEmail\">{{ supportEmail }}</a></p>\r\n </div>\r\n </div>\r\n</div>", styles: [":host{display:block;height:100%;width:100%}.login-container{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100vw;overflow:hidden;background:radial-gradient(circle at top left,#0284c7,#001529);padding:1rem;box-sizing:border-box}.login-card{width:100%;max-width:380px;padding:24px;background:#fff;border-radius:8px;box-shadow:0 12px 48px #0000004d;animation:fadeIn .5s ease-out}.login-header{text-align:center;margin-bottom:24px}.login-header .logo-box{width:40px;height:40px;background:#0284c7;color:#fff;font-size:20px;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;margin-bottom:12px}.login-header .logo{max-height:60px;margin-bottom:1rem;object-fit:contain}.login-header .title{font-size:20px;font-weight:700;color:#001529;margin:0;line-height:1.2}.login-header .title .accent{color:#0284c7;font-style:italic}.login-header .subtitle{font-size:10px;letter-spacing:2px;color:#8c8c8c;margin-top:4px}.error-alert{margin-bottom:16px;border-radius:4px}.login-form{display:flex;flex-direction:column;gap:16px}.form-group{display:flex;flex-direction:column;gap:4px}.error-message{color:#ff4d4f;font-size:12px;margin-top:2px;animation:slideDown .2s ease-out}.form-actions-row{display:flex;justify-content:space-between;align-items:center;font-size:12px;margin-bottom:8px}.form-actions-row ::ng-deep .ant-checkbox-wrapper span{color:#000000d9}.form-actions-row .forgot-password{color:#0284c7;text-decoration:none;cursor:pointer}.form-actions-row .forgot-password:hover{color:#0050b3;text-decoration:underline}.submit-button{width:100%;margin-top:8px}.submit-button ::ng-deep button{width:100%;height:36px;font-size:14px;font-weight:600;border-radius:4px}.login-footer{margin-top:24px;text-align:center;color:#bfbfbf;font-size:10px}.login-footer p{margin:2px 0}.login-footer a{color:#8c8c8c;text-decoration:none}.login-footer a:hover{color:#0284c7}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes slideDown{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: CcInputComponent, selector: "cc-input", inputs: ["type", "placeholder", "label", "error", "disabled", "size", "prefix", "suffix"] }, { kind: "component", type: CcButtonComponent, selector: "cc-button", inputs: ["variant", "type", "disabled", "loading", "icon", "size"] }, { kind: "ngmodule", type: NzAlertModule }, { kind: "component", type: i2$2.NzAlertComponent, selector: "nz-alert", inputs: ["nzAction", "nzCloseText", "nzIconType", "nzMessage", "nzDescription", "nzType", "nzCloseable", "nzShowIcon", "nzBanner", "nzNoAnimation", "nzIcon"], outputs: ["nzOnClose"], exportAs: ["nzAlert"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i3$1.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzCheckboxModule }, { kind: "component", type: i4.NzCheckboxComponent, selector: "[nz-checkbox]", inputs: ["nzValue", "nzAutoFocus", "nzDisabled", "nzIndeterminate", "nzChecked", "nzId", "nzName"], outputs: ["nzCheckedChange"], exportAs: ["nzCheckbox"] }] }); }
2045
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdLoginComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2046
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdLoginComponent, isStandalone: true, selector: "ad-login", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { loginSubmit: "loginSubmit", forgotPasswordClick: "forgotPasswordClick" }, ngImport: i0, template: "<div class=\"w-full max-w-md space-y-8 bg-white p-8 rounded-xl shadow-lg border border-slate-100\">\r\n <div class=\"text-center\">\r\n @if (logo()) {\r\n <img [src]=\"logo()\" alt=\"Logo\" class=\"mx-auto h-12 w-auto\" />\r\n } @else if (icon()) {\r\n <div class=\"mx-auto h-12 w-12 flex items-center justify-center rounded-full bg-sky-100 text-sky-600\">\r\n <!-- Fallback icon or remove nz-icon -->\r\n <span class=\"text-2xl font-bold\">C</span>\r\n </div>\r\n }\r\n <h2 class=\"mt-6 text-3xl font-extrabold text-cerca-navy\">\r\n {{ title() }}\r\n @if (titleAccent()) {\r\n <span class=\"accent-text\">{{ titleAccent() }}</span>\r\n }\r\n </h2>\r\n <p class=\"mt-2 text-sm text-slate-600 uppercase tracking-wide\">{{ subtitle() }}</p>\r\n </div>\r\n\r\n @if (errorMessage()) {\r\n <div class=\"bg-red-50 border-l-4 border-red-500 p-4 mb-4 rounded-md\">\r\n <div class=\"flex\">\r\n <div class=\"ml-3\">\r\n <p class=\"text-sm text-red-700\">{{ errorMessage() }}</p>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n <form [formGroup]=\"loginForm\" class=\"mt-8 space-y-6\" (ngSubmit)=\"submitForm()\">\r\n <div class=\"space-y-4\">\r\n <div class=\"form-group\">\r\n <ad-input formControlName=\"email\" placeholder=\"correo@ejemplo.com\" label=\"Correo Electr\u00F3nico\"\r\n type=\"email\" prefix=\"user\" [error]=\"fieldInvalid('email')\">\r\n </ad-input>\r\n @if (fieldInvalid('email')) {\r\n <p class=\"mt-1 text-sm text-red-600\">\r\n @if (loginForm.get('email')?.hasError('required')) { El campo es requerido }\r\n @else { Ingrese un correo v\u00E1lido }\r\n </p>\r\n }\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <ad-input formControlName=\"password\" placeholder=\"********\" label=\"Contrase\u00F1a\" type=\"password\"\r\n prefix=\"lock\" [error]=\"fieldInvalid('password')\">\r\n </ad-input>\r\n @if (fieldInvalid('password')) {\r\n <p class=\"mt-1 text-sm text-red-600\">\r\n La contrase\u00F1a es requerida\r\n </p>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"flex items-center justify-between\">\r\n <div class=\"flex items-center\">\r\n <input id=\"remember-me\" formControlName=\"remember\" type=\"checkbox\"\r\n class=\"h-4 w-4 rounded border-slate-300 text-sky-600 focus:ring-sky-600\">\r\n <label for=\"remember-me\" class=\"ml-2 block text-sm text-slate-900\">Recordarme</label>\r\n </div>\r\n\r\n @if (recoverPasswordUrl()) {\r\n <a [href]=\"recoverPasswordUrl()\" class=\"text-sm font-medium text-sky-600 hover:text-sky-500\">\r\n {{ forgotPasswordLabel() }}\r\n </a>\r\n } @else {\r\n <a class=\"text-sm font-medium text-sky-600 hover:text-sky-500 cursor-pointer\"\r\n (click)=\"forgotPasswordClick.emit()\">\r\n {{ forgotPasswordLabel() }}\r\n </a>\r\n }\r\n </div>\r\n\r\n <div>\r\n <div>\r\n <ad-button [loading]=\"loading()\" variant=\"primary\" type=\"submit\" [block]=\"true\"\r\n class=\"w-full justify-center\" [disabled]=\"loginForm.invalid || loading()\">\r\n Iniciar Sesi\u00F3n\r\n </ad-button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"mt-6 text-center text-xs text-slate-400\">\r\n <p>\u00BFNecesitas ayuda? Contacta a <a [href]=\"'mailto:' + supportEmail()\"\r\n class=\"hover:text-sky-600 transition-colors\">{{ supportEmail() }}</a></p>\r\n </div>\r\n</div>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: AdInputComponent, selector: "ad-input", inputs: ["type", "placeholder", "label", "error", "rows", "disabled", "size", "prefix", "suffix"] }, { kind: "component", type: AdButtonComponent, selector: "ad-button", inputs: ["variant", "type", "disabled", "loading", "icon", "size", "block"] }] });
543
2047
  }
544
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcLoginComponent, decorators: [{
2048
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdLoginComponent, decorators: [{
545
2049
  type: Component,
546
- args: [{ selector: 'cc-login', standalone: true, imports: [
2050
+ args: [{ selector: 'ad-login', standalone: true, imports: [
547
2051
  CommonModule,
548
2052
  ReactiveFormsModule,
549
- CcInputComponent,
550
- CcButtonComponent,
551
- NzAlertModule,
552
- NzIconModule,
553
- NzCheckboxModule,
554
- NzFormDirective,
555
- NzFormControlComponent,
556
- NzFormLabelComponent,
557
- NzFormItemComponent
558
- ], template: "<div class=\"login-container\">\r\n <div class=\"login-card\">\r\n <div class=\"login-header\">\r\n @if (logoUrl) {\r\n <img [src]=\"logoUrl\" alt=\"Logo\" class=\"logo\" />\r\n } @else if (icon) {\r\n <div class=\"logo-box\">\r\n <span nz-icon [nzType]=\"icon\" nzTheme=\"fill\"></span>\r\n </div>\r\n }\r\n <h2 class=\"title\">\r\n {{ title }}\r\n @if (titleAccent) {\r\n <span class=\"accent\">{{ titleAccent }}</span>\r\n }\r\n </h2>\r\n <p class=\"subtitle text-uppercase\">{{ subtitle }}</p>\r\n </div>\r\n\r\n @if (errorMessage) {\r\n <nz-alert nzType=\"error\" [nzMessage]=\"errorMessage\" nzShowIcon class=\"error-alert\"></nz-alert>\r\n }\r\n\r\n <form [formGroup]=\"loginForm\" (ngSubmit)=\"submitForm()\" class=\"login-form\">\r\n <div class=\"form-group\">\r\n <cc-input formControlName=\"email\" placeholder=\"correo@ejemplo.com\" label=\"Correo Electr\u00F3nico\"\r\n type=\"email\" prefix=\"mail\" [error]=\"fieldInvalid('email')\">\r\n </cc-input>\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <cc-input formControlName=\"password\" placeholder=\"********\" label=\"Contrase\u00F1a\" type=\"password\"\r\n prefix=\"lock\" [error]=\"fieldInvalid('password')\">\r\n </cc-input>\r\n </div>\r\n\r\n <div class=\"form-actions-row\">\r\n <label nz-checkbox formControlName=\"remember\">Recordarme</label>\r\n @if (recoverPasswordUrl) {\r\n <a [href]=\"recoverPasswordUrl\" class=\"forgot-password\">{{ forgotPasswordLabel }}</a>\r\n } @else {\r\n <a class=\"forgot-password\" (click)=\"forgotPasswordClick.emit()\">{{ forgotPasswordLabel }}</a>\r\n }\r\n </div>\r\n\r\n <cc-button [loading]=\"loading\" variant=\"primary\" type=\"submit\" class=\"submit-button\"\r\n [disabled]=\"loginForm.invalid || loading\">\r\n Iniciar Sesi\u00F3n\r\n </cc-button>\r\n </form>\r\n\r\n <div class=\"login-footer\">\r\n <p>\u00BFNecesitas ayuda? Contacta a <a [href]=\"'mailto:' + supportEmail\">{{ supportEmail }}</a></p>\r\n </div>\r\n </div>\r\n</div>", styles: [":host{display:block;height:100%;width:100%}.login-container{display:flex;justify-content:center;align-items:center;min-height:100vh;width:100vw;overflow:hidden;background:radial-gradient(circle at top left,#0284c7,#001529);padding:1rem;box-sizing:border-box}.login-card{width:100%;max-width:380px;padding:24px;background:#fff;border-radius:8px;box-shadow:0 12px 48px #0000004d;animation:fadeIn .5s ease-out}.login-header{text-align:center;margin-bottom:24px}.login-header .logo-box{width:40px;height:40px;background:#0284c7;color:#fff;font-size:20px;border-radius:8px;display:inline-flex;align-items:center;justify-content:center;margin-bottom:12px}.login-header .logo{max-height:60px;margin-bottom:1rem;object-fit:contain}.login-header .title{font-size:20px;font-weight:700;color:#001529;margin:0;line-height:1.2}.login-header .title .accent{color:#0284c7;font-style:italic}.login-header .subtitle{font-size:10px;letter-spacing:2px;color:#8c8c8c;margin-top:4px}.error-alert{margin-bottom:16px;border-radius:4px}.login-form{display:flex;flex-direction:column;gap:16px}.form-group{display:flex;flex-direction:column;gap:4px}.error-message{color:#ff4d4f;font-size:12px;margin-top:2px;animation:slideDown .2s ease-out}.form-actions-row{display:flex;justify-content:space-between;align-items:center;font-size:12px;margin-bottom:8px}.form-actions-row ::ng-deep .ant-checkbox-wrapper span{color:#000000d9}.form-actions-row .forgot-password{color:#0284c7;text-decoration:none;cursor:pointer}.form-actions-row .forgot-password:hover{color:#0050b3;text-decoration:underline}.submit-button{width:100%;margin-top:8px}.submit-button ::ng-deep button{width:100%;height:36px;font-size:14px;font-weight:600;border-radius:4px}.login-footer{margin-top:24px;text-align:center;color:#bfbfbf;font-size:10px}.login-footer p{margin:2px 0}.login-footer a{color:#8c8c8c;text-decoration:none}.login-footer a:hover{color:#0284c7}@keyframes fadeIn{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes slideDown{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}\n"] }]
559
- }], propDecorators: { title: [{
560
- type: Input
561
- }], titleAccent: [{
562
- type: Input
563
- }], subtitle: [{
564
- type: Input
565
- }], logoUrl: [{
566
- type: Input
567
- }], icon: [{
568
- type: Input
569
- }], loading: [{
570
- type: Input
571
- }], errorMessage: [{
572
- type: Input
573
- }], supportEmail: [{
574
- type: Input
575
- }], recoverPasswordUrl: [{
576
- type: Input
577
- }], forgotPasswordLabel: [{
578
- type: Input
579
- }], loginSubmit: [{
580
- type: Output
581
- }], forgotPasswordClick: [{
582
- type: Output
583
- }] } });
2053
+ AdInputComponent,
2054
+ AdButtonComponent
2055
+ ], template: "<div class=\"w-full max-w-md space-y-8 bg-white p-8 rounded-xl shadow-lg border border-slate-100\">\r\n <div class=\"text-center\">\r\n @if (logo()) {\r\n <img [src]=\"logo()\" alt=\"Logo\" class=\"mx-auto h-12 w-auto\" />\r\n } @else if (icon()) {\r\n <div class=\"mx-auto h-12 w-12 flex items-center justify-center rounded-full bg-sky-100 text-sky-600\">\r\n <!-- Fallback icon or remove nz-icon -->\r\n <span class=\"text-2xl font-bold\">C</span>\r\n </div>\r\n }\r\n <h2 class=\"mt-6 text-3xl font-extrabold text-cerca-navy\">\r\n {{ title() }}\r\n @if (titleAccent()) {\r\n <span class=\"accent-text\">{{ titleAccent() }}</span>\r\n }\r\n </h2>\r\n <p class=\"mt-2 text-sm text-slate-600 uppercase tracking-wide\">{{ subtitle() }}</p>\r\n </div>\r\n\r\n @if (errorMessage()) {\r\n <div class=\"bg-red-50 border-l-4 border-red-500 p-4 mb-4 rounded-md\">\r\n <div class=\"flex\">\r\n <div class=\"ml-3\">\r\n <p class=\"text-sm text-red-700\">{{ errorMessage() }}</p>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n\r\n <form [formGroup]=\"loginForm\" class=\"mt-8 space-y-6\" (ngSubmit)=\"submitForm()\">\r\n <div class=\"space-y-4\">\r\n <div class=\"form-group\">\r\n <ad-input formControlName=\"email\" placeholder=\"correo@ejemplo.com\" label=\"Correo Electr\u00F3nico\"\r\n type=\"email\" prefix=\"user\" [error]=\"fieldInvalid('email')\">\r\n </ad-input>\r\n @if (fieldInvalid('email')) {\r\n <p class=\"mt-1 text-sm text-red-600\">\r\n @if (loginForm.get('email')?.hasError('required')) { El campo es requerido }\r\n @else { Ingrese un correo v\u00E1lido }\r\n </p>\r\n }\r\n </div>\r\n\r\n <div class=\"form-group\">\r\n <ad-input formControlName=\"password\" placeholder=\"********\" label=\"Contrase\u00F1a\" type=\"password\"\r\n prefix=\"lock\" [error]=\"fieldInvalid('password')\">\r\n </ad-input>\r\n @if (fieldInvalid('password')) {\r\n <p class=\"mt-1 text-sm text-red-600\">\r\n La contrase\u00F1a es requerida\r\n </p>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"flex items-center justify-between\">\r\n <div class=\"flex items-center\">\r\n <input id=\"remember-me\" formControlName=\"remember\" type=\"checkbox\"\r\n class=\"h-4 w-4 rounded border-slate-300 text-sky-600 focus:ring-sky-600\">\r\n <label for=\"remember-me\" class=\"ml-2 block text-sm text-slate-900\">Recordarme</label>\r\n </div>\r\n\r\n @if (recoverPasswordUrl()) {\r\n <a [href]=\"recoverPasswordUrl()\" class=\"text-sm font-medium text-sky-600 hover:text-sky-500\">\r\n {{ forgotPasswordLabel() }}\r\n </a>\r\n } @else {\r\n <a class=\"text-sm font-medium text-sky-600 hover:text-sky-500 cursor-pointer\"\r\n (click)=\"forgotPasswordClick.emit()\">\r\n {{ forgotPasswordLabel() }}\r\n </a>\r\n }\r\n </div>\r\n\r\n <div>\r\n <div>\r\n <ad-button [loading]=\"loading()\" variant=\"primary\" type=\"submit\" [block]=\"true\"\r\n class=\"w-full justify-center\" [disabled]=\"loginForm.invalid || loading()\">\r\n Iniciar Sesi\u00F3n\r\n </ad-button>\r\n </div>\r\n </div>\r\n </form>\r\n\r\n <div class=\"mt-6 text-center text-xs text-slate-400\">\r\n <p>\u00BFNecesitas ayuda? Contacta a <a [href]=\"'mailto:' + supportEmail()\"\r\n class=\"hover:text-sky-600 transition-colors\">{{ supportEmail() }}</a></p>\r\n </div>\r\n</div>" }]
2056
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], loginSubmit: [{ type: i0.Output, args: ["loginSubmit"] }], forgotPasswordClick: [{ type: i0.Output, args: ["forgotPasswordClick"] }] } });
584
2057
 
585
- class CcContainerComponent {
586
- constructor() {
587
- this.fluid = false;
588
- this.size = 'xl';
2058
+ const LoginResourceSchema = z.object({
2059
+ title: z.string().default('Bienvenido').optional(),
2060
+ titleAccent: z.string().optional(),
2061
+ subtitle: z.string().default('Inicia sesión para continuar').optional(),
2062
+ logo: z.string().optional(),
2063
+ icon: z.string().optional(),
2064
+ loading: z.boolean().default(false).optional(),
2065
+ errorMessage: z.string().nullable().optional(),
2066
+ supportEmail: z.string().default('soporte@cerca.com.co').optional(),
2067
+ recoverPasswordUrl: z.string().optional(),
2068
+ forgotPasswordLabel: z.string().default('¿Olvidaste tu clave?').optional(),
2069
+ });
2070
+
2071
+ const ModalResourceSchema = z.object({
2072
+ isOpen: z.boolean().default(false).optional(),
2073
+ title: z.string().default('').optional(),
2074
+ accentedTitle: z.string().optional(),
2075
+ size: z.enum(['sm', 'md', 'lg']).default('md').optional(),
2076
+ closeOnOverlay: z.boolean().default(true).optional(),
2077
+ showFooter: z.boolean().default(true).optional()
2078
+ });
2079
+
2080
+ class AdSidebarComponent {
2081
+ router;
2082
+ // Inputs as Signals
2083
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
2084
+ menuItems = computed(() => this.resource().menuItems, ...(ngDevMode ? [{ debugName: "menuItems" }] : []));
2085
+ collapsed = computed(() => this.resource().collapsed ?? false, ...(ngDevMode ? [{ debugName: "collapsed" }] : []));
2086
+ // Outputs
2087
+ toggleCollapse = output();
2088
+ navigate = output();
2089
+ // State
2090
+ expandedItems = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedItems" }] : []));
2091
+ constructor(router) {
2092
+ this.router = router;
2093
+ }
2094
+ onItemClick(item) {
2095
+ if (item.children && item.children.length > 0) {
2096
+ this.toggleSubmenu(item);
2097
+ }
2098
+ else if (item.route) {
2099
+ this.navigate.emit(item);
2100
+ }
2101
+ }
2102
+ toggleSubmenu(item) {
2103
+ if (this.collapsed()) {
2104
+ this.toggleCollapse.emit(); // Expand sidebar if clicking a submenu parent while collapsed
2105
+ // layout logic usually handles this, but good to emit
2106
+ }
2107
+ this.expandedItems.update(current => {
2108
+ const newSet = new Set(current);
2109
+ if (newSet.has(item.label)) {
2110
+ newSet.delete(item.label);
2111
+ }
2112
+ else {
2113
+ newSet.add(item.label);
2114
+ }
2115
+ return newSet;
2116
+ });
2117
+ }
2118
+ isExpanded(item) {
2119
+ return this.expandedItems().has(item.label);
589
2120
  }
590
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
591
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcContainerComponent, isStandalone: true, selector: "cc-container", inputs: { fluid: "fluid", size: "size" }, ngImport: i0, template: "<div class=\"cc-container\" [class.cc-container-fluid]=\"fluid\" [ngClass]=\"'size-' + size\">\r\n <ng-content></ng-content>\r\n</div>", styles: [".cc-container{width:100%;margin-right:auto;margin-left:auto;padding-right:var(--space-4);padding-left:var(--space-4)}@media(min-width:768px){.cc-container{padding-right:var(--space-6);padding-left:var(--space-6)}}@media(min-width:1280px){.cc-container{padding-right:var(--space-8);padding-left:var(--space-8)}}.cc-container.cc-container-fluid{max-width:none!important}.cc-container.size-sm{max-width:640px}.cc-container.size-md{max-width:768px}.cc-container.size-lg{max-width:1024px}.cc-container.size-xl{max-width:1280px}.cc-container.size-2xl{max-width:1536px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
2121
+ hasActiveChild(item) {
2122
+ if (!item.children)
2123
+ return false;
2124
+ return item.children.some((child) => {
2125
+ if (child.route) {
2126
+ return this.router.isActive(child.route, {
2127
+ paths: 'subset',
2128
+ queryParams: 'ignored',
2129
+ fragment: 'ignored',
2130
+ matrixParams: 'ignored'
2131
+ });
2132
+ }
2133
+ return false;
2134
+ });
2135
+ }
2136
+ onToggle() {
2137
+ this.toggleCollapse.emit();
2138
+ }
2139
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdSidebarComponent, deps: [{ token: i1$2.Router }], target: i0.ɵɵFactoryTarget.Component });
2140
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdSidebarComponent, isStandalone: true, selector: "ad-sidebar", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { toggleCollapse: "toggleCollapse", navigate: "navigate" }, ngImport: i0, template: "<aside\r\n class=\"flex flex-col bg-[#002B5B] text-white transition-all duration-300 ease-in-out h-full z-30 shadow-[10px_0_40px_-15px_rgba(0,0,0,0.3)] border-r border-white/5\"\r\n [class.w-72]=\"!collapsed()\" [class.w-20]=\"collapsed()\">\r\n\r\n <!-- Logo Area -->\r\n <div\r\n class=\"p-4 flex items-center justify-center border-b border-white/5 h-20 transition-all duration-300 flex-shrink-0\">\r\n @if (collapsed()) {\r\n <!-- Isotipo (C) -->\r\n <div\r\n class=\"w-10 h-10 bg-blue-500 rounded-lg flex items-center justify-center font-bold text-lg shadow-lg animate-in fade-in zoom-in-75\">\r\n C\r\n </div>\r\n } @else {\r\n <!-- Logo Completo -->\r\n <div class=\"flex items-center gap-2 animate-in fade-in slide-in-from-left-4 duration-500\">\r\n <span class=\"text-xl font-bold tracking-tight text-blue-400\">Cerca</span>\r\n <span\r\n class=\"text-[9px] font-bold bg-white/10 px-1.5 py-0.5 rounded tracking-widest text-slate-300 border border-white/10\">ADMIN</span>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Menu de Navegaci\u00F3n -->\r\n <div\r\n class=\"flex-1 overflow-y-auto py-6 px-3 space-y-2 scrollbar-thin scrollbar-thumb-slate-700 scrollbar-track-transparent [&::-webkit-scrollbar]:hidden [-ms-overflow-style:'none'] [scrollbar-width:'none']\">\r\n @for (item of menuItems(); track item.label) {\r\n <!-- Group Header -->\r\n @if (item.isHeader && !collapsed()) {\r\n <h2 class=\"text-[10px] font-bold text-slate-400 tracking-[0.2em] px-4 mb-3 mt-6 uppercase opacity-70\">\r\n {{ item.label }}\r\n </h2>\r\n }\r\n\r\n @if (!item.isHeader) {\r\n <!-- Item Wrapper -->\r\n <div class=\"relative group px-1\">\r\n <!-- Standard Item or Parent -->\r\n @if (!item.children || item.children.length === 0) {\r\n <a [routerLink]=\"item.route\"\r\n [routerLinkActive]=\"['bg-[#0081C9]', 'text-white', 'shadow-[0_10px_20px_-5px_rgba(0,129,201,0.4)]']\"\r\n [routerLinkActiveOptions]=\"{ exact: item.exact || false }\" (click)=\"onItemClick(item)\"\r\n class=\"w-full flex items-center px-4 py-3 rounded-xl transition-all duration-300 group cursor-pointer text-slate-300 hover:bg-white/5 hover:text-white\"\r\n [class.justify-center]=\"collapsed()\" [class.justify-between]=\"!collapsed()\" #rla=\"routerLinkActive\">\r\n\r\n <div class=\"flex items-center gap-3\">\r\n <span class=\"transition-colors\" [class.text-white]=\"rla.isActive\"\r\n [class.text-slate-400]=\"!rla.isActive\" [class.group-hover:text-blue-300]=\"!rla.isActive\">\r\n <ad-icon [name]=\"item.icon!\" size=\"md\"></ad-icon>\r\n </span>\r\n @if (!collapsed()) {\r\n <span class=\"font-medium text-sm whitespace-nowrap\">{{ item.label }}</span>\r\n }\r\n </div>\r\n\r\n @if (item.badge && !collapsed()) {\r\n <span\r\n class=\"bg-[#4CC9FE] text-[#002B5B] text-[10px] font-bold h-5 w-5 flex items-center justify-center rounded-md shadow-sm\">\r\n {{ item.badge }}\r\n </span>\r\n }\r\n </a>\r\n } @else {\r\n <!-- Parent Item with Submenu -->\r\n <div (click)=\"toggleSubmenu(item)\"\r\n class=\"w-full flex items-center px-4 py-3 rounded-xl transition-all duration-300 cursor-pointer hover:bg-white/5 hover:text-white\"\r\n [class.bg-white/5]=\"isExpanded(item)\" [class.text-white]=\"isExpanded(item) && !hasActiveChild(item)\"\r\n [class.text-[#4CC9FE]]=\"hasActiveChild(item)\"\r\n [class.text-slate-300]=\"!isExpanded(item) && !hasActiveChild(item)\" [class.justify-center]=\"collapsed()\"\r\n [class.justify-between]=\"!collapsed()\">\r\n\r\n <div class=\"flex items-center gap-3\">\r\n <span class=\"transition-colors\" [class.text-white]=\"isExpanded(item) && !hasActiveChild(item)\"\r\n [class.text-[#4CC9FE]]=\"hasActiveChild(item)\"\r\n [class.text-slate-400]=\"!isExpanded(item) && !hasActiveChild(item)\"\r\n [class.group-hover:text-blue-300]=\"!isExpanded(item) && !hasActiveChild(item)\">\r\n <ad-icon [name]=\"item.icon!\" size=\"md\"></ad-icon>\r\n </span>\r\n @if (!collapsed()) {\r\n <span class=\"font-medium text-sm whitespace-nowrap\">{{ item.label }}</span>\r\n }\r\n </div>\r\n\r\n @if (!collapsed()) {\r\n <span class=\"transition-transform duration-300\" [class.rotate-180]=\"isExpanded(item)\">\r\n <span class=\"material-icons-outlined text-sm\">expand_more</span>\r\n </span>\r\n }\r\n </div>\r\n\r\n <!-- Submenu -->\r\n @if (isExpanded(item) && !collapsed()) {\r\n <ul class=\"mt-1 ml-9 border-l border-white/10 space-y-1 animate-slide-down\">\r\n @for (subItem of item.children; track subItem.route) {\r\n <li>\r\n <a [routerLink]=\"subItem.route\" [routerLinkActive]=\"['text-white', 'font-medium']\"\r\n [routerLinkActiveOptions]=\"{ exact: subItem.exact || false }\" (click)=\"onItemClick(subItem)\"\r\n class=\"w-full block text-left px-4 py-2 text-xs text-slate-400 hover:text-white transition-colors rounded-lg\">\r\n {{ subItem.label }}\r\n </a>\r\n </li>\r\n }\r\n </ul>\r\n }\r\n }\r\n\r\n <!-- Tooltip for collapsed state -->\r\n @if (collapsed()) {\r\n <div\r\n class=\"fixed left-20 ml-2 px-3 py-1.5 bg-slate-900 text-white text-xs rounded-md opacity-0 group-hover:opacity-100 pointer-events-none transition-all translate-x-[-10px] group-hover:translate-x-0 whitespace-nowrap z-50 shadow-2xl\">\r\n {{ item.label }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"p-4 border-t border-white/5 bg-black/10 transition-all duration-300\">\r\n <div class=\"flex items-center h-10 rounded-lg bg-white/5 border border-white/5 transition-all duration-300\"\r\n [class.justify-center]=\"collapsed()\" [class.px-4]=\"!collapsed()\">\r\n <span class=\"text-[10px] font-medium text-slate-400 tracking-widest uppercase whitespace-nowrap\">\r\n {{ collapsed() ? 'v2' : 'v2.0.0 Design' }}\r\n </span>\r\n </div>\r\n </div>\r\n</aside>", styles: ["@keyframes slideDown{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}.animate-slide-down{animation:slideDown .2s ease-out forwards}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: AdIconComponent, selector: "ad-icon", inputs: ["name", "size", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
592
2141
  }
593
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcContainerComponent, decorators: [{
2142
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdSidebarComponent, decorators: [{
594
2143
  type: Component,
595
- args: [{ selector: 'cc-container', standalone: true, imports: [CommonModule], template: "<div class=\"cc-container\" [class.cc-container-fluid]=\"fluid\" [ngClass]=\"'size-' + size\">\r\n <ng-content></ng-content>\r\n</div>", styles: [".cc-container{width:100%;margin-right:auto;margin-left:auto;padding-right:var(--space-4);padding-left:var(--space-4)}@media(min-width:768px){.cc-container{padding-right:var(--space-6);padding-left:var(--space-6)}}@media(min-width:1280px){.cc-container{padding-right:var(--space-8);padding-left:var(--space-8)}}.cc-container.cc-container-fluid{max-width:none!important}.cc-container.size-sm{max-width:640px}.cc-container.size-md{max-width:768px}.cc-container.size-lg{max-width:1024px}.cc-container.size-xl{max-width:1280px}.cc-container.size-2xl{max-width:1536px}\n"] }]
596
- }], propDecorators: { fluid: [{
597
- type: Input
598
- }], size: [{
599
- type: Input
600
- }] } });
2144
+ args: [{ selector: 'ad-sidebar', standalone: true, imports: [CommonModule, RouterLink, RouterLinkActive, AdIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<aside\r\n class=\"flex flex-col bg-[#002B5B] text-white transition-all duration-300 ease-in-out h-full z-30 shadow-[10px_0_40px_-15px_rgba(0,0,0,0.3)] border-r border-white/5\"\r\n [class.w-72]=\"!collapsed()\" [class.w-20]=\"collapsed()\">\r\n\r\n <!-- Logo Area -->\r\n <div\r\n class=\"p-4 flex items-center justify-center border-b border-white/5 h-20 transition-all duration-300 flex-shrink-0\">\r\n @if (collapsed()) {\r\n <!-- Isotipo (C) -->\r\n <div\r\n class=\"w-10 h-10 bg-blue-500 rounded-lg flex items-center justify-center font-bold text-lg shadow-lg animate-in fade-in zoom-in-75\">\r\n C\r\n </div>\r\n } @else {\r\n <!-- Logo Completo -->\r\n <div class=\"flex items-center gap-2 animate-in fade-in slide-in-from-left-4 duration-500\">\r\n <span class=\"text-xl font-bold tracking-tight text-blue-400\">Cerca</span>\r\n <span\r\n class=\"text-[9px] font-bold bg-white/10 px-1.5 py-0.5 rounded tracking-widest text-slate-300 border border-white/10\">ADMIN</span>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Menu de Navegaci\u00F3n -->\r\n <div\r\n class=\"flex-1 overflow-y-auto py-6 px-3 space-y-2 scrollbar-thin scrollbar-thumb-slate-700 scrollbar-track-transparent [&::-webkit-scrollbar]:hidden [-ms-overflow-style:'none'] [scrollbar-width:'none']\">\r\n @for (item of menuItems(); track item.label) {\r\n <!-- Group Header -->\r\n @if (item.isHeader && !collapsed()) {\r\n <h2 class=\"text-[10px] font-bold text-slate-400 tracking-[0.2em] px-4 mb-3 mt-6 uppercase opacity-70\">\r\n {{ item.label }}\r\n </h2>\r\n }\r\n\r\n @if (!item.isHeader) {\r\n <!-- Item Wrapper -->\r\n <div class=\"relative group px-1\">\r\n <!-- Standard Item or Parent -->\r\n @if (!item.children || item.children.length === 0) {\r\n <a [routerLink]=\"item.route\"\r\n [routerLinkActive]=\"['bg-[#0081C9]', 'text-white', 'shadow-[0_10px_20px_-5px_rgba(0,129,201,0.4)]']\"\r\n [routerLinkActiveOptions]=\"{ exact: item.exact || false }\" (click)=\"onItemClick(item)\"\r\n class=\"w-full flex items-center px-4 py-3 rounded-xl transition-all duration-300 group cursor-pointer text-slate-300 hover:bg-white/5 hover:text-white\"\r\n [class.justify-center]=\"collapsed()\" [class.justify-between]=\"!collapsed()\" #rla=\"routerLinkActive\">\r\n\r\n <div class=\"flex items-center gap-3\">\r\n <span class=\"transition-colors\" [class.text-white]=\"rla.isActive\"\r\n [class.text-slate-400]=\"!rla.isActive\" [class.group-hover:text-blue-300]=\"!rla.isActive\">\r\n <ad-icon [name]=\"item.icon!\" size=\"md\"></ad-icon>\r\n </span>\r\n @if (!collapsed()) {\r\n <span class=\"font-medium text-sm whitespace-nowrap\">{{ item.label }}</span>\r\n }\r\n </div>\r\n\r\n @if (item.badge && !collapsed()) {\r\n <span\r\n class=\"bg-[#4CC9FE] text-[#002B5B] text-[10px] font-bold h-5 w-5 flex items-center justify-center rounded-md shadow-sm\">\r\n {{ item.badge }}\r\n </span>\r\n }\r\n </a>\r\n } @else {\r\n <!-- Parent Item with Submenu -->\r\n <div (click)=\"toggleSubmenu(item)\"\r\n class=\"w-full flex items-center px-4 py-3 rounded-xl transition-all duration-300 cursor-pointer hover:bg-white/5 hover:text-white\"\r\n [class.bg-white/5]=\"isExpanded(item)\" [class.text-white]=\"isExpanded(item) && !hasActiveChild(item)\"\r\n [class.text-[#4CC9FE]]=\"hasActiveChild(item)\"\r\n [class.text-slate-300]=\"!isExpanded(item) && !hasActiveChild(item)\" [class.justify-center]=\"collapsed()\"\r\n [class.justify-between]=\"!collapsed()\">\r\n\r\n <div class=\"flex items-center gap-3\">\r\n <span class=\"transition-colors\" [class.text-white]=\"isExpanded(item) && !hasActiveChild(item)\"\r\n [class.text-[#4CC9FE]]=\"hasActiveChild(item)\"\r\n [class.text-slate-400]=\"!isExpanded(item) && !hasActiveChild(item)\"\r\n [class.group-hover:text-blue-300]=\"!isExpanded(item) && !hasActiveChild(item)\">\r\n <ad-icon [name]=\"item.icon!\" size=\"md\"></ad-icon>\r\n </span>\r\n @if (!collapsed()) {\r\n <span class=\"font-medium text-sm whitespace-nowrap\">{{ item.label }}</span>\r\n }\r\n </div>\r\n\r\n @if (!collapsed()) {\r\n <span class=\"transition-transform duration-300\" [class.rotate-180]=\"isExpanded(item)\">\r\n <span class=\"material-icons-outlined text-sm\">expand_more</span>\r\n </span>\r\n }\r\n </div>\r\n\r\n <!-- Submenu -->\r\n @if (isExpanded(item) && !collapsed()) {\r\n <ul class=\"mt-1 ml-9 border-l border-white/10 space-y-1 animate-slide-down\">\r\n @for (subItem of item.children; track subItem.route) {\r\n <li>\r\n <a [routerLink]=\"subItem.route\" [routerLinkActive]=\"['text-white', 'font-medium']\"\r\n [routerLinkActiveOptions]=\"{ exact: subItem.exact || false }\" (click)=\"onItemClick(subItem)\"\r\n class=\"w-full block text-left px-4 py-2 text-xs text-slate-400 hover:text-white transition-colors rounded-lg\">\r\n {{ subItem.label }}\r\n </a>\r\n </li>\r\n }\r\n </ul>\r\n }\r\n }\r\n\r\n <!-- Tooltip for collapsed state -->\r\n @if (collapsed()) {\r\n <div\r\n class=\"fixed left-20 ml-2 px-3 py-1.5 bg-slate-900 text-white text-xs rounded-md opacity-0 group-hover:opacity-100 pointer-events-none transition-all translate-x-[-10px] group-hover:translate-x-0 whitespace-nowrap z-50 shadow-2xl\">\r\n {{ item.label }}\r\n </div>\r\n }\r\n </div>\r\n }\r\n }\r\n </div>\r\n\r\n <!-- Footer -->\r\n <div class=\"p-4 border-t border-white/5 bg-black/10 transition-all duration-300\">\r\n <div class=\"flex items-center h-10 rounded-lg bg-white/5 border border-white/5 transition-all duration-300\"\r\n [class.justify-center]=\"collapsed()\" [class.px-4]=\"!collapsed()\">\r\n <span class=\"text-[10px] font-medium text-slate-400 tracking-widest uppercase whitespace-nowrap\">\r\n {{ collapsed() ? 'v2' : 'v2.0.0 Design' }}\r\n </span>\r\n </div>\r\n </div>\r\n</aside>", styles: ["@keyframes slideDown{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}.animate-slide-down{animation:slideDown .2s ease-out forwards}\n"] }]
2145
+ }], ctorParameters: () => [{ type: i1$2.Router }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], toggleCollapse: [{ type: i0.Output, args: ["toggleCollapse"] }], navigate: [{ type: i0.Output, args: ["navigate"] }] } });
601
2146
 
602
- class CcStackComponent {
603
- constructor() {
604
- this.gap = input(4, ...(ngDevMode ? [{ debugName: "gap" }] : []));
605
- this.align = input('stretch', ...(ngDevMode ? [{ debugName: "align" }] : []));
606
- this.justify = input('start', ...(ngDevMode ? [{ debugName: "justify" }] : []));
2147
+ const NavItemSchema = z.lazy(() => z.object({
2148
+ label: z.string(),
2149
+ icon: z.string().optional(),
2150
+ route: z.string().optional(),
2151
+ badge: z.union([z.string(), z.number()]).optional(),
2152
+ badgeColor: z.string().optional(),
2153
+ exact: z.boolean().optional(),
2154
+ children: z.array(NavItemSchema).optional(),
2155
+ isHeader: z.boolean().optional(),
2156
+ }));
2157
+ const SidebarResourceSchema = z.object({
2158
+ menuItems: z.array(NavItemSchema),
2159
+ collapsed: z.boolean().default(false).optional(),
2160
+ });
2161
+
2162
+ class AdTableComponent {
2163
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
2164
+ data = computed(() => this.resource().data, ...(ngDevMode ? [{ debugName: "data" }] : []));
2165
+ columns = computed(() => this.resource().columns, ...(ngDevMode ? [{ debugName: "columns" }] : []));
2166
+ total = computed(() => this.resource().total, ...(ngDevMode ? [{ debugName: "total" }] : []));
2167
+ loading = computed(() => this.resource().loading ?? false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
2168
+ pageIndex = computed(() => this.resource().pageIndex ?? 1, ...(ngDevMode ? [{ debugName: "pageIndex" }] : []));
2169
+ pageSize = computed(() => this.resource().pageSize ?? 10, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
2170
+ searchPlaceholder = computed(() => this.resource().searchPlaceholder ?? 'Buscar...', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : []));
2171
+ pageChange = output();
2172
+ search = output();
2173
+ searchInput = new FormControl('');
2174
+ destroy$ = new Subject();
2175
+ datePipe = inject(DatePipe);
2176
+ currencyPipe = inject(CurrencyPipe);
2177
+ decimalPipe = inject(DecimalPipe);
2178
+ percentPipe = inject(PercentPipe);
2179
+ totalPages = computed(() => Math.ceil(this.total() / this.pageSize()), ...(ngDevMode ? [{ debugName: "totalPages" }] : []));
2180
+ isFirstPage = computed(() => this.pageIndex() === 1, ...(ngDevMode ? [{ debugName: "isFirstPage" }] : []));
2181
+ isLastPage = computed(() => this.pageIndex() >= this.totalPages(), ...(ngDevMode ? [{ debugName: "isLastPage" }] : []));
2182
+ ngOnInit() {
2183
+ this.searchInput.valueChanges
2184
+ .pipe(debounceTime$1(300), distinctUntilChanged$1(), takeUntil(this.destroy$))
2185
+ .subscribe((value) => {
2186
+ this.search.emit(value || '');
2187
+ });
607
2188
  }
608
- get gapStyle() {
609
- const g = this.gap();
610
- return typeof g === 'number' ? `var(--space-${g})` : g;
2189
+ ngOnDestroy() {
2190
+ this.destroy$.next();
2191
+ this.destroy$.complete();
611
2192
  }
612
- get alignStyle() {
613
- const map = { start: 'flex-start', center: 'center', end: 'flex-end', stretch: 'stretch' };
614
- return map[this.align()];
2193
+ onPageChange(newPage) {
2194
+ if (newPage >= 1 && newPage <= this.totalPages()) {
2195
+ this.pageChange.emit(newPage);
2196
+ }
615
2197
  }
616
- get justifyStyle() {
617
- const map = { start: 'flex-start', center: 'center', end: 'flex-end', between: 'space-between' };
618
- const j = this.justify();
619
- if (j === 'between')
620
- return 'space-between';
621
- return map[j] || 'flex-start';
2198
+ getAlignClass(align) {
2199
+ switch (align) {
2200
+ case 'center': return 'text-center';
2201
+ case 'right': return 'text-right';
2202
+ default: return 'text-left';
2203
+ }
2204
+ }
2205
+ getCellValue(row, col) {
2206
+ const value = row[col.key];
2207
+ // 1. Prioritize function execution if context is available
2208
+ if (col.function_to_exec && this.resource().context) {
2209
+ const context = this.resource().context;
2210
+ if (typeof context[col.function_to_exec] === 'function') {
2211
+ return context[col.function_to_exec](row, col);
2212
+ }
2213
+ }
2214
+ // 2. Apply pipe if specified
2215
+ if (col.pipe_to_apply && value !== null && value !== undefined) {
2216
+ return this.applyPipe(value, col.pipe_to_apply);
2217
+ }
2218
+ return value;
2219
+ }
2220
+ applyPipe(value, pipeConfig) {
2221
+ const [pipeName, ...args] = pipeConfig.split(':');
2222
+ switch (pipeName.toLowerCase()) {
2223
+ case 'date':
2224
+ return this.datePipe.transform(value, args[0] || 'mediumDate');
2225
+ case 'currency':
2226
+ return this.currencyPipe.transform(value, args[0] || 'USD', args[1] || 'symbol', args[2]);
2227
+ case 'number':
2228
+ case 'decimal':
2229
+ return this.decimalPipe.transform(value, args[0]);
2230
+ case 'percent':
2231
+ return this.percentPipe.transform(value, args[0]);
2232
+ default:
2233
+ return value;
2234
+ }
622
2235
  }
623
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcStackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
624
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.4", type: CcStackComponent, isStandalone: true, selector: "cc-stack", inputs: { gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, justify: { classPropertyName: "justify", publicName: "justify", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.gap": "this.gapStyle", "style.align-items": "this.alignStyle", "style.justify-content": "this.justifyStyle" } }, ngImport: i0, template: "<ng-content></ng-content>", styles: [":host{display:flex;flex-direction:column;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
2236
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2237
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdTableComponent, isStandalone: true, selector: "ad-table", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { pageChange: "pageChange", search: "search" }, providers: [DatePipe, CurrencyPipe, DecimalPipe, PercentPipe], ngImport: i0, template: "<div class=\"flex flex-col h-full w-full bg-white rounded-xl shadow-sm border border-stone-200 overflow-hidden\">\r\n <!-- Header: Search & Actions -->\r\n <div class=\"flex items-center justify-between p-4 border-b border-stone-100 bg-stone-50/50 backdrop-blur-sm\">\r\n <div class=\"relative w-full max-w-sm group\">\r\n <div class=\"absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none\">\r\n <svg class=\"h-4 w-4 text-stone-400 group-focus-within:text-sky-500 transition-colors\"\r\n xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\r\n <path fill-rule=\"evenodd\"\r\n d=\"M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z\"\r\n clip-rule=\"evenodd\" />\r\n </svg>\r\n </div>\r\n <input [formControl]=\"searchInput\" type=\"text\"\r\n class=\"block w-full pl-10 pr-3 py-2 border border-stone-300 rounded-lg leading-5 bg-white placeholder-stone-400 focus:outline-none focus:placeholder-stone-300 focus:border-sky-500 focus:ring-1 focus:ring-sky-500 sm:text-sm transition-shadow duration-200\"\r\n [placeholder]=\"searchPlaceholder()\" />\r\n </div>\r\n <div class=\"ml-4 flex items-center\">\r\n <span\r\n class=\"text-xs font-medium text-stone-500 bg-stone-100 px-2 py-1 rounded-full border border-stone-200\">\r\n Total: <span class=\"text-stone-800 font-bold\">{{ total() }}</span>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Container -->\r\n <div class=\"flex-1 overflow-auto relative\">\r\n <!-- Loading Overlay -->\r\n @if (loading()) {\r\n <div class=\"absolute inset-0 z-10 bg-white/60 backdrop-blur-[1px] flex justify-center items-center\">\r\n <div class=\"flex items-center gap-2 px-4 py-2 bg-white rounded-lg shadow-lg border border-stone-100\">\r\n <ad-loading size=\"md\"></ad-loading>\r\n <span class=\"text-sm font-medium text-stone-600\">Cargando datos...</span>\r\n </div>\r\n </div>\r\n }\r\n\r\n <table class=\"min-w-full divide-y divide-stone-200\">\r\n <thead class=\"bg-stone-50 sticky top-0 z-0 is-header\">\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <th scope=\"col\"\r\n class=\"px-6 py-3 text-xs font-semibold text-stone-500 uppercase tracking-wider whitespace-nowrap\"\r\n [style.width]=\"col.width\" [class]=\"getAlignClass(col.align)\">\r\n {{ col.label }}\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody class=\"bg-white divide-y divide-stone-100\">\r\n @if (data().length === 0 && !loading()) {\r\n <tr>\r\n <td [attr.colspan]=\"columns().length\" class=\"px-6 py-12 text-center\">\r\n <div class=\"flex flex-col items-center justify-center text-stone-400\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\" class=\"w-12 h-12 mb-3 opacity-50\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n d=\"M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z\" />\r\n </svg>\r\n <p class=\"text-base font-medium text-stone-900\">Sin datos disponibles</p>\r\n <p class=\"text-sm\">No se encontraron registros para mostrar.</p>\r\n </div>\r\n </td>\r\n </tr>\r\n } @else {\r\n @for (row of data(); track row) {\r\n <tr class=\"hover:bg-sky-50/50 transition-colors duration-150 group\">\r\n @for (col of columns(); track col.key) {\r\n <td class=\"px-6 py-4 whitespace-nowrap text-sm text-stone-700 border-b border-transparent group-hover:border-sky-100\"\r\n [class]=\"getAlignClass(col.align)\">\r\n {{ getCellValue(row, col) }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- Footer: Pagination -->\r\n <div class=\"bg-white px-4 py-3 flex items-center justify-between border-t border-stone-200 sm:px-6\">\r\n <div class=\"flex-1 flex justify-between sm:hidden\">\r\n <button [disabled]=\"isFirstPage()\" (click)=\"onPageChange(pageIndex() - 1)\"\r\n class=\"relative inline-flex items-center px-4 py-2 border border-stone-300 text-sm font-medium rounded-md text-stone-700 bg-white hover:bg-stone-50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\">\r\n Anterior\r\n </button>\r\n <button [disabled]=\"isLastPage()\" (click)=\"onPageChange(pageIndex() + 1)\"\r\n class=\"ml-3 relative inline-flex items-center px-4 py-2 border border-stone-300 text-sm font-medium rounded-md text-stone-700 bg-white hover:bg-stone-50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\">\r\n Siguiente\r\n </button>\r\n </div>\r\n <div class=\"hidden sm:flex-1 sm:flex sm:items-center sm:justify-between\">\r\n <div>\r\n <p class=\"text-sm text-stone-500\">\r\n Mostrando p\u00E1gina <span class=\"font-medium text-stone-900\">{{ pageIndex() }}</span> de <span\r\n class=\"font-medium text-stone-900\">{{ totalPages() }}</span>\r\n </p>\r\n </div>\r\n <div>\r\n <nav class=\"relative z-0 inline-flex rounded-md shadow-sm -space-x-px\" aria-label=\"Pagination\">\r\n <button [disabled]=\"isFirstPage()\" (click)=\"onPageChange(pageIndex() - 1)\"\r\n class=\"relative inline-flex items-center px-2 py-2 rounded-l-md border border-stone-300 bg-white text-sm font-medium text-stone-500 hover:bg-stone-50 disabled:opacity-50 disabled:cursor-not-allowed focus:z-10 focus:outline-none focus:ring-1 focus:ring-sky-500 focus:border-sky-500 transition-colors\">\r\n <span class=\"sr-only\">Anterior</span>\r\n <!-- Heroicon: chevron-left -->\r\n <svg class=\"h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\r\n aria-hidden=\"true\">\r\n <path fill-rule=\"evenodd\"\r\n d=\"M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z\"\r\n clip-rule=\"evenodd\" />\r\n </svg>\r\n </button>\r\n <button [disabled]=\"isLastPage()\" (click)=\"onPageChange(pageIndex() + 1)\"\r\n class=\"relative inline-flex items-center px-2 py-2 rounded-r-md border border-stone-300 bg-white text-sm font-medium text-stone-500 hover:bg-stone-50 disabled:opacity-50 disabled:cursor-not-allowed focus:z-10 focus:outline-none focus:ring-1 focus:ring-sky-500 focus:border-sky-500 transition-colors\">\r\n <span class=\"sr-only\">Siguiente</span>\r\n <!-- Heroicon: chevron-right -->\r\n <svg class=\"h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\r\n aria-hidden=\"true\">\r\n <path fill-rule=\"evenodd\"\r\n d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\"\r\n clip-rule=\"evenodd\" />\r\n </svg>\r\n </button>\r\n </nav>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: AdLoadingComponent, selector: "ad-loading", inputs: ["size", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
625
2238
  }
626
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcStackComponent, decorators: [{
2239
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdTableComponent, decorators: [{
627
2240
  type: Component,
628
- args: [{ selector: 'cc-stack', standalone: true, imports: [CommonModule], template: "<ng-content></ng-content>", styles: [":host{display:flex;flex-direction:column;width:100%}\n"] }]
629
- }], propDecorators: { gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], justify: [{ type: i0.Input, args: [{ isSignal: true, alias: "justify", required: false }] }], gapStyle: [{
630
- type: HostBinding,
631
- args: ['style.gap']
632
- }], alignStyle: [{
633
- type: HostBinding,
634
- args: ['style.align-items']
635
- }], justifyStyle: [{
636
- type: HostBinding,
637
- args: ['style.justify-content']
2241
+ args: [{ selector: 'ad-table', standalone: true, imports: [CommonModule, ReactiveFormsModule, AdLoadingComponent], providers: [DatePipe, CurrencyPipe, DecimalPipe, PercentPipe], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col h-full w-full bg-white rounded-xl shadow-sm border border-stone-200 overflow-hidden\">\r\n <!-- Header: Search & Actions -->\r\n <div class=\"flex items-center justify-between p-4 border-b border-stone-100 bg-stone-50/50 backdrop-blur-sm\">\r\n <div class=\"relative w-full max-w-sm group\">\r\n <div class=\"absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none\">\r\n <svg class=\"h-4 w-4 text-stone-400 group-focus-within:text-sky-500 transition-colors\"\r\n xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\" aria-hidden=\"true\">\r\n <path fill-rule=\"evenodd\"\r\n d=\"M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z\"\r\n clip-rule=\"evenodd\" />\r\n </svg>\r\n </div>\r\n <input [formControl]=\"searchInput\" type=\"text\"\r\n class=\"block w-full pl-10 pr-3 py-2 border border-stone-300 rounded-lg leading-5 bg-white placeholder-stone-400 focus:outline-none focus:placeholder-stone-300 focus:border-sky-500 focus:ring-1 focus:ring-sky-500 sm:text-sm transition-shadow duration-200\"\r\n [placeholder]=\"searchPlaceholder()\" />\r\n </div>\r\n <div class=\"ml-4 flex items-center\">\r\n <span\r\n class=\"text-xs font-medium text-stone-500 bg-stone-100 px-2 py-1 rounded-full border border-stone-200\">\r\n Total: <span class=\"text-stone-800 font-bold\">{{ total() }}</span>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n <!-- Table Container -->\r\n <div class=\"flex-1 overflow-auto relative\">\r\n <!-- Loading Overlay -->\r\n @if (loading()) {\r\n <div class=\"absolute inset-0 z-10 bg-white/60 backdrop-blur-[1px] flex justify-center items-center\">\r\n <div class=\"flex items-center gap-2 px-4 py-2 bg-white rounded-lg shadow-lg border border-stone-100\">\r\n <ad-loading size=\"md\"></ad-loading>\r\n <span class=\"text-sm font-medium text-stone-600\">Cargando datos...</span>\r\n </div>\r\n </div>\r\n }\r\n\r\n <table class=\"min-w-full divide-y divide-stone-200\">\r\n <thead class=\"bg-stone-50 sticky top-0 z-0 is-header\">\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <th scope=\"col\"\r\n class=\"px-6 py-3 text-xs font-semibold text-stone-500 uppercase tracking-wider whitespace-nowrap\"\r\n [style.width]=\"col.width\" [class]=\"getAlignClass(col.align)\">\r\n {{ col.label }}\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody class=\"bg-white divide-y divide-stone-100\">\r\n @if (data().length === 0 && !loading()) {\r\n <tr>\r\n <td [attr.colspan]=\"columns().length\" class=\"px-6 py-12 text-center\">\r\n <div class=\"flex flex-col items-center justify-center text-stone-400\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\"\r\n stroke=\"currentColor\" class=\"w-12 h-12 mb-3 opacity-50\">\r\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\r\n d=\"M20.25 7.5l-.625 10.632a2.25 2.25 0 01-2.247 2.118H6.622a2.25 2.25 0 01-2.247-2.118L3.75 7.5M10 11.25h4M3.375 7.5h17.25c.621 0 1.125-.504 1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125z\" />\r\n </svg>\r\n <p class=\"text-base font-medium text-stone-900\">Sin datos disponibles</p>\r\n <p class=\"text-sm\">No se encontraron registros para mostrar.</p>\r\n </div>\r\n </td>\r\n </tr>\r\n } @else {\r\n @for (row of data(); track row) {\r\n <tr class=\"hover:bg-sky-50/50 transition-colors duration-150 group\">\r\n @for (col of columns(); track col.key) {\r\n <td class=\"px-6 py-4 whitespace-nowrap text-sm text-stone-700 border-b border-transparent group-hover:border-sky-100\"\r\n [class]=\"getAlignClass(col.align)\">\r\n {{ getCellValue(row, col) }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <!-- Footer: Pagination -->\r\n <div class=\"bg-white px-4 py-3 flex items-center justify-between border-t border-stone-200 sm:px-6\">\r\n <div class=\"flex-1 flex justify-between sm:hidden\">\r\n <button [disabled]=\"isFirstPage()\" (click)=\"onPageChange(pageIndex() - 1)\"\r\n class=\"relative inline-flex items-center px-4 py-2 border border-stone-300 text-sm font-medium rounded-md text-stone-700 bg-white hover:bg-stone-50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\">\r\n Anterior\r\n </button>\r\n <button [disabled]=\"isLastPage()\" (click)=\"onPageChange(pageIndex() + 1)\"\r\n class=\"ml-3 relative inline-flex items-center px-4 py-2 border border-stone-300 text-sm font-medium rounded-md text-stone-700 bg-white hover:bg-stone-50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\">\r\n Siguiente\r\n </button>\r\n </div>\r\n <div class=\"hidden sm:flex-1 sm:flex sm:items-center sm:justify-between\">\r\n <div>\r\n <p class=\"text-sm text-stone-500\">\r\n Mostrando p\u00E1gina <span class=\"font-medium text-stone-900\">{{ pageIndex() }}</span> de <span\r\n class=\"font-medium text-stone-900\">{{ totalPages() }}</span>\r\n </p>\r\n </div>\r\n <div>\r\n <nav class=\"relative z-0 inline-flex rounded-md shadow-sm -space-x-px\" aria-label=\"Pagination\">\r\n <button [disabled]=\"isFirstPage()\" (click)=\"onPageChange(pageIndex() - 1)\"\r\n class=\"relative inline-flex items-center px-2 py-2 rounded-l-md border border-stone-300 bg-white text-sm font-medium text-stone-500 hover:bg-stone-50 disabled:opacity-50 disabled:cursor-not-allowed focus:z-10 focus:outline-none focus:ring-1 focus:ring-sky-500 focus:border-sky-500 transition-colors\">\r\n <span class=\"sr-only\">Anterior</span>\r\n <!-- Heroicon: chevron-left -->\r\n <svg class=\"h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\r\n aria-hidden=\"true\">\r\n <path fill-rule=\"evenodd\"\r\n d=\"M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z\"\r\n clip-rule=\"evenodd\" />\r\n </svg>\r\n </button>\r\n <button [disabled]=\"isLastPage()\" (click)=\"onPageChange(pageIndex() + 1)\"\r\n class=\"relative inline-flex items-center px-2 py-2 rounded-r-md border border-stone-300 bg-white text-sm font-medium text-stone-500 hover:bg-stone-50 disabled:opacity-50 disabled:cursor-not-allowed focus:z-10 focus:outline-none focus:ring-1 focus:ring-sky-500 focus:border-sky-500 transition-colors\">\r\n <span class=\"sr-only\">Siguiente</span>\r\n <!-- Heroicon: chevron-right -->\r\n <svg class=\"h-5 w-5\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 20 20\" fill=\"currentColor\"\r\n aria-hidden=\"true\">\r\n <path fill-rule=\"evenodd\"\r\n d=\"M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z\"\r\n clip-rule=\"evenodd\" />\r\n </svg>\r\n </button>\r\n </nav>\r\n </div>\r\n </div>\r\n </div>\r\n</div>" }]
2242
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], search: [{ type: i0.Output, args: ["search"] }] } });
2243
+
2244
+ const AdTableColumnSchema = z.object({
2245
+ key: z.string(),
2246
+ label: z.string(),
2247
+ width: z.string().optional(),
2248
+ align: z.enum(['left', 'center', 'right']).optional(),
2249
+ pipe_to_apply: z.string().optional(),
2250
+ function_to_exec: z.string().optional(),
2251
+ });
2252
+ const TableResourceSchema = z.object({
2253
+ data: z.array(z.any()),
2254
+ columns: z.array(AdTableColumnSchema),
2255
+ total: z.number(),
2256
+ loading: z.boolean().default(false).optional(),
2257
+ pageIndex: z.number().default(1).optional(),
2258
+ pageSize: z.number().default(10).optional(),
2259
+ searchPlaceholder: z.string().default('Buscar...').optional(),
2260
+ context: z.any().optional(),
2261
+ });
2262
+
2263
+ class AdDocViewerComponent {
2264
+ injector;
2265
+ // Inputs
2266
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
2267
+ showCode = input(true, ...(ngDevMode ? [{ debugName: "showCode" }] : []));
2268
+ showApi = input(true, ...(ngDevMode ? [{ debugName: "showApi" }] : []));
2269
+ id = computed(() => this.resource().id, ...(ngDevMode ? [{ debugName: "id" }] : []));
2270
+ name = computed(() => this.resource().name, ...(ngDevMode ? [{ debugName: "name" }] : []));
2271
+ category = computed(() => this.resource().category, ...(ngDevMode ? [{ debugName: "category" }] : []));
2272
+ description = computed(() => this.resource().description, ...(ngDevMode ? [{ debugName: "description" }] : []));
2273
+ selector = computed(() => this.resource().selector, ...(ngDevMode ? [{ debugName: "selector" }] : []));
2274
+ codeSnippet = computed(() => this.resource().codeSnippet, ...(ngDevMode ? [{ debugName: "codeSnippet" }] : []));
2275
+ api = computed(() => this.resource().api, ...(ngDevMode ? [{ debugName: "api" }] : []));
2276
+ variants = computed(() => this.resource().variants, ...(ngDevMode ? [{ debugName: "variants" }] : []));
2277
+ // Outputs
2278
+ tabChange = output();
2279
+ // Estado interno
2280
+ activeTab = signal('preview', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
2281
+ activeVariant = signal('', ...(ngDevMode ? [{ debugName: "activeVariant" }] : []));
2282
+ copied = signal(false, ...(ngDevMode ? [{ debugName: "copied" }] : []));
2283
+ viewReady = signal(false, ...(ngDevMode ? [{ debugName: "viewReady" }] : []));
2284
+ // Tabs disponibles
2285
+ tabs = computed(() => [
2286
+ { id: 'preview', label: 'Preview' },
2287
+ ...(this.showApi() ? [{ id: 'api', label: 'API' }] : []),
2288
+ ...(this.showCode() ? [{ id: 'code', label: 'Código' }] : []),
2289
+ ], ...(ngDevMode ? [{ debugName: "tabs" }] : []));
2290
+ previewHost;
2291
+ constructor(injector) {
2292
+ this.injector = injector;
2293
+ effect(() => {
2294
+ const res = this.resource();
2295
+ const tab = this.activeTab();
2296
+ // viewReady se activará en ngAfterViewInit
2297
+ if (this.viewReady() && tab === 'preview') {
2298
+ this.renderPreview(res);
2299
+ }
2300
+ });
2301
+ }
2302
+ ngAfterViewInit() {
2303
+ this.viewReady.set(true);
2304
+ if (this.activeTab() === 'preview') {
2305
+ this.renderPreview(this.resource());
2306
+ }
2307
+ }
2308
+ setTab(tab) {
2309
+ this.activeTab.set(tab);
2310
+ this.tabChange.emit(tab);
2311
+ if (tab === 'preview') {
2312
+ // Pequeño delay para que el ViewChild esté disponible tras el @if
2313
+ setTimeout(() => this.renderPreview(this.resource()), 0);
2314
+ }
2315
+ }
2316
+ setVariant(variant) {
2317
+ this.activeVariant.set(variant.label);
2318
+ this.renderPreview(this.resource(), variant.resource);
2319
+ }
2320
+ copyCode() {
2321
+ navigator.clipboard.writeText(this.resource().codeSnippet).then(() => {
2322
+ this.copied.set(true);
2323
+ setTimeout(() => this.copied.set(false), 2000);
2324
+ });
2325
+ }
2326
+ renderPreview(res, overrideResource) {
2327
+ if (!this.previewHost)
2328
+ return;
2329
+ this.previewHost.clear();
2330
+ try {
2331
+ const ref = createComponent(res.component, {
2332
+ environmentInjector: this.injector,
2333
+ elementInjector: this.previewHost.injector,
2334
+ });
2335
+ const inputs = overrideResource ?? res.previewResource ?? {};
2336
+ Object.entries(inputs).forEach(([key, val]) => {
2337
+ try {
2338
+ ref.setInput(key, val);
2339
+ }
2340
+ catch { /* input no encontrado, se ignora */ }
2341
+ });
2342
+ this.previewHost.insert(ref.hostView);
2343
+ }
2344
+ catch (e) {
2345
+ console.warn('[ad-doc-viewer] No se pudo renderizar el preview:', e);
2346
+ }
2347
+ }
2348
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdDocViewerComponent, deps: [{ token: i0.EnvironmentInjector }], target: i0.ɵɵFactoryTarget.Component });
2349
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdDocViewerComponent, isStandalone: true, selector: "ad-doc-viewer", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null }, showCode: { classPropertyName: "showCode", publicName: "showCode", isSignal: true, isRequired: false, transformFunction: null }, showApi: { classPropertyName: "showApi", publicName: "showApi", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tabChange: "tabChange" }, viewQueries: [{ propertyName: "previewHost", first: true, predicate: ["previewHost"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<section class=\"flex flex-col gap-6 p-6 bg-white rounded-2xl border border-stone-200 shadow-sm\">\r\n\r\n <!-- Header del componente -->\r\n <div class=\"flex items-start justify-between\">\r\n <div class=\"flex flex-col gap-1\">\r\n <div class=\"flex items-center gap-2 flex-wrap\">\r\n <span\r\n class=\"text-xs font-semibold px-2 py-0.5 rounded-full bg-sky-100 text-sky-700 uppercase tracking-wide\">\r\n {{ category() }}\r\n </span>\r\n <code class=\"text-xs px-2 py-0.5 rounded-md bg-stone-100 text-stone-600 font-mono\">\r\n {{ selector() }}\r\n </code>\r\n </div>\r\n <h2 class=\"text-xl font-bold text-stone-900 mt-1\">{{ name() }}</h2>\r\n <p class=\"text-sm text-stone-500 max-w-xl\">{{ description() }}</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Tabs de navegaci\u00F3n -->\r\n <div class=\"flex gap-1 border-b border-stone-200\">\r\n @for (tab of tabs(); track tab.id) {\r\n <button\r\n class=\"px-4 py-2 text-sm font-medium transition-colors rounded-t-lg focus:outline-none focus-visible:ring-2 focus-visible:ring-sky-500\"\r\n [class]=\"activeTab() === tab.id\r\n ? 'text-sky-600 border-b-2 border-sky-600 -mb-px bg-sky-50'\r\n : 'text-stone-500 hover:text-stone-700 hover:bg-stone-50'\" (click)=\"setTab(tab.id)\"\r\n [attr.aria-selected]=\"activeTab() === tab.id\" role=\"tab\">\r\n {{ tab.label }}\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- Panel: Preview -->\r\n @if (activeTab() === 'preview') {\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Canvas con fondo ajedrezado -->\r\n <div class=\"flex items-center justify-center min-h-40 rounded-xl border border-dashed border-stone-300\r\n p-8 overflow-auto\"\r\n style=\"background-image: linear-gradient(45deg, #f5f5f4 25%, transparent 25%, transparent 75%, #f5f5f4 75%, #f5f5f4), linear-gradient(45deg, #f5f5f4 25%, transparent 25%, transparent 75%, #f5f5f4 75%, #f5f5f4); background-size: 16px 16px; background-position: 0 0, 8px 8px;\">\r\n <ng-container #previewHost></ng-container>\r\n </div>\r\n\r\n <!-- Variantes -->\r\n @if (variants()?.length) {\r\n <div class=\"flex flex-wrap gap-2\">\r\n <span\r\n class=\"text-xs font-semibold text-stone-400 uppercase tracking-wider self-center mr-1\">Variante:</span>\r\n @for (variant of variants()!; track variant.label) {\r\n <button\r\n class=\"px-3 py-1.5 text-xs font-medium rounded-lg border transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-sky-500\"\r\n [class]=\"activeVariant() === variant.label\r\n ? 'bg-sky-600 border-sky-600 text-white shadow-sm'\r\n : 'border-stone-300 text-stone-600 hover:border-sky-400 hover:text-sky-600 bg-white'\"\r\n (click)=\"setVariant(variant)\">\r\n {{ variant.label }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Panel: API -->\r\n @if (activeTab() === 'api' && showApi()) {\r\n <div class=\"flex flex-col gap-6\">\r\n\r\n <!-- Inputs -->\r\n @if (api().inputs.length) {\r\n <div class=\"flex flex-col gap-2\">\r\n <h3 class=\"text-xs font-semibold text-stone-500 uppercase tracking-widest\">Inputs</h3>\r\n <div class=\"overflow-hidden rounded-xl border border-stone-200\">\r\n <table class=\"w-full text-sm\">\r\n <thead class=\"bg-stone-50 text-stone-500 text-left\">\r\n <tr>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Nombre</th>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Tipo</th>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Requerido</th>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Default</th>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Descripci\u00F3n</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (inp of api().inputs; track inp.name) {\r\n <tr class=\"border-t border-stone-100 hover:bg-stone-50 transition-colors\">\r\n <td class=\"px-4 py-3\">\r\n <code class=\"text-sky-600 font-mono text-xs\">{{ inp.name }}</code>\r\n </td>\r\n <td class=\"px-4 py-3\">\r\n <code class=\"text-emerald-600 font-mono text-xs\">{{ inp.type }}</code>\r\n </td>\r\n <td class=\"px-4 py-3\">\r\n @if (inp.required) {\r\n <span\r\n class=\"text-xs px-1.5 py-0.5 rounded-full bg-rose-100 text-rose-600 font-medium\">S\u00ED</span>\r\n } @else {\r\n <span class=\"text-xs px-1.5 py-0.5 rounded-full bg-stone-100 text-stone-500\">No</span>\r\n }\r\n </td>\r\n <td class=\"px-4 py-3 text-stone-400 font-mono text-xs\">{{ inp.defaultValue || '\u2014' }}</td>\r\n <td class=\"px-4 py-3 text-stone-600 text-xs\">{{ inp.description }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Outputs -->\r\n @if (api().outputs.length) {\r\n <div class=\"flex flex-col gap-2\">\r\n <h3 class=\"text-xs font-semibold text-stone-500 uppercase tracking-widest\">Outputs</h3>\r\n <div class=\"overflow-hidden rounded-xl border border-stone-200\">\r\n <table class=\"w-full text-sm\">\r\n <thead class=\"bg-stone-50 text-stone-500 text-left\">\r\n <tr>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Nombre</th>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Tipo de Evento</th>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Descripci\u00F3n</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (out of api().outputs; track out.name) {\r\n <tr class=\"border-t border-stone-100 hover:bg-stone-50 transition-colors\">\r\n <td class=\"px-4 py-3\">\r\n <code class=\"text-amber-600 font-mono text-xs\">({{ out.name }})</code>\r\n </td>\r\n <td class=\"px-4 py-3\">\r\n <code class=\"text-emerald-600 font-mono text-xs\">{{ out.eventType }}</code>\r\n </td>\r\n <td class=\"px-4 py-3 text-stone-600 text-xs\">{{ out.description }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (!api().inputs.length && !api().outputs.length) {\r\n <p class=\"text-sm text-stone-400 italic\">No hay API documentada para este componente.</p>\r\n }\r\n\r\n </div>\r\n }\r\n\r\n <!-- Panel: C\u00F3digo -->\r\n @if (activeTab() === 'code' && showCode()) {\r\n <div class=\"relative rounded-xl overflow-hidden border border-stone-200\">\r\n <!-- Toolbar del bloque de c\u00F3digo -->\r\n <div class=\"flex items-center justify-between px-4 py-2.5 bg-stone-800\">\r\n <span class=\"text-xs text-stone-400 font-mono uppercase tracking-wider\">HTML</span>\r\n <button\r\n class=\"text-xs flex items-center gap-1.5 transition-colors px-2 py-1 rounded focus:outline-none focus-visible:ring-2 focus-visible:ring-sky-500\"\r\n [class]=\"copied() ? 'text-emerald-400 font-medium' : 'text-stone-400 hover:text-white'\"\r\n (click)=\"copyCode()\">\r\n @if (copied()) {\r\n <span>\u2713 Copiado</span>\r\n } @else {\r\n <span>Copiar</span>\r\n }\r\n </button>\r\n </div>\r\n <!-- Bloque de c\u00F3digo -->\r\n <pre\r\n class=\"bg-stone-900 p-5 overflow-x-auto text-sm font-mono text-stone-200 leading-relaxed whitespace-pre m-0\">{{ codeSnippet() }}</pre>\r\n </div>\r\n }\r\n\r\n</section>", changeDetection: i0.ChangeDetectionStrategy.OnPush });
2350
+ }
2351
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdDocViewerComponent, decorators: [{
2352
+ type: Component,
2353
+ args: [{ selector: 'ad-doc-viewer', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, template: "<section class=\"flex flex-col gap-6 p-6 bg-white rounded-2xl border border-stone-200 shadow-sm\">\r\n\r\n <!-- Header del componente -->\r\n <div class=\"flex items-start justify-between\">\r\n <div class=\"flex flex-col gap-1\">\r\n <div class=\"flex items-center gap-2 flex-wrap\">\r\n <span\r\n class=\"text-xs font-semibold px-2 py-0.5 rounded-full bg-sky-100 text-sky-700 uppercase tracking-wide\">\r\n {{ category() }}\r\n </span>\r\n <code class=\"text-xs px-2 py-0.5 rounded-md bg-stone-100 text-stone-600 font-mono\">\r\n {{ selector() }}\r\n </code>\r\n </div>\r\n <h2 class=\"text-xl font-bold text-stone-900 mt-1\">{{ name() }}</h2>\r\n <p class=\"text-sm text-stone-500 max-w-xl\">{{ description() }}</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Tabs de navegaci\u00F3n -->\r\n <div class=\"flex gap-1 border-b border-stone-200\">\r\n @for (tab of tabs(); track tab.id) {\r\n <button\r\n class=\"px-4 py-2 text-sm font-medium transition-colors rounded-t-lg focus:outline-none focus-visible:ring-2 focus-visible:ring-sky-500\"\r\n [class]=\"activeTab() === tab.id\r\n ? 'text-sky-600 border-b-2 border-sky-600 -mb-px bg-sky-50'\r\n : 'text-stone-500 hover:text-stone-700 hover:bg-stone-50'\" (click)=\"setTab(tab.id)\"\r\n [attr.aria-selected]=\"activeTab() === tab.id\" role=\"tab\">\r\n {{ tab.label }}\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- Panel: Preview -->\r\n @if (activeTab() === 'preview') {\r\n <div class=\"flex flex-col gap-4\">\r\n <!-- Canvas con fondo ajedrezado -->\r\n <div class=\"flex items-center justify-center min-h-40 rounded-xl border border-dashed border-stone-300\r\n p-8 overflow-auto\"\r\n style=\"background-image: linear-gradient(45deg, #f5f5f4 25%, transparent 25%, transparent 75%, #f5f5f4 75%, #f5f5f4), linear-gradient(45deg, #f5f5f4 25%, transparent 25%, transparent 75%, #f5f5f4 75%, #f5f5f4); background-size: 16px 16px; background-position: 0 0, 8px 8px;\">\r\n <ng-container #previewHost></ng-container>\r\n </div>\r\n\r\n <!-- Variantes -->\r\n @if (variants()?.length) {\r\n <div class=\"flex flex-wrap gap-2\">\r\n <span\r\n class=\"text-xs font-semibold text-stone-400 uppercase tracking-wider self-center mr-1\">Variante:</span>\r\n @for (variant of variants()!; track variant.label) {\r\n <button\r\n class=\"px-3 py-1.5 text-xs font-medium rounded-lg border transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-sky-500\"\r\n [class]=\"activeVariant() === variant.label\r\n ? 'bg-sky-600 border-sky-600 text-white shadow-sm'\r\n : 'border-stone-300 text-stone-600 hover:border-sky-400 hover:text-sky-600 bg-white'\"\r\n (click)=\"setVariant(variant)\">\r\n {{ variant.label }}\r\n </button>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Panel: API -->\r\n @if (activeTab() === 'api' && showApi()) {\r\n <div class=\"flex flex-col gap-6\">\r\n\r\n <!-- Inputs -->\r\n @if (api().inputs.length) {\r\n <div class=\"flex flex-col gap-2\">\r\n <h3 class=\"text-xs font-semibold text-stone-500 uppercase tracking-widest\">Inputs</h3>\r\n <div class=\"overflow-hidden rounded-xl border border-stone-200\">\r\n <table class=\"w-full text-sm\">\r\n <thead class=\"bg-stone-50 text-stone-500 text-left\">\r\n <tr>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Nombre</th>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Tipo</th>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Requerido</th>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Default</th>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Descripci\u00F3n</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (inp of api().inputs; track inp.name) {\r\n <tr class=\"border-t border-stone-100 hover:bg-stone-50 transition-colors\">\r\n <td class=\"px-4 py-3\">\r\n <code class=\"text-sky-600 font-mono text-xs\">{{ inp.name }}</code>\r\n </td>\r\n <td class=\"px-4 py-3\">\r\n <code class=\"text-emerald-600 font-mono text-xs\">{{ inp.type }}</code>\r\n </td>\r\n <td class=\"px-4 py-3\">\r\n @if (inp.required) {\r\n <span\r\n class=\"text-xs px-1.5 py-0.5 rounded-full bg-rose-100 text-rose-600 font-medium\">S\u00ED</span>\r\n } @else {\r\n <span class=\"text-xs px-1.5 py-0.5 rounded-full bg-stone-100 text-stone-500\">No</span>\r\n }\r\n </td>\r\n <td class=\"px-4 py-3 text-stone-400 font-mono text-xs\">{{ inp.defaultValue || '\u2014' }}</td>\r\n <td class=\"px-4 py-3 text-stone-600 text-xs\">{{ inp.description }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Outputs -->\r\n @if (api().outputs.length) {\r\n <div class=\"flex flex-col gap-2\">\r\n <h3 class=\"text-xs font-semibold text-stone-500 uppercase tracking-widest\">Outputs</h3>\r\n <div class=\"overflow-hidden rounded-xl border border-stone-200\">\r\n <table class=\"w-full text-sm\">\r\n <thead class=\"bg-stone-50 text-stone-500 text-left\">\r\n <tr>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Nombre</th>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Tipo de Evento</th>\r\n <th class=\"px-4 py-2.5 font-medium text-xs\">Descripci\u00F3n</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (out of api().outputs; track out.name) {\r\n <tr class=\"border-t border-stone-100 hover:bg-stone-50 transition-colors\">\r\n <td class=\"px-4 py-3\">\r\n <code class=\"text-amber-600 font-mono text-xs\">({{ out.name }})</code>\r\n </td>\r\n <td class=\"px-4 py-3\">\r\n <code class=\"text-emerald-600 font-mono text-xs\">{{ out.eventType }}</code>\r\n </td>\r\n <td class=\"px-4 py-3 text-stone-600 text-xs\">{{ out.description }}</td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n </div>\r\n }\r\n\r\n @if (!api().inputs.length && !api().outputs.length) {\r\n <p class=\"text-sm text-stone-400 italic\">No hay API documentada para este componente.</p>\r\n }\r\n\r\n </div>\r\n }\r\n\r\n <!-- Panel: C\u00F3digo -->\r\n @if (activeTab() === 'code' && showCode()) {\r\n <div class=\"relative rounded-xl overflow-hidden border border-stone-200\">\r\n <!-- Toolbar del bloque de c\u00F3digo -->\r\n <div class=\"flex items-center justify-between px-4 py-2.5 bg-stone-800\">\r\n <span class=\"text-xs text-stone-400 font-mono uppercase tracking-wider\">HTML</span>\r\n <button\r\n class=\"text-xs flex items-center gap-1.5 transition-colors px-2 py-1 rounded focus:outline-none focus-visible:ring-2 focus-visible:ring-sky-500\"\r\n [class]=\"copied() ? 'text-emerald-400 font-medium' : 'text-stone-400 hover:text-white'\"\r\n (click)=\"copyCode()\">\r\n @if (copied()) {\r\n <span>\u2713 Copiado</span>\r\n } @else {\r\n <span>Copiar</span>\r\n }\r\n </button>\r\n </div>\r\n <!-- Bloque de c\u00F3digo -->\r\n <pre\r\n class=\"bg-stone-900 p-5 overflow-x-auto text-sm font-mono text-stone-200 leading-relaxed whitespace-pre m-0\">{{ codeSnippet() }}</pre>\r\n </div>\r\n }\r\n\r\n</section>" }]
2354
+ }], ctorParameters: () => [{ type: i0.EnvironmentInjector }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], showCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCode", required: false }] }], showApi: [{ type: i0.Input, args: [{ isSignal: true, alias: "showApi", required: false }] }], tabChange: [{ type: i0.Output, args: ["tabChange"] }], previewHost: [{
2355
+ type: ViewChild,
2356
+ args: ['previewHost', { read: ViewContainerRef }]
638
2357
  }] } });
639
2358
 
640
- class CcGridComponent {
641
- constructor() {
642
- this.cols = 1;
643
- this.gap = 4;
2359
+ const ComponentApiInputSchema = z.object({
2360
+ name: z.string(),
2361
+ type: z.string(),
2362
+ required: z.boolean(),
2363
+ defaultValue: z.string(),
2364
+ description: z.string(),
2365
+ });
2366
+ const ComponentApiOutputSchema = z.object({
2367
+ name: z.string(),
2368
+ eventType: z.string(),
2369
+ description: z.string(),
2370
+ });
2371
+ const ComponentVariantSchema = z.object({
2372
+ label: z.string(),
2373
+ resource: z.record(z.string(), z.unknown()),
2374
+ });
2375
+ const DocViewerResourceSchema = z.object({
2376
+ /** Metadatos de identificación */
2377
+ id: z.string(),
2378
+ name: z.string(),
2379
+ category: z.enum(['atom', 'molecule', 'organism', 'template']),
2380
+ description: z.string(),
2381
+ /** Selector Angular del componente */
2382
+ selector: z.string(),
2383
+ /** Referencia al componente Angular para preview dinámico */
2384
+ component: z.custom(),
2385
+ /** Ejemplo de código de integración (string) */
2386
+ codeSnippet: z.string(),
2387
+ /** API del componente */
2388
+ api: z.object({
2389
+ inputs: z.array(ComponentApiInputSchema),
2390
+ outputs: z.array(ComponentApiOutputSchema),
2391
+ }),
2392
+ /** Recurso de ejemplo pre-configurado para el preview (inputs individuales) */
2393
+ previewResource: z.record(z.string(), z.unknown()).optional(),
2394
+ /** Variantes (states) a mostrar en el preview */
2395
+ variants: z.array(ComponentVariantSchema).optional(),
2396
+ });
2397
+
2398
+ class AdAdminLayoutComponent {
2399
+ // Inputs as Signals
2400
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
2401
+ user = computed(() => this.resource().user, ...(ngDevMode ? [{ debugName: "user" }] : []));
2402
+ menuItems = computed(() => this.resource().menuItems, ...(ngDevMode ? [{ debugName: "menuItems" }] : []));
2403
+ notificationsCount = computed(() => this.resource().notificationsCount ?? 0, ...(ngDevMode ? [{ debugName: "notificationsCount" }] : []));
2404
+ // Derived Resources
2405
+ headerResource = computed(() => ({
2406
+ user: this.user(),
2407
+ notificationsCount: this.notificationsCount()
2408
+ }), ...(ngDevMode ? [{ debugName: "headerResource" }] : []));
2409
+ sidebarResource = computed(() => ({
2410
+ menuItems: this.menuItems(),
2411
+ collapsed: this.isSidebarCollapsed()
2412
+ }), ...(ngDevMode ? [{ debugName: "sidebarResource" }] : []));
2413
+ // Outputs
2414
+ logout = output();
2415
+ navigateProfile = output();
2416
+ toggleTheme = output();
2417
+ // State Signals
2418
+ isMobileMenuOpen = signal(false, ...(ngDevMode ? [{ debugName: "isMobileMenuOpen" }] : []));
2419
+ isSidebarCollapsed = signal(false, ...(ngDevMode ? [{ debugName: "isSidebarCollapsed" }] : []));
2420
+ toggleMobileMenu() {
2421
+ this.isMobileMenuOpen.update(v => !v);
2422
+ }
2423
+ closeMobileMenu() {
2424
+ this.isMobileMenuOpen.set(false);
644
2425
  }
2426
+ toggleSidebar() {
2427
+ this.isSidebarCollapsed.update(v => !v);
2428
+ }
2429
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdAdminLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2430
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdAdminLayoutComponent, isStandalone: true, selector: "ad-admin-layout", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { logout: "logout", navigateProfile: "navigateProfile", toggleTheme: "toggleTheme" }, ngImport: i0, template: "<div class=\"flex h-screen bg-[#F4F7FE] font-sans overflow-hidden transition-colors duration-300\">\r\n <!-- Sidebar -->\r\n <ad-sidebar class=\"hidden md:flex h-full z-30\" [resource]=\"sidebarResource()\" (toggleCollapse)=\"toggleSidebar()\">\r\n </ad-sidebar>\r\n\r\n <!-- Main Content Wrapper -->\r\n <div class=\"flex-1 flex flex-col relative overflow-hidden\">\r\n\r\n <!-- HEADER JOINING SIDEBAR AND CONTENT -->\r\n <ad-header [resource]=\"headerResource()\" (toggleSidebar)=\"toggleSidebar()\"\r\n (toggleMobileMenu)=\"toggleMobileMenu()\" (logout)=\"logout.emit()\" (navigateProfile)=\"navigateProfile.emit()\"\r\n (toggleTheme)=\"toggleTheme.emit($event)\">\r\n </ad-header>\r\n\r\n <!-- DASHBOARD CONTENT AREA / WRAPPER -->\r\n <main class=\"flex-1 overflow-y-auto p-6 md:p-10 bg-gradient-to-b from-white/50 to-transparent scroll-smooth\">\r\n <!-- The routed content will be projected here. \r\n The user's snippet had specific dashboard stats here.\r\n We provide the container, and the Router Outlet content (e.g. DashboardComponent) \r\n should implement the Grid/Cards.\r\n However, to match the \"Card on Canvas\" look for general pages, we can wrap the router outlet.\r\n -->\r\n <div class=\"max-w-7xl mx-auto h-full animate-fade-in-up\">\r\n <ad-card [resource]=\"{ title: '' }\">\r\n <ng-content></ng-content>\r\n </ad-card>\r\n </div>\r\n </main>\r\n\r\n <!-- Mobile Sidebar Overlay -->\r\n @if (isMobileMenuOpen()) {\r\n <div class=\"relative z-50 md:hidden\" role=\"dialog\" aria-modal=\"true\">\r\n <div class=\"fixed inset-0 bg-slate-900/80 transition-opacity backdrop-blur-sm\" (click)=\"closeMobileMenu()\">\r\n </div>\r\n <div class=\"fixed inset-0 flex\">\r\n <div\r\n class=\"relative flex w-full max-w-xs flex-1 flex-col bg-[#002B5B] pb-4 pt-5 transition-transform shadow-2xl\">\r\n <div class=\"flex items-center justify-between px-4 pb-4 border-b border-white/10\">\r\n <div class=\"flex items-center text-white\">\r\n <span class=\"text-xl font-bold tracking-tight\">Cerca</span>\r\n <span\r\n class=\"ml-2 text-[10px] font-bold bg-white/10 px-1.5 py-0.5 rounded tracking-widest text-slate-300 border border-white/10\">ADMIN</span>\r\n </div>\r\n <button (click)=\"closeMobileMenu()\" class=\"text-slate-400 hover:text-white\">\r\n <span class=\"material-icons-outlined\">close</span>\r\n </button>\r\n </div>\r\n <nav class=\"flex-1 overflow-y-auto px-4 py-6 space-y-2\">\r\n @for (item of menuItems(); track item.route) {\r\n <a [routerLink]=\"item.route\" (click)=\"closeMobileMenu()\"\r\n [routerLinkActive]=\"['bg-[#0081C9]', 'text-white', 'shadow-lg']\"\r\n [routerLinkActiveOptions]=\"{ exact: item.exact || false }\"\r\n class=\"group flex items-center px-4 py-3 text-sm font-medium text-slate-300 rounded-xl hover:bg-white/5 hover:text-white transition-all duration-200\">\r\n <span class=\"material-icons-outlined text-[20px] mr-3 transition-colors\"\r\n [class.text-white]=\"false\" [class.group-hover:text-blue-300]=\"true\">\r\n {{ item.icon }}\r\n </span>\r\n {{ item.label }}\r\n </a>\r\n }\r\n </nav>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</div>", styles: ["@keyframes fade-in-down{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.animate-fade-in-down{animation:fade-in-down .2s ease-out}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: AdSidebarComponent, selector: "ad-sidebar", inputs: ["resource"], outputs: ["toggleCollapse", "navigate"] }, { kind: "component", type: AdCardComponent, selector: "ad-card", inputs: ["resource"], outputs: ["action"] }, { kind: "component", type: AdHeaderComponent, selector: "ad-header", inputs: ["resource"], outputs: ["toggleSidebar", "toggleMobileMenu", "logout", "navigateProfile", "toggleTheme"] }] });
2431
+ }
2432
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdAdminLayoutComponent, decorators: [{
2433
+ type: Component,
2434
+ args: [{ selector: 'ad-admin-layout', standalone: true, imports: [
2435
+ CommonModule,
2436
+ RouterLink,
2437
+ RouterLinkActive,
2438
+ AdSidebarComponent,
2439
+ AdCardComponent,
2440
+ AdHeaderComponent
2441
+ ], template: "<div class=\"flex h-screen bg-[#F4F7FE] font-sans overflow-hidden transition-colors duration-300\">\r\n <!-- Sidebar -->\r\n <ad-sidebar class=\"hidden md:flex h-full z-30\" [resource]=\"sidebarResource()\" (toggleCollapse)=\"toggleSidebar()\">\r\n </ad-sidebar>\r\n\r\n <!-- Main Content Wrapper -->\r\n <div class=\"flex-1 flex flex-col relative overflow-hidden\">\r\n\r\n <!-- HEADER JOINING SIDEBAR AND CONTENT -->\r\n <ad-header [resource]=\"headerResource()\" (toggleSidebar)=\"toggleSidebar()\"\r\n (toggleMobileMenu)=\"toggleMobileMenu()\" (logout)=\"logout.emit()\" (navigateProfile)=\"navigateProfile.emit()\"\r\n (toggleTheme)=\"toggleTheme.emit($event)\">\r\n </ad-header>\r\n\r\n <!-- DASHBOARD CONTENT AREA / WRAPPER -->\r\n <main class=\"flex-1 overflow-y-auto p-6 md:p-10 bg-gradient-to-b from-white/50 to-transparent scroll-smooth\">\r\n <!-- The routed content will be projected here. \r\n The user's snippet had specific dashboard stats here.\r\n We provide the container, and the Router Outlet content (e.g. DashboardComponent) \r\n should implement the Grid/Cards.\r\n However, to match the \"Card on Canvas\" look for general pages, we can wrap the router outlet.\r\n -->\r\n <div class=\"max-w-7xl mx-auto h-full animate-fade-in-up\">\r\n <ad-card [resource]=\"{ title: '' }\">\r\n <ng-content></ng-content>\r\n </ad-card>\r\n </div>\r\n </main>\r\n\r\n <!-- Mobile Sidebar Overlay -->\r\n @if (isMobileMenuOpen()) {\r\n <div class=\"relative z-50 md:hidden\" role=\"dialog\" aria-modal=\"true\">\r\n <div class=\"fixed inset-0 bg-slate-900/80 transition-opacity backdrop-blur-sm\" (click)=\"closeMobileMenu()\">\r\n </div>\r\n <div class=\"fixed inset-0 flex\">\r\n <div\r\n class=\"relative flex w-full max-w-xs flex-1 flex-col bg-[#002B5B] pb-4 pt-5 transition-transform shadow-2xl\">\r\n <div class=\"flex items-center justify-between px-4 pb-4 border-b border-white/10\">\r\n <div class=\"flex items-center text-white\">\r\n <span class=\"text-xl font-bold tracking-tight\">Cerca</span>\r\n <span\r\n class=\"ml-2 text-[10px] font-bold bg-white/10 px-1.5 py-0.5 rounded tracking-widest text-slate-300 border border-white/10\">ADMIN</span>\r\n </div>\r\n <button (click)=\"closeMobileMenu()\" class=\"text-slate-400 hover:text-white\">\r\n <span class=\"material-icons-outlined\">close</span>\r\n </button>\r\n </div>\r\n <nav class=\"flex-1 overflow-y-auto px-4 py-6 space-y-2\">\r\n @for (item of menuItems(); track item.route) {\r\n <a [routerLink]=\"item.route\" (click)=\"closeMobileMenu()\"\r\n [routerLinkActive]=\"['bg-[#0081C9]', 'text-white', 'shadow-lg']\"\r\n [routerLinkActiveOptions]=\"{ exact: item.exact || false }\"\r\n class=\"group flex items-center px-4 py-3 text-sm font-medium text-slate-300 rounded-xl hover:bg-white/5 hover:text-white transition-all duration-200\">\r\n <span class=\"material-icons-outlined text-[20px] mr-3 transition-colors\"\r\n [class.text-white]=\"false\" [class.group-hover:text-blue-300]=\"true\">\r\n {{ item.icon }}\r\n </span>\r\n {{ item.label }}\r\n </a>\r\n }\r\n </nav>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</div>", styles: ["@keyframes fade-in-down{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.animate-fade-in-down{animation:fade-in-down .2s ease-out}\n"] }]
2442
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], logout: [{ type: i0.Output, args: ["logout"] }], navigateProfile: [{ type: i0.Output, args: ["navigateProfile"] }], toggleTheme: [{ type: i0.Output, args: ["toggleTheme"] }] } });
2443
+
2444
+ const AdminLayoutResourceSchema = z.object({
2445
+ user: UserSchema,
2446
+ menuItems: z.array(NavItemSchema),
2447
+ notificationsCount: z.number().default(0).optional(),
2448
+ });
2449
+
2450
+ class AdAuthLayoutComponent {
2451
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
2452
+ backgroundType = computed(() => this.resource().backgroundType ?? 'gradient', ...(ngDevMode ? [{ debugName: "backgroundType" }] : []));
2453
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdAuthLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2454
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.4", type: AdAuthLayoutComponent, isStandalone: true, selector: "ad-auth-layout", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"ad-auth-layout\" [ngClass]=\"'bg-' + backgroundType()\">\r\n <div class=\"ad-auth-container\">\r\n <div class=\"ad-auth-card\">\r\n <div class=\"ad-auth-logo\">\r\n <!-- Espacio para logo -->\r\n <div class=\"ad-auth-logo-placeholder\">CERCA</div>\r\n </div>\r\n\r\n <div class=\"ad-auth-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".ad-auth-layout{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:var(--space-4)}.ad-auth-layout.bg-gradient{background:radial-gradient(circle at top left,var(--color-brand-900),var(--neutral-900))}.ad-auth-layout.bg-simple{background-color:var(--color-bg-secondary)}.ad-auth-container{width:100%;max-width:440px}.ad-auth-card{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-2xl);padding:var(--space-8);box-shadow:var(--shadow-2xl)}.ad-auth-logo{display:flex;justify-content:center;margin-bottom:var(--space-8)}.ad-auth-logo .ad-auth-logo-placeholder{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);color:var(--color-brand-600);letter-spacing:-.05em}.ad-auth-content{display:flex;flex-direction:column;gap:var(--space-6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
2455
+ }
2456
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdAuthLayoutComponent, decorators: [{
2457
+ type: Component,
2458
+ args: [{ selector: 'ad-auth-layout', standalone: true, imports: [CommonModule], template: "<div class=\"ad-auth-layout\" [ngClass]=\"'bg-' + backgroundType()\">\r\n <div class=\"ad-auth-container\">\r\n <div class=\"ad-auth-card\">\r\n <div class=\"ad-auth-logo\">\r\n <!-- Espacio para logo -->\r\n <div class=\"ad-auth-logo-placeholder\">CERCA</div>\r\n </div>\r\n\r\n <div class=\"ad-auth-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".ad-auth-layout{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:var(--space-4)}.ad-auth-layout.bg-gradient{background:radial-gradient(circle at top left,var(--color-brand-900),var(--neutral-900))}.ad-auth-layout.bg-simple{background-color:var(--color-bg-secondary)}.ad-auth-container{width:100%;max-width:440px}.ad-auth-card{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-2xl);padding:var(--space-8);box-shadow:var(--shadow-2xl)}.ad-auth-logo{display:flex;justify-content:center;margin-bottom:var(--space-8)}.ad-auth-logo .ad-auth-logo-placeholder{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);color:var(--color-brand-600);letter-spacing:-.05em}.ad-auth-content{display:flex;flex-direction:column;gap:var(--space-6)}\n"] }]
2459
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }] } });
2460
+
2461
+ const AuthLayoutResourceSchema = z.object({
2462
+ backgroundType: z.enum(['gradient', 'image', 'simple']).default('gradient').optional(),
2463
+ });
2464
+
2465
+ class AdGridComponent {
2466
+ cols = 1;
2467
+ colsMd;
2468
+ colsLg;
2469
+ gap = 4;
645
2470
  get classes() {
646
2471
  return [
647
- `cc-grid-cols-${this.cols}`,
648
- this.colsMd ? `cc-grid-cols-md-${this.colsMd}` : '',
649
- this.colsLg ? `cc-grid-cols-lg-${this.colsLg}` : '',
650
- `cc-grid-gap-${this.gap}`
2472
+ `ad-grid-cols-${this.cols}`,
2473
+ this.colsMd ? `ad-grid-cols-md-${this.colsMd}` : '',
2474
+ this.colsLg ? `ad-grid-cols-lg-${this.colsLg}` : '',
2475
+ `ad-grid-gap-${this.gap}`
651
2476
  ].filter(Boolean).join(' ');
652
2477
  }
653
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
654
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcGridComponent, isStandalone: true, selector: "cc-grid", inputs: { cols: "cols", colsMd: "colsMd", colsLg: "colsLg", gap: "gap" }, host: { properties: { "class": "this.classes" } }, ngImport: i0, template: "<div class=\"cc-grid\">\r\n <ng-content></ng-content>\r\n</div>", styles: [".cc-grid{display:grid;width:100%}.cc-grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.cc-grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.cc-grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.cc-grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.cc-grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.cc-grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.cc-grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.cc-grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.cc-grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.cc-grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.cc-grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.cc-grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}@media(min-width:768px){.cc-grid-cols-md-1{grid-template-columns:repeat(1,minmax(0,1fr))}.cc-grid-cols-md-2{grid-template-columns:repeat(2,minmax(0,1fr))}.cc-grid-cols-md-3{grid-template-columns:repeat(3,minmax(0,1fr))}.cc-grid-cols-md-4{grid-template-columns:repeat(4,minmax(0,1fr))}.cc-grid-cols-md-5{grid-template-columns:repeat(5,minmax(0,1fr))}.cc-grid-cols-md-6{grid-template-columns:repeat(6,minmax(0,1fr))}.cc-grid-cols-md-7{grid-template-columns:repeat(7,minmax(0,1fr))}.cc-grid-cols-md-8{grid-template-columns:repeat(8,minmax(0,1fr))}.cc-grid-cols-md-9{grid-template-columns:repeat(9,minmax(0,1fr))}.cc-grid-cols-md-10{grid-template-columns:repeat(10,minmax(0,1fr))}.cc-grid-cols-md-11{grid-template-columns:repeat(11,minmax(0,1fr))}.cc-grid-cols-md-12{grid-template-columns:repeat(12,minmax(0,1fr))}}@media(min-width:1024px){.cc-grid-cols-lg-1{grid-template-columns:repeat(1,minmax(0,1fr))}.cc-grid-cols-lg-2{grid-template-columns:repeat(2,minmax(0,1fr))}.cc-grid-cols-lg-3{grid-template-columns:repeat(3,minmax(0,1fr))}.cc-grid-cols-lg-4{grid-template-columns:repeat(4,minmax(0,1fr))}.cc-grid-cols-lg-5{grid-template-columns:repeat(5,minmax(0,1fr))}.cc-grid-cols-lg-6{grid-template-columns:repeat(6,minmax(0,1fr))}.cc-grid-cols-lg-7{grid-template-columns:repeat(7,minmax(0,1fr))}.cc-grid-cols-lg-8{grid-template-columns:repeat(8,minmax(0,1fr))}.cc-grid-cols-lg-9{grid-template-columns:repeat(9,minmax(0,1fr))}.cc-grid-cols-lg-10{grid-template-columns:repeat(10,minmax(0,1fr))}.cc-grid-cols-lg-11{grid-template-columns:repeat(11,minmax(0,1fr))}.cc-grid-cols-lg-12{grid-template-columns:repeat(12,minmax(0,1fr))}}.cc-grid-gap-1{gap:var(--space-1)}.cc-grid-gap-2{gap:var(--space-2)}.cc-grid-gap-3{gap:var(--space-3)}.cc-grid-gap-4{gap:var(--space-4)}.cc-grid-gap-5{gap:var(--space-5)}.cc-grid-gap-6{gap:var(--space-6)}.cc-grid-gap-7{gap:var(--space-7)}.cc-grid-gap-8{gap:var(--space-8)}.cc-grid-gap-9{gap:var(--space-9)}.cc-grid-gap-10{gap:var(--space-10)}.cc-grid-gap-11{gap:var(--space-11)}.cc-grid-gap-12{gap:var(--space-12)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
2478
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2479
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: AdGridComponent, isStandalone: true, selector: "ad-grid", inputs: { cols: "cols", colsMd: "colsMd", colsLg: "colsLg", gap: "gap" }, host: { properties: { "class": "this.classes" } }, ngImport: i0, template: "<div class=\"ad-grid\">\r\n <ng-content></ng-content>\r\n</div>", styles: [".ad-grid{display:grid;width:100%}.ad-grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.ad-grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.ad-grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.ad-grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.ad-grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.ad-grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.ad-grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.ad-grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.ad-grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.ad-grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.ad-grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.ad-grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}@media(min-width:768px){.ad-grid-cols-md-1{grid-template-columns:repeat(1,minmax(0,1fr))}.ad-grid-cols-md-2{grid-template-columns:repeat(2,minmax(0,1fr))}.ad-grid-cols-md-3{grid-template-columns:repeat(3,minmax(0,1fr))}.ad-grid-cols-md-4{grid-template-columns:repeat(4,minmax(0,1fr))}.ad-grid-cols-md-5{grid-template-columns:repeat(5,minmax(0,1fr))}.ad-grid-cols-md-6{grid-template-columns:repeat(6,minmax(0,1fr))}.ad-grid-cols-md-7{grid-template-columns:repeat(7,minmax(0,1fr))}.ad-grid-cols-md-8{grid-template-columns:repeat(8,minmax(0,1fr))}.ad-grid-cols-md-9{grid-template-columns:repeat(9,minmax(0,1fr))}.ad-grid-cols-md-10{grid-template-columns:repeat(10,minmax(0,1fr))}.ad-grid-cols-md-11{grid-template-columns:repeat(11,minmax(0,1fr))}.ad-grid-cols-md-12{grid-template-columns:repeat(12,minmax(0,1fr))}}@media(min-width:1024px){.ad-grid-cols-lg-1{grid-template-columns:repeat(1,minmax(0,1fr))}.ad-grid-cols-lg-2{grid-template-columns:repeat(2,minmax(0,1fr))}.ad-grid-cols-lg-3{grid-template-columns:repeat(3,minmax(0,1fr))}.ad-grid-cols-lg-4{grid-template-columns:repeat(4,minmax(0,1fr))}.ad-grid-cols-lg-5{grid-template-columns:repeat(5,minmax(0,1fr))}.ad-grid-cols-lg-6{grid-template-columns:repeat(6,minmax(0,1fr))}.ad-grid-cols-lg-7{grid-template-columns:repeat(7,minmax(0,1fr))}.ad-grid-cols-lg-8{grid-template-columns:repeat(8,minmax(0,1fr))}.ad-grid-cols-lg-9{grid-template-columns:repeat(9,minmax(0,1fr))}.ad-grid-cols-lg-10{grid-template-columns:repeat(10,minmax(0,1fr))}.ad-grid-cols-lg-11{grid-template-columns:repeat(11,minmax(0,1fr))}.ad-grid-cols-lg-12{grid-template-columns:repeat(12,minmax(0,1fr))}}.ad-grid-gap-1{gap:var(--space-1)}.ad-grid-gap-2{gap:var(--space-2)}.ad-grid-gap-3{gap:var(--space-3)}.ad-grid-gap-4{gap:var(--space-4)}.ad-grid-gap-5{gap:var(--space-5)}.ad-grid-gap-6{gap:var(--space-6)}.ad-grid-gap-7{gap:var(--space-7)}.ad-grid-gap-8{gap:var(--space-8)}.ad-grid-gap-9{gap:var(--space-9)}.ad-grid-gap-10{gap:var(--space-10)}.ad-grid-gap-11{gap:var(--space-11)}.ad-grid-gap-12{gap:var(--space-12)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
655
2480
  }
656
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcGridComponent, decorators: [{
2481
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdGridComponent, decorators: [{
657
2482
  type: Component,
658
- args: [{ selector: 'cc-grid', standalone: true, imports: [CommonModule], template: "<div class=\"cc-grid\">\r\n <ng-content></ng-content>\r\n</div>", styles: [".cc-grid{display:grid;width:100%}.cc-grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.cc-grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.cc-grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.cc-grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.cc-grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.cc-grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.cc-grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.cc-grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.cc-grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.cc-grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.cc-grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.cc-grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}@media(min-width:768px){.cc-grid-cols-md-1{grid-template-columns:repeat(1,minmax(0,1fr))}.cc-grid-cols-md-2{grid-template-columns:repeat(2,minmax(0,1fr))}.cc-grid-cols-md-3{grid-template-columns:repeat(3,minmax(0,1fr))}.cc-grid-cols-md-4{grid-template-columns:repeat(4,minmax(0,1fr))}.cc-grid-cols-md-5{grid-template-columns:repeat(5,minmax(0,1fr))}.cc-grid-cols-md-6{grid-template-columns:repeat(6,minmax(0,1fr))}.cc-grid-cols-md-7{grid-template-columns:repeat(7,minmax(0,1fr))}.cc-grid-cols-md-8{grid-template-columns:repeat(8,minmax(0,1fr))}.cc-grid-cols-md-9{grid-template-columns:repeat(9,minmax(0,1fr))}.cc-grid-cols-md-10{grid-template-columns:repeat(10,minmax(0,1fr))}.cc-grid-cols-md-11{grid-template-columns:repeat(11,minmax(0,1fr))}.cc-grid-cols-md-12{grid-template-columns:repeat(12,minmax(0,1fr))}}@media(min-width:1024px){.cc-grid-cols-lg-1{grid-template-columns:repeat(1,minmax(0,1fr))}.cc-grid-cols-lg-2{grid-template-columns:repeat(2,minmax(0,1fr))}.cc-grid-cols-lg-3{grid-template-columns:repeat(3,minmax(0,1fr))}.cc-grid-cols-lg-4{grid-template-columns:repeat(4,minmax(0,1fr))}.cc-grid-cols-lg-5{grid-template-columns:repeat(5,minmax(0,1fr))}.cc-grid-cols-lg-6{grid-template-columns:repeat(6,minmax(0,1fr))}.cc-grid-cols-lg-7{grid-template-columns:repeat(7,minmax(0,1fr))}.cc-grid-cols-lg-8{grid-template-columns:repeat(8,minmax(0,1fr))}.cc-grid-cols-lg-9{grid-template-columns:repeat(9,minmax(0,1fr))}.cc-grid-cols-lg-10{grid-template-columns:repeat(10,minmax(0,1fr))}.cc-grid-cols-lg-11{grid-template-columns:repeat(11,minmax(0,1fr))}.cc-grid-cols-lg-12{grid-template-columns:repeat(12,minmax(0,1fr))}}.cc-grid-gap-1{gap:var(--space-1)}.cc-grid-gap-2{gap:var(--space-2)}.cc-grid-gap-3{gap:var(--space-3)}.cc-grid-gap-4{gap:var(--space-4)}.cc-grid-gap-5{gap:var(--space-5)}.cc-grid-gap-6{gap:var(--space-6)}.cc-grid-gap-7{gap:var(--space-7)}.cc-grid-gap-8{gap:var(--space-8)}.cc-grid-gap-9{gap:var(--space-9)}.cc-grid-gap-10{gap:var(--space-10)}.cc-grid-gap-11{gap:var(--space-11)}.cc-grid-gap-12{gap:var(--space-12)}\n"] }]
2483
+ args: [{ selector: 'ad-grid', standalone: true, imports: [CommonModule], template: "<div class=\"ad-grid\">\r\n <ng-content></ng-content>\r\n</div>", styles: [".ad-grid{display:grid;width:100%}.ad-grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.ad-grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.ad-grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.ad-grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.ad-grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.ad-grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.ad-grid-cols-7{grid-template-columns:repeat(7,minmax(0,1fr))}.ad-grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.ad-grid-cols-9{grid-template-columns:repeat(9,minmax(0,1fr))}.ad-grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.ad-grid-cols-11{grid-template-columns:repeat(11,minmax(0,1fr))}.ad-grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}@media(min-width:768px){.ad-grid-cols-md-1{grid-template-columns:repeat(1,minmax(0,1fr))}.ad-grid-cols-md-2{grid-template-columns:repeat(2,minmax(0,1fr))}.ad-grid-cols-md-3{grid-template-columns:repeat(3,minmax(0,1fr))}.ad-grid-cols-md-4{grid-template-columns:repeat(4,minmax(0,1fr))}.ad-grid-cols-md-5{grid-template-columns:repeat(5,minmax(0,1fr))}.ad-grid-cols-md-6{grid-template-columns:repeat(6,minmax(0,1fr))}.ad-grid-cols-md-7{grid-template-columns:repeat(7,minmax(0,1fr))}.ad-grid-cols-md-8{grid-template-columns:repeat(8,minmax(0,1fr))}.ad-grid-cols-md-9{grid-template-columns:repeat(9,minmax(0,1fr))}.ad-grid-cols-md-10{grid-template-columns:repeat(10,minmax(0,1fr))}.ad-grid-cols-md-11{grid-template-columns:repeat(11,minmax(0,1fr))}.ad-grid-cols-md-12{grid-template-columns:repeat(12,minmax(0,1fr))}}@media(min-width:1024px){.ad-grid-cols-lg-1{grid-template-columns:repeat(1,minmax(0,1fr))}.ad-grid-cols-lg-2{grid-template-columns:repeat(2,minmax(0,1fr))}.ad-grid-cols-lg-3{grid-template-columns:repeat(3,minmax(0,1fr))}.ad-grid-cols-lg-4{grid-template-columns:repeat(4,minmax(0,1fr))}.ad-grid-cols-lg-5{grid-template-columns:repeat(5,minmax(0,1fr))}.ad-grid-cols-lg-6{grid-template-columns:repeat(6,minmax(0,1fr))}.ad-grid-cols-lg-7{grid-template-columns:repeat(7,minmax(0,1fr))}.ad-grid-cols-lg-8{grid-template-columns:repeat(8,minmax(0,1fr))}.ad-grid-cols-lg-9{grid-template-columns:repeat(9,minmax(0,1fr))}.ad-grid-cols-lg-10{grid-template-columns:repeat(10,minmax(0,1fr))}.ad-grid-cols-lg-11{grid-template-columns:repeat(11,minmax(0,1fr))}.ad-grid-cols-lg-12{grid-template-columns:repeat(12,minmax(0,1fr))}}.ad-grid-gap-1{gap:var(--space-1)}.ad-grid-gap-2{gap:var(--space-2)}.ad-grid-gap-3{gap:var(--space-3)}.ad-grid-gap-4{gap:var(--space-4)}.ad-grid-gap-5{gap:var(--space-5)}.ad-grid-gap-6{gap:var(--space-6)}.ad-grid-gap-7{gap:var(--space-7)}.ad-grid-gap-8{gap:var(--space-8)}.ad-grid-gap-9{gap:var(--space-9)}.ad-grid-gap-10{gap:var(--space-10)}.ad-grid-gap-11{gap:var(--space-11)}.ad-grid-gap-12{gap:var(--space-12)}\n"] }]
659
2484
  }], propDecorators: { cols: [{
660
2485
  type: Input
661
2486
  }], colsMd: [{
@@ -669,163 +2494,372 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
669
2494
  args: ['class']
670
2495
  }] } });
671
2496
 
672
- class CcInlineComponent {
673
- constructor() {
674
- this.gap = input(4, ...(ngDevMode ? [{ debugName: "gap" }] : []));
675
- this.align = input('center', ...(ngDevMode ? [{ debugName: "align" }] : []));
676
- this.justify = input('start', ...(ngDevMode ? [{ debugName: "justify" }] : []));
677
- this.wrap = input(false, ...(ngDevMode ? [{ debugName: "wrap" }] : []));
678
- }
2497
+ class AdStackComponent {
2498
+ gap = input(4, ...(ngDevMode ? [{ debugName: "gap" }] : []));
2499
+ align = input('stretch', ...(ngDevMode ? [{ debugName: "align" }] : []));
2500
+ justify = input('start', ...(ngDevMode ? [{ debugName: "justify" }] : []));
679
2501
  get gapStyle() {
680
2502
  const g = this.gap();
681
2503
  return typeof g === 'number' ? `var(--space-${g})` : g;
682
2504
  }
683
2505
  get alignStyle() {
684
- const map = { start: 'flex-start', center: 'center', end: 'flex-end', baseline: 'baseline' };
2506
+ const map = { start: 'flex-start', center: 'center', end: 'flex-end', stretch: 'stretch' };
685
2507
  return map[this.align()];
686
2508
  }
687
2509
  get justifyStyle() {
688
- const map = { start: 'flex-start', center: 'center', end: 'flex-end', between: 'space-between', around: 'space-around' };
689
- return map[this.justify()];
690
- }
691
- get wrapStyle() {
692
- return this.wrap() ? 'wrap' : 'nowrap';
2510
+ const map = { start: 'flex-start', center: 'center', end: 'flex-end', between: 'space-between' };
2511
+ const j = this.justify();
2512
+ if (j === 'between')
2513
+ return 'space-between';
2514
+ return map[j] || 'flex-start';
693
2515
  }
694
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcInlineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
695
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.4", type: CcInlineComponent, isStandalone: true, selector: "cc-inline", inputs: { gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, justify: { classPropertyName: "justify", publicName: "justify", isSignal: true, isRequired: false, transformFunction: null }, wrap: { classPropertyName: "wrap", publicName: "wrap", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.--inline-gap": "this.gapStyle", "style.--inline-align": "this.alignStyle", "style.--inline-justify": "this.justifyStyle", "style.--inline-wrap": "this.wrapStyle" } }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{display:flex;flex-direction:row;flex-wrap:var(--inline-wrap, nowrap);align-items:var(--inline-align, center);justify-content:var(--inline-justify, flex-start);gap:var(--inline-gap, var(--space-4))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
2516
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdStackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2517
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.4", type: AdStackComponent, isStandalone: true, selector: "ad-stack", inputs: { gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, justify: { classPropertyName: "justify", publicName: "justify", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.gap": "this.gapStyle", "style.align-items": "this.alignStyle", "style.justify-content": "this.justifyStyle" } }, ngImport: i0, template: "<ng-content></ng-content>", styles: [":host{display:flex;flex-direction:column;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
696
2518
  }
697
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcInlineComponent, decorators: [{
2519
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdStackComponent, decorators: [{
698
2520
  type: Component,
699
- args: [{ selector: 'cc-inline', standalone: true, imports: [CommonModule], template: '<ng-content></ng-content>', styles: [":host{display:flex;flex-direction:row;flex-wrap:var(--inline-wrap, nowrap);align-items:var(--inline-align, center);justify-content:var(--inline-justify, flex-start);gap:var(--inline-gap, var(--space-4))}\n"] }]
700
- }], propDecorators: { gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], justify: [{ type: i0.Input, args: [{ isSignal: true, alias: "justify", required: false }] }], wrap: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrap", required: false }] }], gapStyle: [{
2521
+ args: [{ selector: 'ad-stack', standalone: true, imports: [CommonModule], template: "<ng-content></ng-content>", styles: [":host{display:flex;flex-direction:column;width:100%}\n"] }]
2522
+ }], propDecorators: { gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], justify: [{ type: i0.Input, args: [{ isSignal: true, alias: "justify", required: false }] }], gapStyle: [{
701
2523
  type: HostBinding,
702
- args: ['style.--inline-gap']
2524
+ args: ['style.gap']
703
2525
  }], alignStyle: [{
704
2526
  type: HostBinding,
705
- args: ['style.--inline-align']
2527
+ args: ['style.align-items']
706
2528
  }], justifyStyle: [{
707
2529
  type: HostBinding,
708
- args: ['style.--inline-justify']
709
- }], wrapStyle: [{
710
- type: HostBinding,
711
- args: ['style.--inline-wrap']
2530
+ args: ['style.justify-content']
712
2531
  }] } });
713
2532
 
714
- class CcAdminLayoutComponent {
715
- constructor() {
716
- this.menuItems = [];
717
- this.notificationsCount = 0;
718
- this.isSidebarCollapsed = false;
719
- this.isMobileMenuOpen = false;
720
- }
721
- toggleSidebar() {
722
- this.isSidebarCollapsed = !this.isSidebarCollapsed;
723
- }
724
- toggleMobileMenu() {
725
- this.isMobileMenuOpen = !this.isMobileMenuOpen;
726
- }
727
- onNavItemClick(item) {
728
- if (this.isMobileMenuOpen) {
729
- this.isMobileMenuOpen = false;
730
- }
731
- }
732
- onUserAction(action) {
733
- console.log('User action:', action);
734
- }
735
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcAdminLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
736
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcAdminLayoutComponent, isStandalone: true, selector: "cc-admin-layout", inputs: { user: "user", menuItems: "menuItems", notificationsCount: "notificationsCount" }, ngImport: i0, template: "<div class=\"cc-admin-layout\" [class.sidebar-collapsed]=\"isSidebarCollapsed\">\r\n\r\n <cc-sidebar class=\"cc-admin-sidebar\" [class.mobile-open]=\"isMobileMenuOpen\" [menuItems]=\"menuItems\"\r\n [collapsed]=\"isSidebarCollapsed\" (toggleCollapse)=\"toggleSidebar()\" (navigate)=\"onNavItemClick($event)\">\r\n </cc-sidebar>\r\n\r\n <div class=\"cc-admin-main\">\r\n <cc-header [user]=\"user\" [notificationsCount]=\"notificationsCount\" (toggleSidebar)=\"toggleMobileMenu()\"\r\n (userAction)=\"onUserAction($event)\">\r\n </cc-header>\r\n\r\n <main class=\"cc-admin-content\">\r\n <div class=\"cc-admin-content-container\">\r\n <ng-content></ng-content>\r\n </div>\r\n </main>\r\n </div>\r\n\r\n <!-- Overlay para m\u00F3vil -->\r\n <div class=\"cc-admin-overlay\" *ngIf=\"isMobileMenuOpen\" (click)=\"isMobileMenuOpen = false\"></div>\r\n</div>", styles: [".cc-admin-layout{display:flex;min-height:100vh;background-color:var(--color-bg-secondary);--sidebar-width: 280px;--sidebar-collapsed-width: 80px}.cc-admin-layout.sidebar-collapsed{--sidebar-width: var(--sidebar-collapsed-width)}.cc-admin-sidebar{position:fixed;inset-y:0;left:0;z-index:40;width:var(--sidebar-width);transition:width .3s cubic-bezier(.4,0,.2,1);box-shadow:4px 0 24px #0000000d}.cc-admin-sidebar.mobile-open{display:block;box-shadow:var(--shadow-xl)}.cc-admin-main{flex:1;display:flex;flex-direction:column;min-width:0;padding-left:0;transition:padding-left .3s cubic-bezier(.4,0,.2,1)}@media(min-width:1024px){.cc-admin-main{padding-left:var(--sidebar-width)}}.cc-admin-content{flex:1;padding:var(--space-6) var(--space-4);background-color:var(--color-bg-secondary);min-height:calc(100vh - var(--header-height))}@media(min-width:1024px){.cc-admin-content{padding:var(--space-8) var(--space-6)}}.cc-admin-content-container{max-width:1280px;margin:0 auto;width:100%}.cc-admin-overlay{position:fixed;inset:0;background-color:#00000080;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:30}@media(min-width:1024px){.cc-admin-overlay{display:none}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CcHeaderComponent, selector: "cc-header", inputs: ["user", "notificationsCount", "showMenuButton", "hasLogoContent"], outputs: ["toggleSidebar", "userClick", "notificationClick", "userAction"] }, { kind: "component", type: CcSidebarComponent, selector: "cc-sidebar", inputs: ["menuItems", "collapsed", "activeRoute"], outputs: ["navigate", "toggleCollapse"] }] }); }
2533
+ class AdDashboardTemplateComponent {
2534
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
2535
+ title = computed(() => this.resource().title ?? 'Escritorio', ...(ngDevMode ? [{ debugName: "title" }] : []));
2536
+ subtitle = computed(() => this.resource().subtitle, ...(ngDevMode ? [{ debugName: "subtitle" }] : []));
2537
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdDashboardTemplateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2538
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdDashboardTemplateComponent, isStandalone: true, selector: "ad-dashboard-template", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"ad-dashboard-template\">\r\n <header class=\"ad-dashboard-header\">\r\n <ad-stack [gap]=\"1\">\r\n <h1 class=\"ad-dashboard-title\">{{ title() }}</h1>\r\n @if (subtitle()) {\r\n <p class=\"ad-dashboard-subtitle\">{{ subtitle() }}</p>\r\n }\r\n </ad-stack>\r\n <div class=\"ad-dashboard-actions\">\r\n <ng-content select=\"[actions]\"></ng-content>\r\n </div>\r\n </header>\r\n\r\n <ad-grid [cols]=\"1\" [colsMd]=\"2\" [colsLg]=\"4\" [gap]=\"6\" class=\"ad-dashboard-metrics\">\r\n <ng-content select=\"[metrics]\"></ng-content>\r\n </ad-grid>\r\n\r\n <ad-grid [cols]=\"1\" [colsLg]=\"3\" [gap]=\"6\" class=\"ad-dashboard-main\">\r\n <div class=\"ad-dashboard-primary-content\">\r\n <ng-content select=\"[main-content]\"></ng-content>\r\n </div>\r\n <aside class=\"ad-dashboard-secondary-content\">\r\n <ng-content select=\"[sidebar-content]\"></ng-content>\r\n </aside>\r\n </ad-grid>\r\n</div>", styles: [".ad-dashboard-template{display:flex;flex-direction:column;gap:var(--space-8)}.ad-dashboard-header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4)}.ad-dashboard-title{font-size:var(--font-size-3xl);font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1}.ad-dashboard-subtitle{color:var(--color-text-muted);font-size:var(--font-size-md)}.ad-dashboard-metrics{margin-bottom:var(--space-4)}@media(min-width:1024px){.ad-dashboard-primary-content{grid-column:span 2}}.ad-dashboard-secondary-content{display:flex;flex-direction:column;gap:var(--space-6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AdGridComponent, selector: "ad-grid", inputs: ["cols", "colsMd", "colsLg", "gap"] }, { kind: "component", type: AdStackComponent, selector: "ad-stack", inputs: ["gap", "align", "justify"] }] });
737
2539
  }
738
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcAdminLayoutComponent, decorators: [{
2540
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdDashboardTemplateComponent, decorators: [{
739
2541
  type: Component,
740
- args: [{ selector: 'cc-admin-layout', standalone: true, imports: [CommonModule, CcHeaderComponent, CcSidebarComponent, RouterOutlet], template: "<div class=\"cc-admin-layout\" [class.sidebar-collapsed]=\"isSidebarCollapsed\">\r\n\r\n <cc-sidebar class=\"cc-admin-sidebar\" [class.mobile-open]=\"isMobileMenuOpen\" [menuItems]=\"menuItems\"\r\n [collapsed]=\"isSidebarCollapsed\" (toggleCollapse)=\"toggleSidebar()\" (navigate)=\"onNavItemClick($event)\">\r\n </cc-sidebar>\r\n\r\n <div class=\"cc-admin-main\">\r\n <cc-header [user]=\"user\" [notificationsCount]=\"notificationsCount\" (toggleSidebar)=\"toggleMobileMenu()\"\r\n (userAction)=\"onUserAction($event)\">\r\n </cc-header>\r\n\r\n <main class=\"cc-admin-content\">\r\n <div class=\"cc-admin-content-container\">\r\n <ng-content></ng-content>\r\n </div>\r\n </main>\r\n </div>\r\n\r\n <!-- Overlay para m\u00F3vil -->\r\n <div class=\"cc-admin-overlay\" *ngIf=\"isMobileMenuOpen\" (click)=\"isMobileMenuOpen = false\"></div>\r\n</div>", styles: [".cc-admin-layout{display:flex;min-height:100vh;background-color:var(--color-bg-secondary);--sidebar-width: 280px;--sidebar-collapsed-width: 80px}.cc-admin-layout.sidebar-collapsed{--sidebar-width: var(--sidebar-collapsed-width)}.cc-admin-sidebar{position:fixed;inset-y:0;left:0;z-index:40;width:var(--sidebar-width);transition:width .3s cubic-bezier(.4,0,.2,1);box-shadow:4px 0 24px #0000000d}.cc-admin-sidebar.mobile-open{display:block;box-shadow:var(--shadow-xl)}.cc-admin-main{flex:1;display:flex;flex-direction:column;min-width:0;padding-left:0;transition:padding-left .3s cubic-bezier(.4,0,.2,1)}@media(min-width:1024px){.cc-admin-main{padding-left:var(--sidebar-width)}}.cc-admin-content{flex:1;padding:var(--space-6) var(--space-4);background-color:var(--color-bg-secondary);min-height:calc(100vh - var(--header-height))}@media(min-width:1024px){.cc-admin-content{padding:var(--space-8) var(--space-6)}}.cc-admin-content-container{max-width:1280px;margin:0 auto;width:100%}.cc-admin-overlay{position:fixed;inset:0;background-color:#00000080;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:30}@media(min-width:1024px){.cc-admin-overlay{display:none}}\n"] }]
741
- }], propDecorators: { user: [{
742
- type: Input
743
- }], menuItems: [{
744
- type: Input
745
- }], notificationsCount: [{
746
- type: Input
747
- }] } });
2542
+ args: [{ selector: 'ad-dashboard-template', standalone: true, imports: [CommonModule, AdGridComponent, AdStackComponent], template: "<div class=\"ad-dashboard-template\">\r\n <header class=\"ad-dashboard-header\">\r\n <ad-stack [gap]=\"1\">\r\n <h1 class=\"ad-dashboard-title\">{{ title() }}</h1>\r\n @if (subtitle()) {\r\n <p class=\"ad-dashboard-subtitle\">{{ subtitle() }}</p>\r\n }\r\n </ad-stack>\r\n <div class=\"ad-dashboard-actions\">\r\n <ng-content select=\"[actions]\"></ng-content>\r\n </div>\r\n </header>\r\n\r\n <ad-grid [cols]=\"1\" [colsMd]=\"2\" [colsLg]=\"4\" [gap]=\"6\" class=\"ad-dashboard-metrics\">\r\n <ng-content select=\"[metrics]\"></ng-content>\r\n </ad-grid>\r\n\r\n <ad-grid [cols]=\"1\" [colsLg]=\"3\" [gap]=\"6\" class=\"ad-dashboard-main\">\r\n <div class=\"ad-dashboard-primary-content\">\r\n <ng-content select=\"[main-content]\"></ng-content>\r\n </div>\r\n <aside class=\"ad-dashboard-secondary-content\">\r\n <ng-content select=\"[sidebar-content]\"></ng-content>\r\n </aside>\r\n </ad-grid>\r\n</div>", styles: [".ad-dashboard-template{display:flex;flex-direction:column;gap:var(--space-8)}.ad-dashboard-header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4)}.ad-dashboard-title{font-size:var(--font-size-3xl);font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1}.ad-dashboard-subtitle{color:var(--color-text-muted);font-size:var(--font-size-md)}.ad-dashboard-metrics{margin-bottom:var(--space-4)}@media(min-width:1024px){.ad-dashboard-primary-content{grid-column:span 2}}.ad-dashboard-secondary-content{display:flex;flex-direction:column;gap:var(--space-6)}\n"] }]
2543
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }] } });
748
2544
 
749
- class CcAuthLayoutComponent {
750
- constructor() {
751
- this.backgroundType = 'gradient';
2545
+ const DashboardTemplateResourceSchema = z.object({
2546
+ title: z.string().default('Escritorio').optional(),
2547
+ subtitle: z.string().optional(),
2548
+ });
2549
+
2550
+ class AdDocumentationWrapperComponent {
2551
+ wrapperResource = input.required({ ...(ngDevMode ? { debugName: "wrapperResource" } : {}), alias: 'resource' });
2552
+ title = computed(() => this.wrapperResource().title, ...(ngDevMode ? [{ debugName: "title" }] : []));
2553
+ description = computed(() => this.wrapperResource().description, ...(ngDevMode ? [{ debugName: "description" }] : []));
2554
+ code = computed(() => this.wrapperResource().code, ...(ngDevMode ? [{ debugName: "code" }] : []));
2555
+ componentResource = computed(() => this.wrapperResource().componentResource, ...(ngDevMode ? [{ debugName: "componentResource" }] : []));
2556
+ status = computed(() => this.wrapperResource().status ?? 'stable', ...(ngDevMode ? [{ debugName: "status" }] : []));
2557
+ activeTab = signal('preview', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
2558
+ copyToClipboard(text) {
2559
+ navigator.clipboard.writeText(text);
2560
+ // Could add toast notification here
752
2561
  }
753
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcAuthLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
754
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcAuthLayoutComponent, isStandalone: true, selector: "cc-auth-layout", inputs: { backgroundType: "backgroundType" }, ngImport: i0, template: "<div class=\"cc-auth-layout\" [ngClass]=\"'bg-' + backgroundType\">\r\n <div class=\"cc-auth-container\">\r\n <div class=\"cc-auth-card\">\r\n <div class=\"cc-auth-logo\">\r\n <!-- Espacio para logo -->\r\n <div class=\"cc-auth-logo-placeholder\">CERCA</div>\r\n </div>\r\n\r\n <div class=\"cc-auth-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".cc-auth-layout{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:var(--space-4)}.cc-auth-layout.bg-gradient{background:radial-gradient(circle at top left,var(--color-brand-900),var(--neutral-900))}.cc-auth-layout.bg-simple{background-color:var(--color-bg-secondary)}.cc-auth-container{width:100%;max-width:440px}.cc-auth-card{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-2xl);padding:var(--space-8);box-shadow:var(--shadow-2xl)}.cc-auth-logo{display:flex;justify-content:center;margin-bottom:var(--space-8)}.cc-auth-logo .cc-auth-logo-placeholder{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);color:var(--color-brand-600);letter-spacing:-.05em}.cc-auth-content{display:flex;flex-direction:column;gap:var(--space-6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
2562
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdDocumentationWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2563
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdDocumentationWrapperComponent, isStandalone: true, selector: "ad-documentation-wrapper", inputs: { wrapperResource: { classPropertyName: "wrapperResource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
2564
+ <div class="space-y-6">
2565
+ <!-- Header -->
2566
+ <div class="flex items-center justify-between border-b-2 border-stone-100 dark:border-cerca-primary-hover pb-2">
2567
+ <h2 class="text-2xl font-bold text-stone-800 dark:text-white">{{ title() }}</h2>
2568
+ @if (status() === 'new') {
2569
+ <span class="bg-emerald-100 text-emerald-800 text-xs font-medium px-2.5 py-0.5 rounded dark:bg-emerald-900 dark:text-emerald-300">New</span>
2570
+ } @else if (status() === 'updated') {
2571
+ <span class="bg-sky-100 text-sky-800 text-xs font-medium px-2.5 py-0.5 rounded dark:bg-sky-900 dark:text-sky-300">Updated</span>
2572
+ }
2573
+ </div>
2574
+
2575
+ <!-- Description -->
2576
+ <div class="p-4 bg-yellow-50 border-l-4 border-yellow-400 text-stone-700 dark:bg-yellow-900/10 dark:text-yellow-100 dark:border-yellow-600">
2577
+ <p>{{ description() }}</p>
2578
+ </div>
2579
+
2580
+ <!-- Tabs -->
2581
+ <div class="border-b border-stone-200 dark:border-cerca-primary">
2582
+ <nav class="-mb-px flex space-x-8" aria-label="Tabs">
2583
+ <button
2584
+ (click)="activeTab.set('preview')"
2585
+ [class.border-sky-500]="activeTab() === 'preview'"
2586
+ [class.text-sky-600]="activeTab() === 'preview'"
2587
+ [class.dark:text-sky-400]="activeTab() === 'preview'"
2588
+ [class.border-transparent]="activeTab() !== 'preview'"
2589
+ [class.text-stone-500]="activeTab() !== 'preview'"
2590
+ [class.hover:text-stone-700]="activeTab() !== 'preview'"
2591
+ [class.hover:border-stone-300]="activeTab() !== 'preview'"
2592
+ class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200">
2593
+ Preview
2594
+ </button>
2595
+
2596
+ @if (code()) {
2597
+ <button
2598
+ (click)="activeTab.set('code')"
2599
+ [class.border-sky-500]="activeTab() === 'code'"
2600
+ [class.text-sky-600]="activeTab() === 'code'"
2601
+ [class.dark:text-sky-400]="activeTab() === 'code'"
2602
+ [class.border-transparent]="activeTab() !== 'code'"
2603
+ [class.text-stone-500]="activeTab() !== 'code'"
2604
+ [class.hover:text-stone-700]="activeTab() !== 'code'"
2605
+ [class.hover:border-stone-300]="activeTab() !== 'code'"
2606
+ class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200">
2607
+ Code
2608
+ </button>
2609
+ }
2610
+
2611
+ @if (componentResource()) {
2612
+ <button
2613
+ (click)="activeTab.set('resource')"
2614
+ [class.border-sky-500]="activeTab() === 'resource'"
2615
+ [class.text-sky-600]="activeTab() === 'resource'"
2616
+ [class.dark:text-sky-400]="activeTab() === 'resource'"
2617
+ [class.border-transparent]="activeTab() !== 'resource'"
2618
+ [class.text-stone-500]="activeTab() !== 'resource'"
2619
+ [class.hover:text-stone-700]="activeTab() !== 'resource'"
2620
+ [class.hover:border-stone-300]="activeTab() !== 'resource'"
2621
+ class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200">
2622
+ Resource
2623
+ </button>
2624
+ }
2625
+ </nav>
2626
+ </div>
2627
+
2628
+ <!-- Tab Content -->
2629
+ <div class="mt-4">
2630
+ @switch (activeTab()) {
2631
+ @case ('preview') {
2632
+ <div class="p-6 bg-stone-50 rounded-lg border border-stone-200 dark:bg-cerca-primary-active dark:border-cerca-primary">
2633
+ <ng-content></ng-content>
2634
+ </div>
2635
+ }
2636
+ @case ('code') {
2637
+ <div class="relative group">
2638
+ <div class="absolute right-2 top-2 opacity-0 group-hover:opacity-100 transition-opacity">
2639
+ <button (click)="copyToClipboard(code()!)" class="p-1 rounded bg-stone-700 text-white hover:bg-stone-600 text-xs">Copy</button>
2640
+ </div>
2641
+ <pre class="p-4 bg-stone-900 text-stone-50 rounded-lg overflow-x-auto text-sm font-mono leading-relaxed"><code>{{ code() }}</code></pre>
2642
+ </div>
2643
+ }
2644
+ @case ('resource') {
2645
+ <div class="relative group">
2646
+ <div class="absolute right-2 top-2 opacity-0 group-hover:opacity-100 transition-opacity">
2647
+ <button (click)="copyToClipboard(componentResource()!)" class="p-1 rounded bg-stone-700 text-white hover:bg-stone-600 text-xs">Copy</button>
2648
+ </div>
2649
+ <pre class="p-4 bg-stone-900 text-stone-50 rounded-lg overflow-x-auto text-sm font-mono leading-relaxed"><code>{{ componentResource() }}</code></pre>
2650
+ </div>
2651
+ }
2652
+ }
2653
+ </div>
2654
+ </div>
2655
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
755
2656
  }
756
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcAuthLayoutComponent, decorators: [{
2657
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdDocumentationWrapperComponent, decorators: [{
757
2658
  type: Component,
758
- args: [{ selector: 'cc-auth-layout', standalone: true, imports: [CommonModule], template: "<div class=\"cc-auth-layout\" [ngClass]=\"'bg-' + backgroundType\">\r\n <div class=\"cc-auth-container\">\r\n <div class=\"cc-auth-card\">\r\n <div class=\"cc-auth-logo\">\r\n <!-- Espacio para logo -->\r\n <div class=\"cc-auth-logo-placeholder\">CERCA</div>\r\n </div>\r\n\r\n <div class=\"cc-auth-content\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".cc-auth-layout{min-height:100vh;display:flex;align-items:center;justify-content:center;padding:var(--space-4)}.cc-auth-layout.bg-gradient{background:radial-gradient(circle at top left,var(--color-brand-900),var(--neutral-900))}.cc-auth-layout.bg-simple{background-color:var(--color-bg-secondary)}.cc-auth-container{width:100%;max-width:440px}.cc-auth-card{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-2xl);padding:var(--space-8);box-shadow:var(--shadow-2xl)}.cc-auth-logo{display:flex;justify-content:center;margin-bottom:var(--space-8)}.cc-auth-logo .cc-auth-logo-placeholder{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);color:var(--color-brand-600);letter-spacing:-.05em}.cc-auth-content{display:flex;flex-direction:column;gap:var(--space-6)}\n"] }]
759
- }], propDecorators: { backgroundType: [{
760
- type: Input
761
- }] } });
2659
+ args: [{
2660
+ selector: 'ad-documentation-wrapper',
2661
+ standalone: true,
2662
+ imports: [CommonModule],
2663
+ template: `
2664
+ <div class="space-y-6">
2665
+ <!-- Header -->
2666
+ <div class="flex items-center justify-between border-b-2 border-stone-100 dark:border-cerca-primary-hover pb-2">
2667
+ <h2 class="text-2xl font-bold text-stone-800 dark:text-white">{{ title() }}</h2>
2668
+ @if (status() === 'new') {
2669
+ <span class="bg-emerald-100 text-emerald-800 text-xs font-medium px-2.5 py-0.5 rounded dark:bg-emerald-900 dark:text-emerald-300">New</span>
2670
+ } @else if (status() === 'updated') {
2671
+ <span class="bg-sky-100 text-sky-800 text-xs font-medium px-2.5 py-0.5 rounded dark:bg-sky-900 dark:text-sky-300">Updated</span>
2672
+ }
2673
+ </div>
2674
+
2675
+ <!-- Description -->
2676
+ <div class="p-4 bg-yellow-50 border-l-4 border-yellow-400 text-stone-700 dark:bg-yellow-900/10 dark:text-yellow-100 dark:border-yellow-600">
2677
+ <p>{{ description() }}</p>
2678
+ </div>
2679
+
2680
+ <!-- Tabs -->
2681
+ <div class="border-b border-stone-200 dark:border-cerca-primary">
2682
+ <nav class="-mb-px flex space-x-8" aria-label="Tabs">
2683
+ <button
2684
+ (click)="activeTab.set('preview')"
2685
+ [class.border-sky-500]="activeTab() === 'preview'"
2686
+ [class.text-sky-600]="activeTab() === 'preview'"
2687
+ [class.dark:text-sky-400]="activeTab() === 'preview'"
2688
+ [class.border-transparent]="activeTab() !== 'preview'"
2689
+ [class.text-stone-500]="activeTab() !== 'preview'"
2690
+ [class.hover:text-stone-700]="activeTab() !== 'preview'"
2691
+ [class.hover:border-stone-300]="activeTab() !== 'preview'"
2692
+ class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200">
2693
+ Preview
2694
+ </button>
2695
+
2696
+ @if (code()) {
2697
+ <button
2698
+ (click)="activeTab.set('code')"
2699
+ [class.border-sky-500]="activeTab() === 'code'"
2700
+ [class.text-sky-600]="activeTab() === 'code'"
2701
+ [class.dark:text-sky-400]="activeTab() === 'code'"
2702
+ [class.border-transparent]="activeTab() !== 'code'"
2703
+ [class.text-stone-500]="activeTab() !== 'code'"
2704
+ [class.hover:text-stone-700]="activeTab() !== 'code'"
2705
+ [class.hover:border-stone-300]="activeTab() !== 'code'"
2706
+ class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200">
2707
+ Code
2708
+ </button>
2709
+ }
2710
+
2711
+ @if (componentResource()) {
2712
+ <button
2713
+ (click)="activeTab.set('resource')"
2714
+ [class.border-sky-500]="activeTab() === 'resource'"
2715
+ [class.text-sky-600]="activeTab() === 'resource'"
2716
+ [class.dark:text-sky-400]="activeTab() === 'resource'"
2717
+ [class.border-transparent]="activeTab() !== 'resource'"
2718
+ [class.text-stone-500]="activeTab() !== 'resource'"
2719
+ [class.hover:text-stone-700]="activeTab() !== 'resource'"
2720
+ [class.hover:border-stone-300]="activeTab() !== 'resource'"
2721
+ class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm transition-colors duration-200">
2722
+ Resource
2723
+ </button>
2724
+ }
2725
+ </nav>
2726
+ </div>
2727
+
2728
+ <!-- Tab Content -->
2729
+ <div class="mt-4">
2730
+ @switch (activeTab()) {
2731
+ @case ('preview') {
2732
+ <div class="p-6 bg-stone-50 rounded-lg border border-stone-200 dark:bg-cerca-primary-active dark:border-cerca-primary">
2733
+ <ng-content></ng-content>
2734
+ </div>
2735
+ }
2736
+ @case ('code') {
2737
+ <div class="relative group">
2738
+ <div class="absolute right-2 top-2 opacity-0 group-hover:opacity-100 transition-opacity">
2739
+ <button (click)="copyToClipboard(code()!)" class="p-1 rounded bg-stone-700 text-white hover:bg-stone-600 text-xs">Copy</button>
2740
+ </div>
2741
+ <pre class="p-4 bg-stone-900 text-stone-50 rounded-lg overflow-x-auto text-sm font-mono leading-relaxed"><code>{{ code() }}</code></pre>
2742
+ </div>
2743
+ }
2744
+ @case ('resource') {
2745
+ <div class="relative group">
2746
+ <div class="absolute right-2 top-2 opacity-0 group-hover:opacity-100 transition-opacity">
2747
+ <button (click)="copyToClipboard(componentResource()!)" class="p-1 rounded bg-stone-700 text-white hover:bg-stone-600 text-xs">Copy</button>
2748
+ </div>
2749
+ <pre class="p-4 bg-stone-900 text-stone-50 rounded-lg overflow-x-auto text-sm font-mono leading-relaxed"><code>{{ componentResource() }}</code></pre>
2750
+ </div>
2751
+ }
2752
+ }
2753
+ </div>
2754
+ </div>
2755
+ `,
2756
+ encapsulation: ViewEncapsulation.None
2757
+ }]
2758
+ }], propDecorators: { wrapperResource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }] } });
762
2759
 
763
- class CcDashboardTemplateComponent {
764
- constructor() {
765
- this.title = 'Escritorio';
766
- }
767
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcDashboardTemplateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
768
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcDashboardTemplateComponent, isStandalone: true, selector: "cc-dashboard-template", inputs: { title: "title", subtitle: "subtitle" }, ngImport: i0, template: "<div class=\"cc-dashboard-template\">\r\n <header class=\"cc-dashboard-header\">\r\n <cc-stack [gap]=\"1\">\r\n <h1 class=\"cc-dashboard-title\">{{ title }}</h1>\r\n <p class=\"cc-dashboard-subtitle\" *ngIf=\"subtitle\">{{ subtitle }}</p>\r\n </cc-stack>\r\n <div class=\"cc-dashboard-actions\">\r\n <ng-content select=\"[actions]\"></ng-content>\r\n </div>\r\n </header>\r\n\r\n <cc-grid [cols]=\"1\" [colsMd]=\"2\" [colsLg]=\"4\" [gap]=\"6\" class=\"cc-dashboard-metrics\">\r\n <ng-content select=\"[metrics]\"></ng-content>\r\n </cc-grid>\r\n\r\n <cc-grid [cols]=\"1\" [colsLg]=\"3\" [gap]=\"6\" class=\"cc-dashboard-main\">\r\n <div class=\"cc-dashboard-primary-content\">\r\n <ng-content select=\"[main-content]\"></ng-content>\r\n </div>\r\n <aside class=\"cc-dashboard-secondary-content\">\r\n <ng-content select=\"[sidebar-content]\"></ng-content>\r\n </aside>\r\n </cc-grid>\r\n</div>", styles: [".cc-dashboard-template{display:flex;flex-direction:column;gap:var(--space-8)}.cc-dashboard-header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4)}.cc-dashboard-title{font-size:var(--font-size-3xl);font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1}.cc-dashboard-subtitle{color:var(--color-text-muted);font-size:var(--font-size-md)}.cc-dashboard-metrics{margin-bottom:var(--space-4)}@media(min-width:1024px){.cc-dashboard-primary-content{grid-column:span 2}}.cc-dashboard-secondary-content{display:flex;flex-direction:column;gap:var(--space-6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CcGridComponent, selector: "cc-grid", inputs: ["cols", "colsMd", "colsLg", "gap"] }, { kind: "component", type: CcStackComponent, selector: "cc-stack", inputs: ["gap", "align", "justify"] }] }); }
2760
+ const DocStatusSchema = z.enum(['new', 'updated', 'stable']);
2761
+ const DocumentationWrapperResourceSchema = z.object({
2762
+ title: z.string(),
2763
+ description: z.string(),
2764
+ code: z.string().optional(),
2765
+ componentResource: z.string().optional(),
2766
+ status: z.enum(['new', 'updated', 'stable']).default('stable').optional(),
2767
+ });
2768
+
2769
+ class AdFormLayoutComponent {
2770
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
2771
+ gap = computed(() => this.resource().gap ?? 'md', ...(ngDevMode ? [{ debugName: "gap" }] : []));
2772
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdFormLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2773
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.4", type: AdFormLayoutComponent, isStandalone: true, selector: "ad-form-layout", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
2774
+ <form class="grid grid-cols-1 md:grid-cols-12 gap-6 items-start">
2775
+ <ng-content></ng-content>
2776
+
2777
+ <!-- Footer Actions -->
2778
+ <div class="md:col-span-12 mt-6 flex justify-end gap-3 border-t border-stone-200 dark:border-cerca-primary pt-6">
2779
+ <ng-content select="[footer-actions]"></ng-content>
2780
+ </div>
2781
+ </form>
2782
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }], encapsulation: i0.ViewEncapsulation.None });
769
2783
  }
770
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcDashboardTemplateComponent, decorators: [{
2784
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdFormLayoutComponent, decorators: [{
771
2785
  type: Component,
772
- args: [{ selector: 'cc-dashboard-template', standalone: true, imports: [CommonModule, CcGridComponent, CcStackComponent], template: "<div class=\"cc-dashboard-template\">\r\n <header class=\"cc-dashboard-header\">\r\n <cc-stack [gap]=\"1\">\r\n <h1 class=\"cc-dashboard-title\">{{ title }}</h1>\r\n <p class=\"cc-dashboard-subtitle\" *ngIf=\"subtitle\">{{ subtitle }}</p>\r\n </cc-stack>\r\n <div class=\"cc-dashboard-actions\">\r\n <ng-content select=\"[actions]\"></ng-content>\r\n </div>\r\n </header>\r\n\r\n <cc-grid [cols]=\"1\" [colsMd]=\"2\" [colsLg]=\"4\" [gap]=\"6\" class=\"cc-dashboard-metrics\">\r\n <ng-content select=\"[metrics]\"></ng-content>\r\n </cc-grid>\r\n\r\n <cc-grid [cols]=\"1\" [colsLg]=\"3\" [gap]=\"6\" class=\"cc-dashboard-main\">\r\n <div class=\"cc-dashboard-primary-content\">\r\n <ng-content select=\"[main-content]\"></ng-content>\r\n </div>\r\n <aside class=\"cc-dashboard-secondary-content\">\r\n <ng-content select=\"[sidebar-content]\"></ng-content>\r\n </aside>\r\n </cc-grid>\r\n</div>", styles: [".cc-dashboard-template{display:flex;flex-direction:column;gap:var(--space-8)}.cc-dashboard-header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4)}.cc-dashboard-title{font-size:var(--font-size-3xl);font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1}.cc-dashboard-subtitle{color:var(--color-text-muted);font-size:var(--font-size-md)}.cc-dashboard-metrics{margin-bottom:var(--space-4)}@media(min-width:1024px){.cc-dashboard-primary-content{grid-column:span 2}}.cc-dashboard-secondary-content{display:flex;flex-direction:column;gap:var(--space-6)}\n"] }]
773
- }], propDecorators: { title: [{
774
- type: Input
775
- }], subtitle: [{
776
- type: Input
777
- }] } });
2786
+ args: [{
2787
+ selector: 'ad-form-layout',
2788
+ standalone: true,
2789
+ imports: [CommonModule],
2790
+ template: `
2791
+ <form class="grid grid-cols-1 md:grid-cols-12 gap-6 items-start">
2792
+ <ng-content></ng-content>
2793
+
2794
+ <!-- Footer Actions -->
2795
+ <div class="md:col-span-12 mt-6 flex justify-end gap-3 border-t border-stone-200 dark:border-cerca-primary pt-6">
2796
+ <ng-content select="[footer-actions]"></ng-content>
2797
+ </div>
2798
+ </form>
2799
+ `,
2800
+ encapsulation: ViewEncapsulation.None
2801
+ }]
2802
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }] } });
778
2803
 
779
- class CcListPageTemplateComponent {
780
- constructor() {
781
- this.title = '';
782
- this.hasFilters = true; // Added missing property
783
- }
784
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcListPageTemplateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
785
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcListPageTemplateComponent, isStandalone: true, selector: "cc-list-page-template", inputs: { title: "title", description: "description", hasFilters: "hasFilters" }, queries: [{ propertyName: "filtersTemplate", first: true, predicate: ["filters"], descendants: true }], ngImport: i0, template: "<div class=\"cc-list-page\">\r\n <header class=\"cc-page-header\">\r\n <cc-stack [gap]=\"1\">\r\n <h1 class=\"cc-page-title\">{{ title }}</h1>\r\n <p class=\"cc-page-description\" *ngIf=\"description\">{{ description }}</p>\r\n </cc-stack>\r\n <div class=\"cc-page-actions\">\r\n <ng-content select=\"[actions]\"></ng-content>\r\n </div>\r\n </header>\r\n\r\n <section class=\"cc-page-filters\" *ngIf=\"hasFilters\">\r\n <ng-content select=\"[filters]\"></ng-content>\r\n </section>\r\n\r\n <main class=\"cc-page-main\">\r\n <ng-content select=\"[table]\"></ng-content>\r\n </main>\r\n\r\n <footer class=\"cc-page-footer\">\r\n <ng-content select=\"[pagination]\"></ng-content>\r\n </footer>\r\n</div>", styles: [".cc-list-page{display:flex;flex-direction:column;gap:var(--space-6)}.cc-page-header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4);margin-bottom:var(--space-2)}.cc-page-title{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1.2}.cc-page-description{color:var(--color-text-muted);font-size:var(--font-size-sm)}.cc-page-filters{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-xl);padding:var(--space-4)}.cc-page-main{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-xl);overflow:hidden;box-shadow:var(--shadow-sm)}.cc-page-footer{display:flex;justify-content:flex-end;margin-top:var(--space-2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CcStackComponent, selector: "cc-stack", inputs: ["gap", "align", "justify"] }] }); }
2804
+ const FormLayoutResourceSchema = z.object({
2805
+ gap: z.enum(['sm', 'md', 'lg']).default('md').optional(),
2806
+ });
2807
+
2808
+ class AdFormPageTemplateComponent {
2809
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
2810
+ title = computed(() => this.resource().title ?? '', ...(ngDevMode ? [{ debugName: "title" }] : []));
2811
+ backUrl = computed(() => this.resource().backUrl, ...(ngDevMode ? [{ debugName: "backUrl" }] : []));
2812
+ loading = computed(() => this.resource().loading ?? false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
2813
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdFormPageTemplateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2814
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdFormPageTemplateComponent, isStandalone: true, selector: "ad-form-page-template", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"ad-form-page\">\r\n <header class=\"ad-form-page-header\">\r\n <ad-stack [gap]=\"1\">\r\n <div class=\"ad-form-page-nav\">\r\n <ng-content select=\"[back-button]\"></ng-content>\r\n </div>\r\n <h1 class=\"ad-form-page-title\">{{ title() }}</h1>\r\n </ad-stack>\r\n <div class=\"ad-form-page-actions-header\">\r\n <ng-content select=\"[header-actions]\"></ng-content>\r\n </div>\r\n </header>\r\n\r\n <main class=\"ad-form-page-main\">\r\n <div class=\"ad-form-page-card\">\r\n <ng-content select=\"[form-content]\"></ng-content>\r\n </div>\r\n </main>\r\n\r\n <footer class=\"ad-form-page-footer\">\r\n <ng-content select=\"[form-actions]\"></ng-content>\r\n </footer>\r\n\r\n @if (loading()) {\r\n <div class=\"ad-form-page-loading-overlay\">\r\n <div class=\"ad-form-page-spinner\"></div>\r\n </div>\r\n }\r\n</div>", styles: [".ad-form-page{display:flex;flex-direction:column;gap:var(--space-6);position:relative;min-height:100%}.ad-form-page-header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4);margin-bottom:var(--space-2)}.ad-form-page-title{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);color:var(--color-text-primary)}.ad-form-page-main{flex:1}.ad-form-page-card{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-2xl);padding:var(--space-6);box-shadow:var(--shadow-sm)}@media(min-width:768px){.ad-form-page-card{padding:var(--space-8)}}.ad-form-page-footer{background-color:var(--color-bg-primary);border-top:1px solid var(--color-border-subtle);padding:var(--space-4) var(--space-6);margin:0 calc(var(--space-6) * -1);display:flex;justify-content:flex-end;gap:var(--space-4);border-bottom-left-radius:var(--radius-2xl);border-bottom-right-radius:var(--radius-2xl)}.ad-form-page-loading-overlay{position:absolute;inset:0;background-color:#ffffffbf;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:flex;align-items:center;justify-content:center;z-index:50;border-radius:var(--radius-2xl)}.ad-form-page-spinner{width:40px;height:40px;border:3px solid var(--color-border-subtle);border-top-color:var(--color-brand-600);border-radius:50%;animation:ad-spin .8s linear infinite}@keyframes ad-spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AdStackComponent, selector: "ad-stack", inputs: ["gap", "align", "justify"] }] });
786
2815
  }
787
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcListPageTemplateComponent, decorators: [{
2816
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdFormPageTemplateComponent, decorators: [{
788
2817
  type: Component,
789
- args: [{ selector: 'cc-list-page-template', standalone: true, imports: [CommonModule, CcStackComponent], template: "<div class=\"cc-list-page\">\r\n <header class=\"cc-page-header\">\r\n <cc-stack [gap]=\"1\">\r\n <h1 class=\"cc-page-title\">{{ title }}</h1>\r\n <p class=\"cc-page-description\" *ngIf=\"description\">{{ description }}</p>\r\n </cc-stack>\r\n <div class=\"cc-page-actions\">\r\n <ng-content select=\"[actions]\"></ng-content>\r\n </div>\r\n </header>\r\n\r\n <section class=\"cc-page-filters\" *ngIf=\"hasFilters\">\r\n <ng-content select=\"[filters]\"></ng-content>\r\n </section>\r\n\r\n <main class=\"cc-page-main\">\r\n <ng-content select=\"[table]\"></ng-content>\r\n </main>\r\n\r\n <footer class=\"cc-page-footer\">\r\n <ng-content select=\"[pagination]\"></ng-content>\r\n </footer>\r\n</div>", styles: [".cc-list-page{display:flex;flex-direction:column;gap:var(--space-6)}.cc-page-header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4);margin-bottom:var(--space-2)}.cc-page-title{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1.2}.cc-page-description{color:var(--color-text-muted);font-size:var(--font-size-sm)}.cc-page-filters{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-xl);padding:var(--space-4)}.cc-page-main{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-xl);overflow:hidden;box-shadow:var(--shadow-sm)}.cc-page-footer{display:flex;justify-content:flex-end;margin-top:var(--space-2)}\n"] }]
790
- }], propDecorators: { title: [{
791
- type: Input
792
- }], description: [{
793
- type: Input
794
- }], hasFilters: [{
795
- type: Input
796
- }], filtersTemplate: [{
797
- type: ContentChild,
798
- args: ['filters']
799
- }] } });
2818
+ args: [{ selector: 'ad-form-page-template', standalone: true, imports: [CommonModule, AdStackComponent], template: "<div class=\"ad-form-page\">\r\n <header class=\"ad-form-page-header\">\r\n <ad-stack [gap]=\"1\">\r\n <div class=\"ad-form-page-nav\">\r\n <ng-content select=\"[back-button]\"></ng-content>\r\n </div>\r\n <h1 class=\"ad-form-page-title\">{{ title() }}</h1>\r\n </ad-stack>\r\n <div class=\"ad-form-page-actions-header\">\r\n <ng-content select=\"[header-actions]\"></ng-content>\r\n </div>\r\n </header>\r\n\r\n <main class=\"ad-form-page-main\">\r\n <div class=\"ad-form-page-card\">\r\n <ng-content select=\"[form-content]\"></ng-content>\r\n </div>\r\n </main>\r\n\r\n <footer class=\"ad-form-page-footer\">\r\n <ng-content select=\"[form-actions]\"></ng-content>\r\n </footer>\r\n\r\n @if (loading()) {\r\n <div class=\"ad-form-page-loading-overlay\">\r\n <div class=\"ad-form-page-spinner\"></div>\r\n </div>\r\n }\r\n</div>", styles: [".ad-form-page{display:flex;flex-direction:column;gap:var(--space-6);position:relative;min-height:100%}.ad-form-page-header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4);margin-bottom:var(--space-2)}.ad-form-page-title{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);color:var(--color-text-primary)}.ad-form-page-main{flex:1}.ad-form-page-card{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-2xl);padding:var(--space-6);box-shadow:var(--shadow-sm)}@media(min-width:768px){.ad-form-page-card{padding:var(--space-8)}}.ad-form-page-footer{background-color:var(--color-bg-primary);border-top:1px solid var(--color-border-subtle);padding:var(--space-4) var(--space-6);margin:0 calc(var(--space-6) * -1);display:flex;justify-content:flex-end;gap:var(--space-4);border-bottom-left-radius:var(--radius-2xl);border-bottom-right-radius:var(--radius-2xl)}.ad-form-page-loading-overlay{position:absolute;inset:0;background-color:#ffffffbf;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:flex;align-items:center;justify-content:center;z-index:50;border-radius:var(--radius-2xl)}.ad-form-page-spinner{width:40px;height:40px;border:3px solid var(--color-border-subtle);border-top-color:var(--color-brand-600);border-radius:50%;animation:ad-spin .8s linear infinite}@keyframes ad-spin{to{transform:rotate(360deg)}}\n"] }]
2819
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }] } });
800
2820
 
801
- class CcFormPageTemplateComponent {
802
- constructor() {
803
- this.title = '';
804
- this.loading = false;
805
- }
806
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcFormPageTemplateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
807
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.4", type: CcFormPageTemplateComponent, isStandalone: true, selector: "cc-form-page-template", inputs: { title: "title", backUrl: "backUrl", loading: "loading" }, ngImport: i0, template: "<div class=\"cc-form-page\">\r\n <header class=\"cc-form-page-header\">\r\n <cc-stack [gap]=\"1\">\r\n <div class=\"cc-form-page-nav\">\r\n <ng-content select=\"[back-button]\"></ng-content>\r\n </div>\r\n <h1 class=\"cc-form-page-title\">{{ title }}</h1>\r\n </cc-stack>\r\n <div class=\"cc-form-page-actions-header\">\r\n <ng-content select=\"[header-actions]\"></ng-content>\r\n </div>\r\n </header>\r\n\r\n <main class=\"cc-form-page-main\">\r\n <div class=\"cc-form-page-card\">\r\n <ng-content select=\"[form-content]\"></ng-content>\r\n </div>\r\n </main>\r\n\r\n <footer class=\"cc-form-page-footer\">\r\n <ng-content select=\"[form-actions]\"></ng-content>\r\n </footer>\r\n\r\n <div class=\"cc-form-page-loading-overlay\" *ngIf=\"loading\">\r\n <div class=\"cc-form-page-spinner\"></div>\r\n </div>\r\n</div>", styles: [".cc-form-page{display:flex;flex-direction:column;gap:var(--space-6);position:relative;min-height:100%}.cc-form-page-header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4);margin-bottom:var(--space-2)}.cc-form-page-title{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);color:var(--color-text-primary)}.cc-form-page-main{flex:1}.cc-form-page-card{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-2xl);padding:var(--space-6);box-shadow:var(--shadow-sm)}@media(min-width:768px){.cc-form-page-card{padding:var(--space-8)}}.cc-form-page-footer{background-color:var(--color-bg-primary);border-top:1px solid var(--color-border-subtle);padding:var(--space-4) var(--space-6);margin:0 calc(var(--space-6) * -1);display:flex;justify-content:flex-end;gap:var(--space-4);border-bottom-left-radius:var(--radius-2xl);border-bottom-right-radius:var(--radius-2xl)}.cc-form-page-loading-overlay{position:absolute;inset:0;background-color:#ffffffbf;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:flex;align-items:center;justify-content:center;z-index:50;border-radius:var(--radius-2xl)}.cc-form-page-spinner{width:40px;height:40px;border:3px solid var(--color-border-subtle);border-top-color:var(--color-brand-600);border-radius:50%;animation:cc-spin .8s linear infinite}@keyframes cc-spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CcStackComponent, selector: "cc-stack", inputs: ["gap", "align", "justify"] }] }); }
2821
+ const FormPageTemplateResourceSchema = z.object({
2822
+ title: z.string().default(''),
2823
+ backUrl: z.string().optional(),
2824
+ loading: z.boolean().default(false).optional(),
2825
+ });
2826
+
2827
+ const FormSectionResourceSchema = z.object({
2828
+ title: z.string().optional(),
2829
+ cols: z.number().default(12).optional(),
2830
+ loading: z.boolean().default(false).optional(),
2831
+ });
2832
+
2833
+ class AdListPageTemplateComponent {
2834
+ resource = input.required(...(ngDevMode ? [{ debugName: "resource" }] : []));
2835
+ title = computed(() => this.resource().title ?? '', ...(ngDevMode ? [{ debugName: "title" }] : []));
2836
+ description = computed(() => this.resource().description, ...(ngDevMode ? [{ debugName: "description" }] : []));
2837
+ hasFilters = computed(() => this.resource().hasFilters ?? true, ...(ngDevMode ? [{ debugName: "hasFilters" }] : []));
2838
+ filtersTemplate;
2839
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdListPageTemplateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2840
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: AdListPageTemplateComponent, isStandalone: true, selector: "ad-list-page-template", inputs: { resource: { classPropertyName: "resource", publicName: "resource", isSignal: true, isRequired: true, transformFunction: null } }, queries: [{ propertyName: "filtersTemplate", first: true, predicate: ["filters"], descendants: true }], ngImport: i0, template: "<div class=\"ad-list-page\">\r\n <header class=\"ad-page-header\">\r\n <ad-stack [gap]=\"1\">\r\n <h1 class=\"ad-page-title\">{{ title() }}</h1>\r\n @if (description()) {\r\n <p class=\"ad-page-description\">{{ description() }}</p>\r\n }\r\n </ad-stack>\r\n <div class=\"ad-page-actions\">\r\n <ng-content select=\"[actions]\"></ng-content>\r\n </div>\r\n </header>\r\n\r\n @if (hasFilters()) {\r\n <section class=\"ad-page-filters\">\r\n <ng-content select=\"[filters]\"></ng-content>\r\n </section>\r\n }\r\n\r\n <main class=\"ad-page-main\">\r\n <ng-content select=\"[table]\"></ng-content>\r\n </main>\r\n\r\n <footer class=\"ad-page-footer\">\r\n <ng-content select=\"[pagination]\"></ng-content>\r\n </footer>\r\n</div>", styles: [".ad-list-page{display:flex;flex-direction:column;gap:var(--space-6)}.ad-page-header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4);margin-bottom:var(--space-2)}.ad-page-title{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1.2}.ad-page-description{color:var(--color-text-muted);font-size:var(--font-size-sm)}.ad-page-filters{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-xl);padding:var(--space-4)}.ad-page-main{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-xl);overflow:hidden;box-shadow:var(--shadow-sm)}.ad-page-footer{display:flex;justify-content:flex-end;margin-top:var(--space-2)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: AdStackComponent, selector: "ad-stack", inputs: ["gap", "align", "justify"] }] });
808
2841
  }
809
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: CcFormPageTemplateComponent, decorators: [{
2842
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: AdListPageTemplateComponent, decorators: [{
810
2843
  type: Component,
811
- args: [{ selector: 'cc-form-page-template', standalone: true, imports: [CommonModule, CcStackComponent], template: "<div class=\"cc-form-page\">\r\n <header class=\"cc-form-page-header\">\r\n <cc-stack [gap]=\"1\">\r\n <div class=\"cc-form-page-nav\">\r\n <ng-content select=\"[back-button]\"></ng-content>\r\n </div>\r\n <h1 class=\"cc-form-page-title\">{{ title }}</h1>\r\n </cc-stack>\r\n <div class=\"cc-form-page-actions-header\">\r\n <ng-content select=\"[header-actions]\"></ng-content>\r\n </div>\r\n </header>\r\n\r\n <main class=\"cc-form-page-main\">\r\n <div class=\"cc-form-page-card\">\r\n <ng-content select=\"[form-content]\"></ng-content>\r\n </div>\r\n </main>\r\n\r\n <footer class=\"cc-form-page-footer\">\r\n <ng-content select=\"[form-actions]\"></ng-content>\r\n </footer>\r\n\r\n <div class=\"cc-form-page-loading-overlay\" *ngIf=\"loading\">\r\n <div class=\"cc-form-page-spinner\"></div>\r\n </div>\r\n</div>", styles: [".cc-form-page{display:flex;flex-direction:column;gap:var(--space-6);position:relative;min-height:100%}.cc-form-page-header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4);margin-bottom:var(--space-2)}.cc-form-page-title{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);color:var(--color-text-primary)}.cc-form-page-main{flex:1}.cc-form-page-card{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-2xl);padding:var(--space-6);box-shadow:var(--shadow-sm)}@media(min-width:768px){.cc-form-page-card{padding:var(--space-8)}}.cc-form-page-footer{background-color:var(--color-bg-primary);border-top:1px solid var(--color-border-subtle);padding:var(--space-4) var(--space-6);margin:0 calc(var(--space-6) * -1);display:flex;justify-content:flex-end;gap:var(--space-4);border-bottom-left-radius:var(--radius-2xl);border-bottom-right-radius:var(--radius-2xl)}.cc-form-page-loading-overlay{position:absolute;inset:0;background-color:#ffffffbf;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);display:flex;align-items:center;justify-content:center;z-index:50;border-radius:var(--radius-2xl)}.cc-form-page-spinner{width:40px;height:40px;border:3px solid var(--color-border-subtle);border-top-color:var(--color-brand-600);border-radius:50%;animation:cc-spin .8s linear infinite}@keyframes cc-spin{to{transform:rotate(360deg)}}\n"] }]
812
- }], propDecorators: { title: [{
813
- type: Input
814
- }], backUrl: [{
815
- type: Input
816
- }], loading: [{
817
- type: Input
2844
+ args: [{ selector: 'ad-list-page-template', standalone: true, imports: [CommonModule, AdStackComponent], template: "<div class=\"ad-list-page\">\r\n <header class=\"ad-page-header\">\r\n <ad-stack [gap]=\"1\">\r\n <h1 class=\"ad-page-title\">{{ title() }}</h1>\r\n @if (description()) {\r\n <p class=\"ad-page-description\">{{ description() }}</p>\r\n }\r\n </ad-stack>\r\n <div class=\"ad-page-actions\">\r\n <ng-content select=\"[actions]\"></ng-content>\r\n </div>\r\n </header>\r\n\r\n @if (hasFilters()) {\r\n <section class=\"ad-page-filters\">\r\n <ng-content select=\"[filters]\"></ng-content>\r\n </section>\r\n }\r\n\r\n <main class=\"ad-page-main\">\r\n <ng-content select=\"[table]\"></ng-content>\r\n </main>\r\n\r\n <footer class=\"ad-page-footer\">\r\n <ng-content select=\"[pagination]\"></ng-content>\r\n </footer>\r\n</div>", styles: [".ad-list-page{display:flex;flex-direction:column;gap:var(--space-6)}.ad-page-header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4);margin-bottom:var(--space-2)}.ad-page-title{font-size:var(--font-size-2xl);font-weight:var(--font-weight-bold);color:var(--color-text-primary);line-height:1.2}.ad-page-description{color:var(--color-text-muted);font-size:var(--font-size-sm)}.ad-page-filters{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-xl);padding:var(--space-4)}.ad-page-main{background-color:var(--color-bg-primary);border:1px solid var(--color-border-subtle);border-radius:var(--radius-xl);overflow:hidden;box-shadow:var(--shadow-sm)}.ad-page-footer{display:flex;justify-content:flex-end;margin-top:var(--space-2)}\n"] }]
2845
+ }], propDecorators: { resource: [{ type: i0.Input, args: [{ isSignal: true, alias: "resource", required: true }] }], filtersTemplate: [{
2846
+ type: ContentChild,
2847
+ args: ['filters']
818
2848
  }] } });
819
2849
 
820
- // Atoms
2850
+ const ListPageTemplateResourceSchema = z.object({
2851
+ title: z.string().default(''),
2852
+ description: z.string().optional(),
2853
+ hasFilters: z.boolean().default(true).optional(),
2854
+ });
821
2855
 
822
2856
  /*
823
- * Public API Surface of @cerca/design-system
2857
+ * Public API Surface of design-system
824
2858
  */
825
2859
 
826
2860
  /**
827
2861
  * Generated bundle index. Do not edit.
828
2862
  */
829
2863
 
830
- export { CcAdminLayoutComponent, CcAuthLayoutComponent, CcBadgeComponent, CcButtonComponent, CcCardComponent, CcContainerComponent, CcDashboardTemplateComponent, CcDataTableComponent, CcFormFieldComponent, CcFormPageTemplateComponent, CcGridComponent, CcHeaderComponent, CcIconComponent, CcInlineComponent, CcInputComponent, CcLabelComponent, CcListPageTemplateComponent, CcLoginComponent, CcModalComponent, CcSearchBarComponent, CcSelectComponent, CcSidebarComponent, CcStackComponent };
2864
+ export { AdAdminLayoutComponent, AdAuthLayoutComponent, AdBadgeComponent, AdButtonComponent, AdCardComponent, AdDashboardTemplateComponent, AdDataTableComponent, AdDescriptionHeaderComponent, AdDocViewerComponent, AdDocumentationWrapperComponent, AdFormFieldComponent, AdFormLayoutComponent, AdFormPageTemplateComponent, AdFormSectionComponent, AdHeaderComponent, AdIconComponent, AdInputComponent, AdLabelComponent, AdListPageTemplateComponent, AdLoadingComponent, AdLoginComponent, AdModalComponent, AdModalService, AdModalTriggerComponent, AdModalWrapperComponent, AdSearchBarComponent, AdSelectComponent, AdSidebarComponent, AdStatCardComponent, AdSwitchComponent, AdTableColumnSchema, AdTableComponent, AdminLayoutResourceSchema, AdminSectionCardActionSchema, AdminSectionCardComponent, AdminSectionCardResourceSchema, AuthLayoutResourceSchema, CardResourceSchema, ComponentApiInputSchema, ComponentApiOutputSchema, ComponentVariantSchema, DashboardTemplateResourceSchema, DataTableColumnSchema, DataTableResourceSchema, DescriptionHeaderButtonSchema, DescriptionHeaderResourceSchema, DesignSystem, DocStatusSchema, DocViewerResourceSchema, DocumentationWrapperResourceSchema, FieldRendererRegistry, FormEngineComponent, FormEngineService, FormFieldResourceSchema, FormLayoutResourceSchema, FormPageTemplateResourceSchema, FormSectionResourceSchema, HeaderResourceSchema, ListPageTemplateResourceSchema, LoginResourceSchema, ModalResourceSchema, ModalTriggerResourceSchema, NavItemSchema, STAT_CARD_COLOR_MAP, SearchBarResourceSchema, SidebarResourceSchema, StatCardColorSchema, StatCardResourceSchema, TableEngineComponent, TableResourceSchema, UserSchema, ValidatorRegistry };
831
2865
  //# sourceMappingURL=cerca-design-system.mjs.map