@avora-labs/meta-forge 1.0.5 → 1.1.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.
- package/README.md +0 -0
- package/fesm2022/{avora-labs-meta-forge-amf-auth-shell.component-BWSdjBUS.mjs → avora-labs-meta-forge-amf-auth-shell.component-C89gSPc9.mjs} +59 -59
- package/fesm2022/avora-labs-meta-forge-amf-auth-shell.component-C89gSPc9.mjs.map +1 -0
- package/fesm2022/{avora-labs-meta-forge-contact-support.page-BAUiKm3P.mjs → avora-labs-meta-forge-contact-support.page-C_kdmzhL.mjs} +148 -148
- package/fesm2022/avora-labs-meta-forge-contact-support.page-C_kdmzhL.mjs.map +1 -0
- package/fesm2022/{avora-labs-meta-forge-forgot-password.page-0XLiBrV1.mjs → avora-labs-meta-forge-forgot-password.page-PY9_K4M-.mjs} +240 -240
- package/fesm2022/avora-labs-meta-forge-forgot-password.page-PY9_K4M-.mjs.map +1 -0
- package/fesm2022/{avora-labs-meta-forge-login.page-etTr5NqJ.mjs → avora-labs-meta-forge-login.page-BW-RWCQM.mjs} +76 -76
- package/fesm2022/avora-labs-meta-forge-login.page-BW-RWCQM.mjs.map +1 -0
- package/fesm2022/avora-labs-meta-forge.mjs +2098 -2098
- package/fesm2022/avora-labs-meta-forge.mjs.map +1 -1
- package/package.json +13 -6
- package/styles/_palettes.scss +84 -84
- package/styles/_themes.scss +96 -96
- package/styles/_variables.scss +56 -56
- package/styles/styles.scss +295 -295
- package/fesm2022/avora-labs-meta-forge-amf-auth-shell.component-BWSdjBUS.mjs.map +0 -1
- package/fesm2022/avora-labs-meta-forge-contact-support.page-BAUiKm3P.mjs.map +0 -1
- package/fesm2022/avora-labs-meta-forge-forgot-password.page-0XLiBrV1.mjs.map +0 -1
- package/fesm2022/avora-labs-meta-forge-login.page-etTr5NqJ.mjs.map +0 -1
|
@@ -156,10 +156,10 @@ class NotificationService {
|
|
|
156
156
|
remove(id) {
|
|
157
157
|
this._notifications.update(n => n.filter(item => item.id !== id));
|
|
158
158
|
}
|
|
159
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
160
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
159
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: NotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
160
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: NotificationService, providedIn: 'root' });
|
|
161
161
|
}
|
|
162
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
162
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: NotificationService, decorators: [{
|
|
163
163
|
type: Injectable,
|
|
164
164
|
args: [{
|
|
165
165
|
providedIn: 'root'
|
|
@@ -336,10 +336,10 @@ class MetaStateService {
|
|
|
336
336
|
return undefined;
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
340
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
339
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
340
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaStateService, providedIn: 'root' });
|
|
341
341
|
}
|
|
342
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
342
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaStateService, decorators: [{
|
|
343
343
|
type: Injectable,
|
|
344
344
|
args: [{ providedIn: 'root' }]
|
|
345
345
|
}] });
|
|
@@ -759,10 +759,10 @@ class MetaApiService {
|
|
|
759
759
|
}
|
|
760
760
|
return formData;
|
|
761
761
|
}
|
|
762
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
763
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
762
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
763
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaApiService, providedIn: 'root' });
|
|
764
764
|
}
|
|
765
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
765
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaApiService, decorators: [{
|
|
766
766
|
type: Injectable,
|
|
767
767
|
args: [{ providedIn: 'root' }]
|
|
768
768
|
}] });
|
|
@@ -957,10 +957,10 @@ class ConditionEvaluatorService {
|
|
|
957
957
|
return obj;
|
|
958
958
|
return path.split('.').reduce((current, key) => current?.[key], obj);
|
|
959
959
|
}
|
|
960
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
961
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
960
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ConditionEvaluatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
961
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ConditionEvaluatorService, providedIn: 'root' });
|
|
962
962
|
}
|
|
963
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
963
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ConditionEvaluatorService, decorators: [{
|
|
964
964
|
type: Injectable,
|
|
965
965
|
args: [{ providedIn: 'root' }]
|
|
966
966
|
}] });
|
|
@@ -995,10 +995,10 @@ class AmfDialogService {
|
|
|
995
995
|
});
|
|
996
996
|
});
|
|
997
997
|
}
|
|
998
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
999
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
998
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AmfDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
999
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AmfDialogService, providedIn: 'root' });
|
|
1000
1000
|
}
|
|
1001
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1001
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AmfDialogService, decorators: [{
|
|
1002
1002
|
type: Injectable,
|
|
1003
1003
|
args: [{ providedIn: 'root' }]
|
|
1004
1004
|
}] });
|
|
@@ -1526,10 +1526,10 @@ class ActionDispatcherService {
|
|
|
1526
1526
|
if (el) {
|
|
1527
1527
|
const printWindow = window.open('', '_blank');
|
|
1528
1528
|
if (printWindow) {
|
|
1529
|
-
printWindow.document.write(`
|
|
1530
|
-
<html><head><title>${config.title || 'Print'}</title>
|
|
1531
|
-
<style>body { font-family: system-ui, sans-serif; padding: 20px; }</style>
|
|
1532
|
-
</head><body>${el.innerHTML}</body></html>
|
|
1529
|
+
printWindow.document.write(`
|
|
1530
|
+
<html><head><title>${config.title || 'Print'}</title>
|
|
1531
|
+
<style>body { font-family: system-ui, sans-serif; padding: 20px; }</style>
|
|
1532
|
+
</head><body>${el.innerHTML}</body></html>
|
|
1533
1533
|
`);
|
|
1534
1534
|
printWindow.document.close();
|
|
1535
1535
|
printWindow.print();
|
|
@@ -1624,10 +1624,10 @@ class ActionDispatcherService {
|
|
|
1624
1624
|
return undefined;
|
|
1625
1625
|
return path.split('.').reduce((obj, key) => obj?.[key], context);
|
|
1626
1626
|
}
|
|
1627
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1628
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
1627
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ActionDispatcherService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1628
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ActionDispatcherService, providedIn: 'root' });
|
|
1629
1629
|
}
|
|
1630
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1630
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ActionDispatcherService, decorators: [{
|
|
1631
1631
|
type: Injectable,
|
|
1632
1632
|
args: [{ providedIn: 'root' }]
|
|
1633
1633
|
}] });
|
|
@@ -1645,10 +1645,10 @@ class ComponentRegistryService {
|
|
|
1645
1645
|
has(key) { return this.registry.has(key); }
|
|
1646
1646
|
keys() { return Array.from(this.registry.keys()); }
|
|
1647
1647
|
unregister(key) { return this.registry.delete(key); }
|
|
1648
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1649
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
1648
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ComponentRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1649
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ComponentRegistryService, providedIn: 'root' });
|
|
1650
1650
|
}
|
|
1651
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1651
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ComponentRegistryService, decorators: [{
|
|
1652
1652
|
type: Injectable,
|
|
1653
1653
|
args: [{ providedIn: 'root' }]
|
|
1654
1654
|
}] });
|
|
@@ -1696,10 +1696,10 @@ class MetaRendererComponent {
|
|
|
1696
1696
|
if (this.section.gridRow)
|
|
1697
1697
|
hostEl.style.gridRow = this.section.gridRow;
|
|
1698
1698
|
}
|
|
1699
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1700
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
1699
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1700
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.15", type: MetaRendererComponent, isStandalone: true, selector: "amf-renderer", inputs: { section: "section", context: "context" }, viewQueries: [{ propertyName: "outlet", first: true, predicate: ["outlet"], descendants: true, read: ViewContainerRef, static: true }], usesOnChanges: true, ngImport: i0, template: `<ng-container #outlet></ng-container>`, isInline: true, styles: [":host{display:block}\n"] });
|
|
1701
1701
|
}
|
|
1702
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1702
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaRendererComponent, decorators: [{
|
|
1703
1703
|
type: Component,
|
|
1704
1704
|
args: [{ selector: 'amf-renderer', standalone: true, template: `<ng-container #outlet></ng-container>`, styles: [":host{display:block}\n"] }]
|
|
1705
1705
|
}], propDecorators: { section: [{
|
|
@@ -1830,33 +1830,33 @@ class MetaPageComponent {
|
|
|
1830
1830
|
}
|
|
1831
1831
|
return true;
|
|
1832
1832
|
}
|
|
1833
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
1834
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
1835
|
-
@if (pageMeta()) {
|
|
1836
|
-
<div class="amf-page-wrapper" [class]="pageMeta()!.cssClass || ''"
|
|
1837
|
-
[class.amf-animate-fade]="pageMeta()!.animation === 'fade'"
|
|
1838
|
-
[class.amf-animate-slide-up]="pageMeta()!.animation === 'slide-up'"
|
|
1839
|
-
[class.amf-animate-zoom]="pageMeta()!.animation === 'zoom'">
|
|
1840
|
-
@for (section of pageMeta()!.sections; track $index) {
|
|
1841
|
-
<amf-renderer [section]="section" [context]="context()" class="amf-section"></amf-renderer>
|
|
1842
|
-
}
|
|
1843
|
-
</div>
|
|
1844
|
-
}
|
|
1833
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1834
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: MetaPageComponent, isStandalone: true, selector: "amf-page", ngImport: i0, template: `
|
|
1835
|
+
@if (pageMeta()) {
|
|
1836
|
+
<div class="amf-page-wrapper" [class]="pageMeta()!.cssClass || ''"
|
|
1837
|
+
[class.amf-animate-fade]="pageMeta()!.animation === 'fade'"
|
|
1838
|
+
[class.amf-animate-slide-up]="pageMeta()!.animation === 'slide-up'"
|
|
1839
|
+
[class.amf-animate-zoom]="pageMeta()!.animation === 'zoom'">
|
|
1840
|
+
@for (section of pageMeta()!.sections; track $index) {
|
|
1841
|
+
<amf-renderer [section]="section" [context]="context()" class="amf-section"></amf-renderer>
|
|
1842
|
+
}
|
|
1843
|
+
</div>
|
|
1844
|
+
}
|
|
1845
1845
|
`, isInline: true, styles: [".amf-page-wrapper{display:flex;flex-direction:column;gap:24px;width:100%}.amf-section{display:block;width:100%}.amf-animate-fade{animation:amfFadeIn .3s ease-out}.amf-animate-slide-up{animation:amfSlideUp .3s ease-out}.amf-animate-zoom{animation:amfZoom .3s ease-out}@keyframes amfFadeIn{0%{opacity:0}to{opacity:1}}@keyframes amfSlideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes amfZoom{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}\n"], dependencies: [{ kind: "component", type: MetaRendererComponent, selector: "amf-renderer", inputs: ["section", "context"] }] });
|
|
1846
1846
|
}
|
|
1847
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
1847
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaPageComponent, decorators: [{
|
|
1848
1848
|
type: Component,
|
|
1849
|
-
args: [{ selector: 'amf-page', standalone: true, imports: [MetaRendererComponent], template: `
|
|
1850
|
-
@if (pageMeta()) {
|
|
1851
|
-
<div class="amf-page-wrapper" [class]="pageMeta()!.cssClass || ''"
|
|
1852
|
-
[class.amf-animate-fade]="pageMeta()!.animation === 'fade'"
|
|
1853
|
-
[class.amf-animate-slide-up]="pageMeta()!.animation === 'slide-up'"
|
|
1854
|
-
[class.amf-animate-zoom]="pageMeta()!.animation === 'zoom'">
|
|
1855
|
-
@for (section of pageMeta()!.sections; track $index) {
|
|
1856
|
-
<amf-renderer [section]="section" [context]="context()" class="amf-section"></amf-renderer>
|
|
1857
|
-
}
|
|
1858
|
-
</div>
|
|
1859
|
-
}
|
|
1849
|
+
args: [{ selector: 'amf-page', standalone: true, imports: [MetaRendererComponent], template: `
|
|
1850
|
+
@if (pageMeta()) {
|
|
1851
|
+
<div class="amf-page-wrapper" [class]="pageMeta()!.cssClass || ''"
|
|
1852
|
+
[class.amf-animate-fade]="pageMeta()!.animation === 'fade'"
|
|
1853
|
+
[class.amf-animate-slide-up]="pageMeta()!.animation === 'slide-up'"
|
|
1854
|
+
[class.amf-animate-zoom]="pageMeta()!.animation === 'zoom'">
|
|
1855
|
+
@for (section of pageMeta()!.sections; track $index) {
|
|
1856
|
+
<amf-renderer [section]="section" [context]="context()" class="amf-section"></amf-renderer>
|
|
1857
|
+
}
|
|
1858
|
+
</div>
|
|
1859
|
+
}
|
|
1860
1860
|
`, styles: [".amf-page-wrapper{display:flex;flex-direction:column;gap:24px;width:100%}.amf-section{display:block;width:100%}.amf-animate-fade{animation:amfFadeIn .3s ease-out}.amf-animate-slide-up{animation:amfSlideUp .3s ease-out}.amf-animate-zoom{animation:amfZoom .3s ease-out}@keyframes amfFadeIn{0%{opacity:0}to{opacity:1}}@keyframes amfSlideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes amfZoom{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}\n"] }]
|
|
1861
1861
|
}], ctorParameters: () => [] });
|
|
1862
1862
|
|
|
@@ -2010,10 +2010,10 @@ class AuthService {
|
|
|
2010
2010
|
return true;
|
|
2011
2011
|
}
|
|
2012
2012
|
}
|
|
2013
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2014
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
2013
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AuthService, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2014
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AuthService, providedIn: 'root' });
|
|
2015
2015
|
}
|
|
2016
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2016
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AuthService, decorators: [{
|
|
2017
2017
|
type: Injectable,
|
|
2018
2018
|
args: [{ providedIn: 'root' }]
|
|
2019
2019
|
}], ctorParameters: () => [{ type: i1.Router }] });
|
|
@@ -2030,10 +2030,10 @@ class PluginRegistryService {
|
|
|
2030
2030
|
}
|
|
2031
2031
|
getAll() { return Array.from(this.plugins.values()); }
|
|
2032
2032
|
get(name) { return this.plugins.get(name); }
|
|
2033
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2034
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
2033
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: PluginRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2034
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: PluginRegistryService, providedIn: 'root' });
|
|
2035
2035
|
}
|
|
2036
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2036
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: PluginRegistryService, decorators: [{
|
|
2037
2037
|
type: Injectable,
|
|
2038
2038
|
args: [{ providedIn: 'root' }]
|
|
2039
2039
|
}] });
|
|
@@ -2250,10 +2250,10 @@ class MetaRouterService {
|
|
|
2250
2250
|
return route;
|
|
2251
2251
|
});
|
|
2252
2252
|
}
|
|
2253
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2254
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
2253
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaRouterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2254
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaRouterService, providedIn: 'root' });
|
|
2255
2255
|
}
|
|
2256
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2256
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaRouterService, decorators: [{
|
|
2257
2257
|
type: Injectable,
|
|
2258
2258
|
args: [{ providedIn: 'root' }]
|
|
2259
2259
|
}] });
|
|
@@ -2277,21 +2277,21 @@ function getAmfAuthRoutes(meta) {
|
|
|
2277
2277
|
if (pages.includes('login')) {
|
|
2278
2278
|
routes.push({
|
|
2279
2279
|
path: 'login',
|
|
2280
|
-
loadComponent: () => import('./avora-labs-meta-forge-login.page-
|
|
2280
|
+
loadComponent: () => import('./avora-labs-meta-forge-login.page-BW-RWCQM.mjs').then(m => m.LoginComponent),
|
|
2281
2281
|
data: { layout: 'empty' },
|
|
2282
2282
|
});
|
|
2283
2283
|
}
|
|
2284
2284
|
if (pages.includes('forgot-password')) {
|
|
2285
2285
|
routes.push({
|
|
2286
2286
|
path: 'forgot-password',
|
|
2287
|
-
loadComponent: () => import('./avora-labs-meta-forge-forgot-password.page-
|
|
2287
|
+
loadComponent: () => import('./avora-labs-meta-forge-forgot-password.page-PY9_K4M-.mjs').then(m => m.ForgotPasswordComponent),
|
|
2288
2288
|
data: { layout: 'empty' },
|
|
2289
2289
|
});
|
|
2290
2290
|
}
|
|
2291
2291
|
if (pages.includes('contact-support')) {
|
|
2292
2292
|
routes.push({
|
|
2293
2293
|
path: 'contact-support',
|
|
2294
|
-
loadComponent: () => import('./avora-labs-meta-forge-contact-support.page-
|
|
2294
|
+
loadComponent: () => import('./avora-labs-meta-forge-contact-support.page-C_kdmzhL.mjs').then(m => m.ContactSupportComponent),
|
|
2295
2295
|
data: { layout: 'empty' },
|
|
2296
2296
|
});
|
|
2297
2297
|
}
|
|
@@ -2346,101 +2346,101 @@ class AccordionSectionComponent {
|
|
|
2346
2346
|
}
|
|
2347
2347
|
this.openPanels.set(current);
|
|
2348
2348
|
}
|
|
2349
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2350
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
2351
|
-
<div class="amf-accordion"
|
|
2352
|
-
[class]="'variant-' + (config.variant || 'default')"
|
|
2353
|
-
[class.accordion-bordered]="config.variant === 'bordered'">
|
|
2354
|
-
@for (panel of visiblePanels(); track $index) {
|
|
2355
|
-
<div class="accordion-panel"
|
|
2356
|
-
[class.open]="isOpen($index)"
|
|
2357
|
-
[class.disabled]="panel.disabled">
|
|
2358
|
-
|
|
2359
|
-
<!-- Panel Header -->
|
|
2360
|
-
<button
|
|
2361
|
-
type="button"
|
|
2362
|
-
class="accordion-header"
|
|
2363
|
-
[attr.aria-expanded]="isOpen($index)"
|
|
2364
|
-
[disabled]="panel.disabled"
|
|
2365
|
-
(click)="togglePanel($index)">
|
|
2366
|
-
|
|
2367
|
-
<div class="accordion-header-left">
|
|
2368
|
-
@if (panel.icon) {
|
|
2369
|
-
<svg class="panel-icon" viewBox="0 0 24 24">
|
|
2370
|
-
<path [attr.d]="panel.icon"/>
|
|
2371
|
-
</svg>
|
|
2372
|
-
}
|
|
2373
|
-
<span class="panel-title">{{ panel.title }}</span>
|
|
2374
|
-
</div>
|
|
2375
|
-
|
|
2376
|
-
<div class="accordion-header-right">
|
|
2377
|
-
<svg class="chevron-icon" viewBox="0 0 24 24">
|
|
2378
|
-
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z"/>
|
|
2379
|
-
</svg>
|
|
2380
|
-
</div>
|
|
2381
|
-
</button>
|
|
2382
|
-
|
|
2383
|
-
<!-- Panel Content -->
|
|
2384
|
-
<div class="accordion-body" [class.open]="isOpen($index)">
|
|
2385
|
-
<div class="accordion-body-inner">
|
|
2386
|
-
@for (section of panel.sections; track $index) {
|
|
2387
|
-
<amf-renderer [section]="section" [context]="context" class="amf-section">
|
|
2388
|
-
</amf-renderer>
|
|
2389
|
-
}
|
|
2390
|
-
</div>
|
|
2391
|
-
</div>
|
|
2392
|
-
</div>
|
|
2393
|
-
}
|
|
2394
|
-
</div>
|
|
2349
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AccordionSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2350
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: AccordionSectionComponent, isStandalone: true, selector: "amf-accordion-section", inputs: { config: "config", context: "context" }, usesOnChanges: true, ngImport: i0, template: `
|
|
2351
|
+
<div class="amf-accordion"
|
|
2352
|
+
[class]="'variant-' + (config.variant || 'default')"
|
|
2353
|
+
[class.accordion-bordered]="config.variant === 'bordered'">
|
|
2354
|
+
@for (panel of visiblePanels(); track $index) {
|
|
2355
|
+
<div class="accordion-panel"
|
|
2356
|
+
[class.open]="isOpen($index)"
|
|
2357
|
+
[class.disabled]="panel.disabled">
|
|
2358
|
+
|
|
2359
|
+
<!-- Panel Header -->
|
|
2360
|
+
<button
|
|
2361
|
+
type="button"
|
|
2362
|
+
class="accordion-header"
|
|
2363
|
+
[attr.aria-expanded]="isOpen($index)"
|
|
2364
|
+
[disabled]="panel.disabled"
|
|
2365
|
+
(click)="togglePanel($index)">
|
|
2366
|
+
|
|
2367
|
+
<div class="accordion-header-left">
|
|
2368
|
+
@if (panel.icon) {
|
|
2369
|
+
<svg class="panel-icon" viewBox="0 0 24 24">
|
|
2370
|
+
<path [attr.d]="panel.icon"/>
|
|
2371
|
+
</svg>
|
|
2372
|
+
}
|
|
2373
|
+
<span class="panel-title">{{ panel.title }}</span>
|
|
2374
|
+
</div>
|
|
2375
|
+
|
|
2376
|
+
<div class="accordion-header-right">
|
|
2377
|
+
<svg class="chevron-icon" viewBox="0 0 24 24">
|
|
2378
|
+
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z"/>
|
|
2379
|
+
</svg>
|
|
2380
|
+
</div>
|
|
2381
|
+
</button>
|
|
2382
|
+
|
|
2383
|
+
<!-- Panel Content -->
|
|
2384
|
+
<div class="accordion-body" [class.open]="isOpen($index)">
|
|
2385
|
+
<div class="accordion-body-inner">
|
|
2386
|
+
@for (section of panel.sections; track $index) {
|
|
2387
|
+
<amf-renderer [section]="section" [context]="context" class="amf-section">
|
|
2388
|
+
</amf-renderer>
|
|
2389
|
+
}
|
|
2390
|
+
</div>
|
|
2391
|
+
</div>
|
|
2392
|
+
</div>
|
|
2393
|
+
}
|
|
2394
|
+
</div>
|
|
2395
2395
|
`, isInline: true, styles: [".amf-accordion{display:flex;flex-direction:column;border-radius:16px;overflow:hidden;border:1px solid var(--app-border);background:var(--app-surface)}.amf-accordion.variant-flush{border:none;border-radius:0;gap:0}.amf-accordion.variant-bordered{gap:8px;border:none;background:transparent;overflow:visible}.accordion-panel{overflow:hidden;transition:box-shadow .2s}.variant-default .accordion-panel+.accordion-panel{border-top:1px solid var(--app-border)}.variant-bordered .accordion-panel{border:1px solid var(--app-border);border-radius:12px;overflow:hidden;background:var(--app-surface);transition:box-shadow .25s}.variant-bordered .accordion-panel.open{box-shadow:0 4px 20px #0000001f;border-color:var(--app-primary)}.accordion-panel.disabled{opacity:.5;pointer-events:none}.accordion-header{display:flex;align-items:center;justify-content:space-between;width:100%;padding:16px 20px;background:transparent;border:none;cursor:pointer;text-align:left;transition:background .2s;gap:12px}.accordion-header:hover{background:var(--glass-bg)}.accordion-header:disabled{cursor:not-allowed}.accordion-panel.open .accordion-header{background:var(--glass-bg)}.accordion-header-left{display:flex;align-items:center;gap:10px;flex:1;min-width:0}.panel-icon{width:18px;height:18px;fill:var(--app-primary);flex-shrink:0}.panel-title{font-size:.9375rem;font-weight:600;color:var(--app-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.accordion-header-right{flex-shrink:0}.chevron-icon{width:20px;height:20px;fill:var(--app-text-muted);transition:transform .3s cubic-bezier(.4,0,.2,1)}.accordion-panel.open .chevron-icon{transform:rotate(180deg);fill:var(--app-primary)}.accordion-body{max-height:0;overflow:hidden;transition:max-height .45s cubic-bezier(.4,0,.2,1)}.accordion-body.open{max-height:4000px}.accordion-body-inner{display:flex;flex-direction:column;gap:16px;padding:16px 20px 20px;border-top:1px solid var(--app-border);animation:accordionFadeIn .3s ease-out}@keyframes accordionFadeIn{0%{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}:host{display:block}.amf-section{display:block}\n"], dependencies: [{ kind: "component", type: MetaRendererComponent, selector: "amf-renderer", inputs: ["section", "context"] }] });
|
|
2396
2396
|
}
|
|
2397
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2397
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AccordionSectionComponent, decorators: [{
|
|
2398
2398
|
type: Component,
|
|
2399
|
-
args: [{ selector: 'amf-accordion-section', standalone: true, imports: [MetaRendererComponent], template: `
|
|
2400
|
-
<div class="amf-accordion"
|
|
2401
|
-
[class]="'variant-' + (config.variant || 'default')"
|
|
2402
|
-
[class.accordion-bordered]="config.variant === 'bordered'">
|
|
2403
|
-
@for (panel of visiblePanels(); track $index) {
|
|
2404
|
-
<div class="accordion-panel"
|
|
2405
|
-
[class.open]="isOpen($index)"
|
|
2406
|
-
[class.disabled]="panel.disabled">
|
|
2407
|
-
|
|
2408
|
-
<!-- Panel Header -->
|
|
2409
|
-
<button
|
|
2410
|
-
type="button"
|
|
2411
|
-
class="accordion-header"
|
|
2412
|
-
[attr.aria-expanded]="isOpen($index)"
|
|
2413
|
-
[disabled]="panel.disabled"
|
|
2414
|
-
(click)="togglePanel($index)">
|
|
2415
|
-
|
|
2416
|
-
<div class="accordion-header-left">
|
|
2417
|
-
@if (panel.icon) {
|
|
2418
|
-
<svg class="panel-icon" viewBox="0 0 24 24">
|
|
2419
|
-
<path [attr.d]="panel.icon"/>
|
|
2420
|
-
</svg>
|
|
2421
|
-
}
|
|
2422
|
-
<span class="panel-title">{{ panel.title }}</span>
|
|
2423
|
-
</div>
|
|
2424
|
-
|
|
2425
|
-
<div class="accordion-header-right">
|
|
2426
|
-
<svg class="chevron-icon" viewBox="0 0 24 24">
|
|
2427
|
-
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z"/>
|
|
2428
|
-
</svg>
|
|
2429
|
-
</div>
|
|
2430
|
-
</button>
|
|
2431
|
-
|
|
2432
|
-
<!-- Panel Content -->
|
|
2433
|
-
<div class="accordion-body" [class.open]="isOpen($index)">
|
|
2434
|
-
<div class="accordion-body-inner">
|
|
2435
|
-
@for (section of panel.sections; track $index) {
|
|
2436
|
-
<amf-renderer [section]="section" [context]="context" class="amf-section">
|
|
2437
|
-
</amf-renderer>
|
|
2438
|
-
}
|
|
2439
|
-
</div>
|
|
2440
|
-
</div>
|
|
2441
|
-
</div>
|
|
2442
|
-
}
|
|
2443
|
-
</div>
|
|
2399
|
+
args: [{ selector: 'amf-accordion-section', standalone: true, imports: [MetaRendererComponent], template: `
|
|
2400
|
+
<div class="amf-accordion"
|
|
2401
|
+
[class]="'variant-' + (config.variant || 'default')"
|
|
2402
|
+
[class.accordion-bordered]="config.variant === 'bordered'">
|
|
2403
|
+
@for (panel of visiblePanels(); track $index) {
|
|
2404
|
+
<div class="accordion-panel"
|
|
2405
|
+
[class.open]="isOpen($index)"
|
|
2406
|
+
[class.disabled]="panel.disabled">
|
|
2407
|
+
|
|
2408
|
+
<!-- Panel Header -->
|
|
2409
|
+
<button
|
|
2410
|
+
type="button"
|
|
2411
|
+
class="accordion-header"
|
|
2412
|
+
[attr.aria-expanded]="isOpen($index)"
|
|
2413
|
+
[disabled]="panel.disabled"
|
|
2414
|
+
(click)="togglePanel($index)">
|
|
2415
|
+
|
|
2416
|
+
<div class="accordion-header-left">
|
|
2417
|
+
@if (panel.icon) {
|
|
2418
|
+
<svg class="panel-icon" viewBox="0 0 24 24">
|
|
2419
|
+
<path [attr.d]="panel.icon"/>
|
|
2420
|
+
</svg>
|
|
2421
|
+
}
|
|
2422
|
+
<span class="panel-title">{{ panel.title }}</span>
|
|
2423
|
+
</div>
|
|
2424
|
+
|
|
2425
|
+
<div class="accordion-header-right">
|
|
2426
|
+
<svg class="chevron-icon" viewBox="0 0 24 24">
|
|
2427
|
+
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z"/>
|
|
2428
|
+
</svg>
|
|
2429
|
+
</div>
|
|
2430
|
+
</button>
|
|
2431
|
+
|
|
2432
|
+
<!-- Panel Content -->
|
|
2433
|
+
<div class="accordion-body" [class.open]="isOpen($index)">
|
|
2434
|
+
<div class="accordion-body-inner">
|
|
2435
|
+
@for (section of panel.sections; track $index) {
|
|
2436
|
+
<amf-renderer [section]="section" [context]="context" class="amf-section">
|
|
2437
|
+
</amf-renderer>
|
|
2438
|
+
}
|
|
2439
|
+
</div>
|
|
2440
|
+
</div>
|
|
2441
|
+
</div>
|
|
2442
|
+
}
|
|
2443
|
+
</div>
|
|
2444
2444
|
`, styles: [".amf-accordion{display:flex;flex-direction:column;border-radius:16px;overflow:hidden;border:1px solid var(--app-border);background:var(--app-surface)}.amf-accordion.variant-flush{border:none;border-radius:0;gap:0}.amf-accordion.variant-bordered{gap:8px;border:none;background:transparent;overflow:visible}.accordion-panel{overflow:hidden;transition:box-shadow .2s}.variant-default .accordion-panel+.accordion-panel{border-top:1px solid var(--app-border)}.variant-bordered .accordion-panel{border:1px solid var(--app-border);border-radius:12px;overflow:hidden;background:var(--app-surface);transition:box-shadow .25s}.variant-bordered .accordion-panel.open{box-shadow:0 4px 20px #0000001f;border-color:var(--app-primary)}.accordion-panel.disabled{opacity:.5;pointer-events:none}.accordion-header{display:flex;align-items:center;justify-content:space-between;width:100%;padding:16px 20px;background:transparent;border:none;cursor:pointer;text-align:left;transition:background .2s;gap:12px}.accordion-header:hover{background:var(--glass-bg)}.accordion-header:disabled{cursor:not-allowed}.accordion-panel.open .accordion-header{background:var(--glass-bg)}.accordion-header-left{display:flex;align-items:center;gap:10px;flex:1;min-width:0}.panel-icon{width:18px;height:18px;fill:var(--app-primary);flex-shrink:0}.panel-title{font-size:.9375rem;font-weight:600;color:var(--app-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.accordion-header-right{flex-shrink:0}.chevron-icon{width:20px;height:20px;fill:var(--app-text-muted);transition:transform .3s cubic-bezier(.4,0,.2,1)}.accordion-panel.open .chevron-icon{transform:rotate(180deg);fill:var(--app-primary)}.accordion-body{max-height:0;overflow:hidden;transition:max-height .45s cubic-bezier(.4,0,.2,1)}.accordion-body.open{max-height:4000px}.accordion-body-inner{display:flex;flex-direction:column;gap:16px;padding:16px 20px 20px;border-top:1px solid var(--app-border);animation:accordionFadeIn .3s ease-out}@keyframes accordionFadeIn{0%{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:translateY(0)}}:host{display:block}.amf-section{display:block}\n"] }]
|
|
2445
2445
|
}], propDecorators: { config: [{
|
|
2446
2446
|
type: Input
|
|
@@ -2479,61 +2479,61 @@ class MetaModalHostComponent {
|
|
|
2479
2479
|
dispatchAction(actionMeta) {
|
|
2480
2480
|
this.dispatcher.dispatch(actionMeta, {});
|
|
2481
2481
|
}
|
|
2482
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2483
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
2484
|
-
@if (isOpen()) {
|
|
2485
|
-
<div class="amf-modal-backdrop" (click)="closeOnBackdrop($event)">
|
|
2486
|
-
<div class="amf-modal-dialog" [ngClass]="['size-' + (config()?.size || 'md')]" (click)="$event.stopPropagation()">
|
|
2487
|
-
<div class="amf-modal-header">
|
|
2488
|
-
<h3>{{ config()?.title }}</h3>
|
|
2489
|
-
<button class="amf-modal-close" (click)="close()">×</button>
|
|
2490
|
-
</div>
|
|
2491
|
-
<div class="amf-modal-content">
|
|
2492
|
-
@if (config()?.content) {
|
|
2493
|
-
<amf-renderer [section]="config()!.content" [context]="{}"></amf-renderer>
|
|
2494
|
-
}
|
|
2495
|
-
</div>
|
|
2496
|
-
@if (config()?.actions?.length) {
|
|
2497
|
-
<div class="amf-modal-footer">
|
|
2498
|
-
@for (action of config()!.actions; track action.label) {
|
|
2499
|
-
<button [class]="'btn-' + (action.color || 'primary')" (click)="dispatchAction(action.action)">
|
|
2500
|
-
{{ action.label }}
|
|
2501
|
-
</button>
|
|
2502
|
-
}
|
|
2503
|
-
</div>
|
|
2504
|
-
}
|
|
2505
|
-
</div>
|
|
2506
|
-
</div>
|
|
2507
|
-
}
|
|
2482
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaModalHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2483
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: MetaModalHostComponent, isStandalone: true, selector: "amf-modal-host", ngImport: i0, template: `
|
|
2484
|
+
@if (isOpen()) {
|
|
2485
|
+
<div class="amf-modal-backdrop" (click)="closeOnBackdrop($event)">
|
|
2486
|
+
<div class="amf-modal-dialog" [ngClass]="['size-' + (config()?.size || 'md')]" (click)="$event.stopPropagation()">
|
|
2487
|
+
<div class="amf-modal-header">
|
|
2488
|
+
<h3>{{ config()?.title }}</h3>
|
|
2489
|
+
<button class="amf-modal-close" (click)="close()">×</button>
|
|
2490
|
+
</div>
|
|
2491
|
+
<div class="amf-modal-content">
|
|
2492
|
+
@if (config()?.content) {
|
|
2493
|
+
<amf-renderer [section]="config()!.content" [context]="{}"></amf-renderer>
|
|
2494
|
+
}
|
|
2495
|
+
</div>
|
|
2496
|
+
@if (config()?.actions?.length) {
|
|
2497
|
+
<div class="amf-modal-footer">
|
|
2498
|
+
@for (action of config()!.actions; track action.label) {
|
|
2499
|
+
<button [class]="'btn-' + (action.color || 'primary')" (click)="dispatchAction(action.action)">
|
|
2500
|
+
{{ action.label }}
|
|
2501
|
+
</button>
|
|
2502
|
+
}
|
|
2503
|
+
</div>
|
|
2504
|
+
}
|
|
2505
|
+
</div>
|
|
2506
|
+
</div>
|
|
2507
|
+
}
|
|
2508
2508
|
`, isInline: true, styles: [".amf-modal-backdrop{position:fixed;inset:0;background:#0009;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:9999;display:flex;align-items:center;justify-content:center;padding:20px;animation:fadeIn .2s ease-out}.amf-modal-dialog{background:var(--glass-bg, rgba(20,25,40,.9));border:1px solid var(--app-border, rgba(255,255,255,.1));border-radius:16px;box-shadow:0 25px 50px -12px #00000080;width:100%;max-height:90vh;overflow-y:auto;display:flex;flex-direction:column;animation:slideUp .3s cubic-bezier(.16,1,.3,1)}.size-sm{max-width:400px}.size-md{max-width:600px}.size-lg{max-width:800px}.size-full{max-width:95vw;height:95vh}.amf-modal-header{padding:20px 24px;border-bottom:1px solid var(--app-border, rgba(255,255,255,.1));display:flex;justify-content:space-between;align-items:center}.amf-modal-header h3{font-size:1.25rem;margin:0;color:#fff}.amf-modal-close{background:transparent;border:none;color:#94a3b8;font-size:1.5rem;cursor:pointer;line-height:1;padding:0 4px}.amf-modal-close:hover{color:#fff}.amf-modal-content{padding:24px;flex-grow:1;color:#94a3b8}.amf-modal-footer{padding:16px 24px;border-top:1px solid var(--app-border, rgba(255,255,255,.1));display:flex;justify-content:flex-end;gap:12px}.btn-primary{background:linear-gradient(135deg,var(--app-primary, #6366f1),var(--app-accent, #c084fc));color:#fff;padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:600}.btn-outline{background:transparent;border:1px solid #475569;color:#e2e8f0;padding:10px 20px;border-radius:8px;cursor:pointer;font-weight:600}.btn-danger{background:#ef4444;color:#fff;padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:600}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(20px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MetaRendererComponent, selector: "amf-renderer", inputs: ["section", "context"] }] });
|
|
2509
2509
|
}
|
|
2510
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2510
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaModalHostComponent, decorators: [{
|
|
2511
2511
|
type: Component,
|
|
2512
|
-
args: [{ selector: 'amf-modal-host', standalone: true, imports: [CommonModule, MetaRendererComponent], template: `
|
|
2513
|
-
@if (isOpen()) {
|
|
2514
|
-
<div class="amf-modal-backdrop" (click)="closeOnBackdrop($event)">
|
|
2515
|
-
<div class="amf-modal-dialog" [ngClass]="['size-' + (config()?.size || 'md')]" (click)="$event.stopPropagation()">
|
|
2516
|
-
<div class="amf-modal-header">
|
|
2517
|
-
<h3>{{ config()?.title }}</h3>
|
|
2518
|
-
<button class="amf-modal-close" (click)="close()">×</button>
|
|
2519
|
-
</div>
|
|
2520
|
-
<div class="amf-modal-content">
|
|
2521
|
-
@if (config()?.content) {
|
|
2522
|
-
<amf-renderer [section]="config()!.content" [context]="{}"></amf-renderer>
|
|
2523
|
-
}
|
|
2524
|
-
</div>
|
|
2525
|
-
@if (config()?.actions?.length) {
|
|
2526
|
-
<div class="amf-modal-footer">
|
|
2527
|
-
@for (action of config()!.actions; track action.label) {
|
|
2528
|
-
<button [class]="'btn-' + (action.color || 'primary')" (click)="dispatchAction(action.action)">
|
|
2529
|
-
{{ action.label }}
|
|
2530
|
-
</button>
|
|
2531
|
-
}
|
|
2532
|
-
</div>
|
|
2533
|
-
}
|
|
2534
|
-
</div>
|
|
2535
|
-
</div>
|
|
2536
|
-
}
|
|
2512
|
+
args: [{ selector: 'amf-modal-host', standalone: true, imports: [CommonModule, MetaRendererComponent], template: `
|
|
2513
|
+
@if (isOpen()) {
|
|
2514
|
+
<div class="amf-modal-backdrop" (click)="closeOnBackdrop($event)">
|
|
2515
|
+
<div class="amf-modal-dialog" [ngClass]="['size-' + (config()?.size || 'md')]" (click)="$event.stopPropagation()">
|
|
2516
|
+
<div class="amf-modal-header">
|
|
2517
|
+
<h3>{{ config()?.title }}</h3>
|
|
2518
|
+
<button class="amf-modal-close" (click)="close()">×</button>
|
|
2519
|
+
</div>
|
|
2520
|
+
<div class="amf-modal-content">
|
|
2521
|
+
@if (config()?.content) {
|
|
2522
|
+
<amf-renderer [section]="config()!.content" [context]="{}"></amf-renderer>
|
|
2523
|
+
}
|
|
2524
|
+
</div>
|
|
2525
|
+
@if (config()?.actions?.length) {
|
|
2526
|
+
<div class="amf-modal-footer">
|
|
2527
|
+
@for (action of config()!.actions; track action.label) {
|
|
2528
|
+
<button [class]="'btn-' + (action.color || 'primary')" (click)="dispatchAction(action.action)">
|
|
2529
|
+
{{ action.label }}
|
|
2530
|
+
</button>
|
|
2531
|
+
}
|
|
2532
|
+
</div>
|
|
2533
|
+
}
|
|
2534
|
+
</div>
|
|
2535
|
+
</div>
|
|
2536
|
+
}
|
|
2537
2537
|
`, styles: [".amf-modal-backdrop{position:fixed;inset:0;background:#0009;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:9999;display:flex;align-items:center;justify-content:center;padding:20px;animation:fadeIn .2s ease-out}.amf-modal-dialog{background:var(--glass-bg, rgba(20,25,40,.9));border:1px solid var(--app-border, rgba(255,255,255,.1));border-radius:16px;box-shadow:0 25px 50px -12px #00000080;width:100%;max-height:90vh;overflow-y:auto;display:flex;flex-direction:column;animation:slideUp .3s cubic-bezier(.16,1,.3,1)}.size-sm{max-width:400px}.size-md{max-width:600px}.size-lg{max-width:800px}.size-full{max-width:95vw;height:95vh}.amf-modal-header{padding:20px 24px;border-bottom:1px solid var(--app-border, rgba(255,255,255,.1));display:flex;justify-content:space-between;align-items:center}.amf-modal-header h3{font-size:1.25rem;margin:0;color:#fff}.amf-modal-close{background:transparent;border:none;color:#94a3b8;font-size:1.5rem;cursor:pointer;line-height:1;padding:0 4px}.amf-modal-close:hover{color:#fff}.amf-modal-content{padding:24px;flex-grow:1;color:#94a3b8}.amf-modal-footer{padding:16px 24px;border-top:1px solid var(--app-border, rgba(255,255,255,.1));display:flex;justify-content:flex-end;gap:12px}.btn-primary{background:linear-gradient(135deg,var(--app-primary, #6366f1),var(--app-accent, #c084fc));color:#fff;padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:600}.btn-outline{background:transparent;border:1px solid #475569;color:#e2e8f0;padding:10px 20px;border-radius:8px;cursor:pointer;font-weight:600}.btn-danger{background:#ef4444;color:#fff;padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:600}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(20px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}\n"] }]
|
|
2538
2538
|
}] });
|
|
2539
2539
|
|
|
@@ -2594,10 +2594,10 @@ class IconRegistryService {
|
|
|
2594
2594
|
this.register('dollar-sign', 'M11.8 10.9c-2.27-.59-3-1.2-3-2.15 0-1.09 1.01-1.85 2.7-1.85 1.78 0 2.44.85 2.5 2.1h2.21c-.07-1.72-1.12-3.3-3.21-3.81V3h-3v2.16c-1.94.42-3.5 1.68-3.5 3.61 0 2.31 1.91 3.46 4.7 4.13 2.5.6 3 1.48 3 2.41 0 .69-.49 1.79-2.7 1.79-2.06 0-2.87-.92-2.98-2.1h-2.2c.12 2.19 1.76 3.42 3.68 3.83V21h3v-2.15c1.95-.37 3.5-1.5 3.5-3.55 0-2.84-2.43-3.81-4.7-4.4z');
|
|
2595
2595
|
this.register('activity', 'M22 12h-4l-3 9L9 3l-3 9H2');
|
|
2596
2596
|
}
|
|
2597
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2598
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
2597
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: IconRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2598
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: IconRegistryService, providedIn: 'root' });
|
|
2599
2599
|
}
|
|
2600
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2600
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: IconRegistryService, decorators: [{
|
|
2601
2601
|
type: Injectable,
|
|
2602
2602
|
args: [{ providedIn: 'root' }]
|
|
2603
2603
|
}], ctorParameters: () => [] });
|
|
@@ -2634,85 +2634,85 @@ class AmfDialogHostComponent {
|
|
|
2634
2634
|
this.currentDialog.set(null); // Clear the dialog visually
|
|
2635
2635
|
}
|
|
2636
2636
|
}
|
|
2637
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2638
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
2639
|
-
@if (currentDialog()) {
|
|
2640
|
-
<div class="amf-dialog-backdrop" (click)="onBackdropClick()">
|
|
2641
|
-
<div class="amf-dialog-box" (click)="$event.stopPropagation()">
|
|
2642
|
-
|
|
2643
|
-
<div class="dialog-header">
|
|
2644
|
-
<div class="dialog-icon-wrapper" [ngClass]="'variant-' + (currentDialog()?.config?.variant || 'info')">
|
|
2645
|
-
@if (currentDialog()?.config?.icon) {
|
|
2646
|
-
<svg viewBox="0 0 24 24" class="icon-element">
|
|
2647
|
-
<path [attr.d]="iconPath"></path>
|
|
2648
|
-
</svg>
|
|
2649
|
-
} @else {
|
|
2650
|
-
<span class="icon-fallback">!</span>
|
|
2651
|
-
}
|
|
2652
|
-
</div>
|
|
2653
|
-
@if (currentDialog()?.config?.title) {
|
|
2654
|
-
<h3 class="dialog-title">{{ currentDialog()!.config!.title }}</h3>
|
|
2655
|
-
}
|
|
2656
|
-
</div>
|
|
2657
|
-
|
|
2658
|
-
<div class="dialog-content">
|
|
2659
|
-
<p class="dialog-message">{{ currentDialog()!.config!.message }}</p>
|
|
2660
|
-
</div>
|
|
2661
|
-
|
|
2662
|
-
<div class="dialog-actions">
|
|
2663
|
-
@if (currentDialog()?.config?.showCancel) {
|
|
2664
|
-
<button class="btn btn-cancel" (click)="close(false)">
|
|
2665
|
-
{{ currentDialog()?.config?.cancelLabel || 'Cancel' }}
|
|
2666
|
-
</button>
|
|
2667
|
-
}
|
|
2668
|
-
<button class="btn btn-confirm" [ngClass]="'btn-variant-' + (currentDialog()?.config?.variant || 'info')" (click)="close(true)">
|
|
2669
|
-
{{ currentDialog()?.config?.confirmLabel || 'OK' }}
|
|
2670
|
-
</button>
|
|
2671
|
-
</div>
|
|
2672
|
-
</div>
|
|
2673
|
-
</div>
|
|
2674
|
-
}
|
|
2637
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AmfDialogHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2638
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: AmfDialogHostComponent, isStandalone: true, selector: "amf-dialog-host", ngImport: i0, template: `
|
|
2639
|
+
@if (currentDialog()) {
|
|
2640
|
+
<div class="amf-dialog-backdrop" (click)="onBackdropClick()">
|
|
2641
|
+
<div class="amf-dialog-box" (click)="$event.stopPropagation()">
|
|
2642
|
+
|
|
2643
|
+
<div class="dialog-header">
|
|
2644
|
+
<div class="dialog-icon-wrapper" [ngClass]="'variant-' + (currentDialog()?.config?.variant || 'info')">
|
|
2645
|
+
@if (currentDialog()?.config?.icon) {
|
|
2646
|
+
<svg viewBox="0 0 24 24" class="icon-element">
|
|
2647
|
+
<path [attr.d]="iconPath"></path>
|
|
2648
|
+
</svg>
|
|
2649
|
+
} @else {
|
|
2650
|
+
<span class="icon-fallback">!</span>
|
|
2651
|
+
}
|
|
2652
|
+
</div>
|
|
2653
|
+
@if (currentDialog()?.config?.title) {
|
|
2654
|
+
<h3 class="dialog-title">{{ currentDialog()!.config!.title }}</h3>
|
|
2655
|
+
}
|
|
2656
|
+
</div>
|
|
2657
|
+
|
|
2658
|
+
<div class="dialog-content">
|
|
2659
|
+
<p class="dialog-message">{{ currentDialog()!.config!.message }}</p>
|
|
2660
|
+
</div>
|
|
2661
|
+
|
|
2662
|
+
<div class="dialog-actions">
|
|
2663
|
+
@if (currentDialog()?.config?.showCancel) {
|
|
2664
|
+
<button class="btn btn-cancel" (click)="close(false)">
|
|
2665
|
+
{{ currentDialog()?.config?.cancelLabel || 'Cancel' }}
|
|
2666
|
+
</button>
|
|
2667
|
+
}
|
|
2668
|
+
<button class="btn btn-confirm" [ngClass]="'btn-variant-' + (currentDialog()?.config?.variant || 'info')" (click)="close(true)">
|
|
2669
|
+
{{ currentDialog()?.config?.confirmLabel || 'OK' }}
|
|
2670
|
+
</button>
|
|
2671
|
+
</div>
|
|
2672
|
+
</div>
|
|
2673
|
+
</div>
|
|
2674
|
+
}
|
|
2675
2675
|
`, isInline: true, styles: [".amf-dialog-backdrop{position:fixed;inset:0;background:#0a0f1ebf;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);z-index:10000;display:flex;align-items:center;justify-content:center;padding:20px;animation:fadeIn .25s ease-out}.amf-dialog-box{background:var(--glass-bg, rgba(20,25,40,.9));border:1px solid var(--app-border, rgba(255,255,255,.1));border-radius:20px;box-shadow:0 25px 50px -12px #0009,0 0 0 1px #ffffff0d inset;width:100%;max-width:420px;display:flex;flex-direction:column;animation:popIn .3s cubic-bezier(.16,1,.3,1);overflow:hidden}.dialog-header{padding:32px 32px 16px;display:flex;flex-direction:column;align-items:center;text-align:center;gap:16px}.dialog-icon-wrapper{width:64px;height:64px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:32px;color:#fff;box-shadow:0 8px 16px -4px #0000004d}.dialog-icon-wrapper.variant-info{background:linear-gradient(135deg,#3b82f6,#2563eb);box-shadow:0 8px 24px -6px #3b82f680}.dialog-icon-wrapper.variant-success{background:linear-gradient(135deg,#10b981,#059669);box-shadow:0 8px 24px -6px #10b98180}.dialog-icon-wrapper.variant-warning{background:linear-gradient(135deg,#f59e0b,#d97706);box-shadow:0 8px 24px -6px #f59e0b80}.dialog-icon-wrapper.variant-danger{background:linear-gradient(135deg,#ef4444,#dc2626);box-shadow:0 8px 24px -6px #ef444480}.icon-element{width:32px;height:32px;display:block;filter:drop-shadow(0 2px 2px rgba(0,0,0,.2))}.icon-fallback{font-family:monospace;font-weight:700}.dialog-title{margin:0;color:var(--app-text, #ffffff);font-size:1.25rem;font-weight:700;letter-spacing:-.02em}.dialog-content{padding:0 32px 32px;text-align:center}.dialog-message{margin:0;color:var(--app-text-muted, #94a3b8);font-size:.95rem;line-height:1.5}.dialog-actions{display:flex;gap:12px;padding:24px 32px;background:#0003;border-top:1px solid var(--app-border, rgba(255,255,255,.05))}.btn{flex:1;padding:12px 20px;border-radius:12px;font-size:.9rem;font-weight:600;cursor:pointer;transition:all .2s;border:none;display:inline-flex;align-items:center;justify-content:center}.btn-cancel{background:#ffffff0d;color:var(--app-text, #ffffff);border:1px solid rgba(255,255,255,.1)}.btn-cancel:hover{background:#ffffff1a}.btn-confirm{color:#fff;box-shadow:0 4px 12px transparent}.btn-confirm:hover{transform:translateY(-1px)}.btn-variant-info{background:#3b82f6;box-shadow:0 4px 12px #3b82f64d}.btn-variant-info:hover{background:#60a5fa;box-shadow:0 6px 16px #3b82f666}.btn-variant-success{background:#10b981;box-shadow:0 4px 12px #10b9814d}.btn-variant-success:hover{background:#34d399;box-shadow:0 6px 16px #10b98166}.btn-variant-warning{background:#f59e0b;box-shadow:0 4px 12px #f59e0b4d}.btn-variant-warning:hover{background:#fbbf24;box-shadow:0 6px 16px #f59e0b66}.btn-variant-danger{background:#ef4444;box-shadow:0 4px 12px #ef44444d}.btn-variant-danger:hover{background:#f87171;box-shadow:0 6px 16px #ef444466}@keyframes fadeIn{0%{opacity:0;-webkit-backdrop-filter:blur(0px);backdrop-filter:blur(0px)}to{opacity:1;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}}@keyframes popIn{0%{opacity:0;transform:scale(.9) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
2676
2676
|
}
|
|
2677
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2677
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AmfDialogHostComponent, decorators: [{
|
|
2678
2678
|
type: Component,
|
|
2679
|
-
args: [{ selector: 'amf-dialog-host', standalone: true, imports: [CommonModule], template: `
|
|
2680
|
-
@if (currentDialog()) {
|
|
2681
|
-
<div class="amf-dialog-backdrop" (click)="onBackdropClick()">
|
|
2682
|
-
<div class="amf-dialog-box" (click)="$event.stopPropagation()">
|
|
2683
|
-
|
|
2684
|
-
<div class="dialog-header">
|
|
2685
|
-
<div class="dialog-icon-wrapper" [ngClass]="'variant-' + (currentDialog()?.config?.variant || 'info')">
|
|
2686
|
-
@if (currentDialog()?.config?.icon) {
|
|
2687
|
-
<svg viewBox="0 0 24 24" class="icon-element">
|
|
2688
|
-
<path [attr.d]="iconPath"></path>
|
|
2689
|
-
</svg>
|
|
2690
|
-
} @else {
|
|
2691
|
-
<span class="icon-fallback">!</span>
|
|
2692
|
-
}
|
|
2693
|
-
</div>
|
|
2694
|
-
@if (currentDialog()?.config?.title) {
|
|
2695
|
-
<h3 class="dialog-title">{{ currentDialog()!.config!.title }}</h3>
|
|
2696
|
-
}
|
|
2697
|
-
</div>
|
|
2698
|
-
|
|
2699
|
-
<div class="dialog-content">
|
|
2700
|
-
<p class="dialog-message">{{ currentDialog()!.config!.message }}</p>
|
|
2701
|
-
</div>
|
|
2702
|
-
|
|
2703
|
-
<div class="dialog-actions">
|
|
2704
|
-
@if (currentDialog()?.config?.showCancel) {
|
|
2705
|
-
<button class="btn btn-cancel" (click)="close(false)">
|
|
2706
|
-
{{ currentDialog()?.config?.cancelLabel || 'Cancel' }}
|
|
2707
|
-
</button>
|
|
2708
|
-
}
|
|
2709
|
-
<button class="btn btn-confirm" [ngClass]="'btn-variant-' + (currentDialog()?.config?.variant || 'info')" (click)="close(true)">
|
|
2710
|
-
{{ currentDialog()?.config?.confirmLabel || 'OK' }}
|
|
2711
|
-
</button>
|
|
2712
|
-
</div>
|
|
2713
|
-
</div>
|
|
2714
|
-
</div>
|
|
2715
|
-
}
|
|
2679
|
+
args: [{ selector: 'amf-dialog-host', standalone: true, imports: [CommonModule], template: `
|
|
2680
|
+
@if (currentDialog()) {
|
|
2681
|
+
<div class="amf-dialog-backdrop" (click)="onBackdropClick()">
|
|
2682
|
+
<div class="amf-dialog-box" (click)="$event.stopPropagation()">
|
|
2683
|
+
|
|
2684
|
+
<div class="dialog-header">
|
|
2685
|
+
<div class="dialog-icon-wrapper" [ngClass]="'variant-' + (currentDialog()?.config?.variant || 'info')">
|
|
2686
|
+
@if (currentDialog()?.config?.icon) {
|
|
2687
|
+
<svg viewBox="0 0 24 24" class="icon-element">
|
|
2688
|
+
<path [attr.d]="iconPath"></path>
|
|
2689
|
+
</svg>
|
|
2690
|
+
} @else {
|
|
2691
|
+
<span class="icon-fallback">!</span>
|
|
2692
|
+
}
|
|
2693
|
+
</div>
|
|
2694
|
+
@if (currentDialog()?.config?.title) {
|
|
2695
|
+
<h3 class="dialog-title">{{ currentDialog()!.config!.title }}</h3>
|
|
2696
|
+
}
|
|
2697
|
+
</div>
|
|
2698
|
+
|
|
2699
|
+
<div class="dialog-content">
|
|
2700
|
+
<p class="dialog-message">{{ currentDialog()!.config!.message }}</p>
|
|
2701
|
+
</div>
|
|
2702
|
+
|
|
2703
|
+
<div class="dialog-actions">
|
|
2704
|
+
@if (currentDialog()?.config?.showCancel) {
|
|
2705
|
+
<button class="btn btn-cancel" (click)="close(false)">
|
|
2706
|
+
{{ currentDialog()?.config?.cancelLabel || 'Cancel' }}
|
|
2707
|
+
</button>
|
|
2708
|
+
}
|
|
2709
|
+
<button class="btn btn-confirm" [ngClass]="'btn-variant-' + (currentDialog()?.config?.variant || 'info')" (click)="close(true)">
|
|
2710
|
+
{{ currentDialog()?.config?.confirmLabel || 'OK' }}
|
|
2711
|
+
</button>
|
|
2712
|
+
</div>
|
|
2713
|
+
</div>
|
|
2714
|
+
</div>
|
|
2715
|
+
}
|
|
2716
2716
|
`, styles: [".amf-dialog-backdrop{position:fixed;inset:0;background:#0a0f1ebf;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);z-index:10000;display:flex;align-items:center;justify-content:center;padding:20px;animation:fadeIn .25s ease-out}.amf-dialog-box{background:var(--glass-bg, rgba(20,25,40,.9));border:1px solid var(--app-border, rgba(255,255,255,.1));border-radius:20px;box-shadow:0 25px 50px -12px #0009,0 0 0 1px #ffffff0d inset;width:100%;max-width:420px;display:flex;flex-direction:column;animation:popIn .3s cubic-bezier(.16,1,.3,1);overflow:hidden}.dialog-header{padding:32px 32px 16px;display:flex;flex-direction:column;align-items:center;text-align:center;gap:16px}.dialog-icon-wrapper{width:64px;height:64px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:32px;color:#fff;box-shadow:0 8px 16px -4px #0000004d}.dialog-icon-wrapper.variant-info{background:linear-gradient(135deg,#3b82f6,#2563eb);box-shadow:0 8px 24px -6px #3b82f680}.dialog-icon-wrapper.variant-success{background:linear-gradient(135deg,#10b981,#059669);box-shadow:0 8px 24px -6px #10b98180}.dialog-icon-wrapper.variant-warning{background:linear-gradient(135deg,#f59e0b,#d97706);box-shadow:0 8px 24px -6px #f59e0b80}.dialog-icon-wrapper.variant-danger{background:linear-gradient(135deg,#ef4444,#dc2626);box-shadow:0 8px 24px -6px #ef444480}.icon-element{width:32px;height:32px;display:block;filter:drop-shadow(0 2px 2px rgba(0,0,0,.2))}.icon-fallback{font-family:monospace;font-weight:700}.dialog-title{margin:0;color:var(--app-text, #ffffff);font-size:1.25rem;font-weight:700;letter-spacing:-.02em}.dialog-content{padding:0 32px 32px;text-align:center}.dialog-message{margin:0;color:var(--app-text-muted, #94a3b8);font-size:.95rem;line-height:1.5}.dialog-actions{display:flex;gap:12px;padding:24px 32px;background:#0003;border-top:1px solid var(--app-border, rgba(255,255,255,.05))}.btn{flex:1;padding:12px 20px;border-radius:12px;font-size:.9rem;font-weight:600;cursor:pointer;transition:all .2s;border:none;display:inline-flex;align-items:center;justify-content:center}.btn-cancel{background:#ffffff0d;color:var(--app-text, #ffffff);border:1px solid rgba(255,255,255,.1)}.btn-cancel:hover{background:#ffffff1a}.btn-confirm{color:#fff;box-shadow:0 4px 12px transparent}.btn-confirm:hover{transform:translateY(-1px)}.btn-variant-info{background:#3b82f6;box-shadow:0 4px 12px #3b82f64d}.btn-variant-info:hover{background:#60a5fa;box-shadow:0 6px 16px #3b82f666}.btn-variant-success{background:#10b981;box-shadow:0 4px 12px #10b9814d}.btn-variant-success:hover{background:#34d399;box-shadow:0 6px 16px #10b98166}.btn-variant-warning{background:#f59e0b;box-shadow:0 4px 12px #f59e0b4d}.btn-variant-warning:hover{background:#fbbf24;box-shadow:0 6px 16px #f59e0b66}.btn-variant-danger{background:#ef4444;box-shadow:0 4px 12px #ef44444d}.btn-variant-danger:hover{background:#f87171;box-shadow:0 6px 16px #ef444466}@keyframes fadeIn{0%{opacity:0;-webkit-backdrop-filter:blur(0px);backdrop-filter:blur(0px)}to{opacity:1;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}}@keyframes popIn{0%{opacity:0;transform:scale(.9) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}}\n"] }]
|
|
2717
2717
|
}] });
|
|
2718
2718
|
|
|
@@ -2749,75 +2749,75 @@ class AmfDrawerHostComponent {
|
|
|
2749
2749
|
dispatchAction(actionMeta) {
|
|
2750
2750
|
this.dispatcher.dispatch(actionMeta, {});
|
|
2751
2751
|
}
|
|
2752
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
2753
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
2754
|
-
@if (isOpen()) {
|
|
2755
|
-
<!-- Backdrop -->
|
|
2756
|
-
<div class="amf-drawer-backdrop" (click)="closeOnBackdrop()"></div>
|
|
2757
|
-
}
|
|
2758
|
-
<!-- Drawer panel — always in DOM so the CSS slide animation works -->
|
|
2759
|
-
<div class="amf-drawer-panel"
|
|
2760
|
-
[class.is-open]="isOpen()"
|
|
2761
|
-
[style.width]="config()?.size || '420px'"
|
|
2762
|
-
[class.position-left]="config()?.position === 'left'"
|
|
2763
|
-
(click)="$event.stopPropagation()">
|
|
2764
|
-
@if (isOpen() && config()) {
|
|
2765
|
-
<div class="amf-drawer-header">
|
|
2766
|
-
<h3>{{ config()?.title }}</h3>
|
|
2767
|
-
<button class="amf-drawer-close" (click)="close()" aria-label="Close drawer">×</button>
|
|
2768
|
-
</div>
|
|
2769
|
-
<div class="amf-drawer-content">
|
|
2770
|
-
@if (config()?.content) {
|
|
2771
|
-
<amf-renderer [section]="config()!.content" [context]="{}"></amf-renderer>
|
|
2772
|
-
}
|
|
2773
|
-
</div>
|
|
2774
|
-
@if (config()?.actions?.length) {
|
|
2775
|
-
<div class="amf-drawer-footer">
|
|
2776
|
-
@for (action of config()!.actions; track action.label) {
|
|
2777
|
-
<button [class]="'btn-' + (action.color || 'primary')" (click)="dispatchAction(action.action)">
|
|
2778
|
-
{{ action.label }}
|
|
2779
|
-
</button>
|
|
2780
|
-
}
|
|
2781
|
-
</div>
|
|
2782
|
-
}
|
|
2783
|
-
}
|
|
2784
|
-
</div>
|
|
2752
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AmfDrawerHostComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2753
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: AmfDrawerHostComponent, isStandalone: true, selector: "amf-drawer-host", ngImport: i0, template: `
|
|
2754
|
+
@if (isOpen()) {
|
|
2755
|
+
<!-- Backdrop -->
|
|
2756
|
+
<div class="amf-drawer-backdrop" (click)="closeOnBackdrop()"></div>
|
|
2757
|
+
}
|
|
2758
|
+
<!-- Drawer panel — always in DOM so the CSS slide animation works -->
|
|
2759
|
+
<div class="amf-drawer-panel"
|
|
2760
|
+
[class.is-open]="isOpen()"
|
|
2761
|
+
[style.width]="config()?.size || '420px'"
|
|
2762
|
+
[class.position-left]="config()?.position === 'left'"
|
|
2763
|
+
(click)="$event.stopPropagation()">
|
|
2764
|
+
@if (isOpen() && config()) {
|
|
2765
|
+
<div class="amf-drawer-header">
|
|
2766
|
+
<h3>{{ config()?.title }}</h3>
|
|
2767
|
+
<button class="amf-drawer-close" (click)="close()" aria-label="Close drawer">×</button>
|
|
2768
|
+
</div>
|
|
2769
|
+
<div class="amf-drawer-content">
|
|
2770
|
+
@if (config()?.content) {
|
|
2771
|
+
<amf-renderer [section]="config()!.content" [context]="{}"></amf-renderer>
|
|
2772
|
+
}
|
|
2773
|
+
</div>
|
|
2774
|
+
@if (config()?.actions?.length) {
|
|
2775
|
+
<div class="amf-drawer-footer">
|
|
2776
|
+
@for (action of config()!.actions; track action.label) {
|
|
2777
|
+
<button [class]="'btn-' + (action.color || 'primary')" (click)="dispatchAction(action.action)">
|
|
2778
|
+
{{ action.label }}
|
|
2779
|
+
</button>
|
|
2780
|
+
}
|
|
2781
|
+
</div>
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
</div>
|
|
2785
2785
|
`, isInline: true, styles: [".amf-drawer-backdrop{position:fixed;inset:0;background:#0000008c;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1200;animation:fadeIn .25s ease-out}.amf-drawer-panel{position:fixed;top:0;right:0;height:100%;max-width:95vw;background:var(--glass-bg, rgba(15, 20, 40, .97));border-left:1px solid var(--app-border, rgba(255,255,255,.08));box-shadow:-20px 0 60px #00000080;z-index:1201;display:flex;flex-direction:column;transform:translate(100%);transition:transform .35s cubic-bezier(.16,1,.3,1);will-change:transform;overflow:hidden}.amf-drawer-panel.position-left{right:auto;left:0;border-left:none;border-right:1px solid var(--app-border, rgba(255,255,255,.08));transform:translate(-100%)}.amf-drawer-panel.is-open{transform:translate(0)}.amf-drawer-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--app-border, rgba(255,255,255,.08));flex-shrink:0}.amf-drawer-header h3{margin:0;font-size:1.125rem;font-weight:700;color:var(--app-text, #f1f5f9);letter-spacing:-.01em}.amf-drawer-close{background:#ffffff0f;border:1px solid rgba(255,255,255,.08);color:var(--app-text-muted, #94a3b8);font-size:1.25rem;line-height:1;width:32px;height:32px;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s;flex-shrink:0}.amf-drawer-close:hover{background:#ffffff1f;color:var(--app-text, #f1f5f9)}.amf-drawer-content{flex:1;overflow-y:auto;padding:24px}.amf-drawer-footer{flex-shrink:0;padding:16px 24px;border-top:1px solid var(--app-border, rgba(255,255,255,.08));display:flex;justify-content:flex-end;gap:12px;background:#00000026}.btn-primary{background:linear-gradient(135deg,var(--app-primary, #6366f1),var(--app-accent, #c084fc));color:#fff;padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:600;transition:all .2s}.btn-primary:hover{transform:translateY(-1px);box-shadow:0 6px 20px var(--app-glow)}.btn-outline{background:transparent;border:1px solid #475569;color:#e2e8f0;padding:10px 20px;border-radius:8px;cursor:pointer;font-weight:600;transition:all .2s}.btn-outline:hover{background:#ffffff0f}.btn-danger{background:#ef4444;color:#fff;padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:600}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}\n"], dependencies: [{ kind: "component", type: MetaRendererComponent, selector: "amf-renderer", inputs: ["section", "context"] }] });
|
|
2786
2786
|
}
|
|
2787
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
2787
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AmfDrawerHostComponent, decorators: [{
|
|
2788
2788
|
type: Component,
|
|
2789
|
-
args: [{ selector: 'amf-drawer-host', standalone: true, imports: [MetaRendererComponent], template: `
|
|
2790
|
-
@if (isOpen()) {
|
|
2791
|
-
<!-- Backdrop -->
|
|
2792
|
-
<div class="amf-drawer-backdrop" (click)="closeOnBackdrop()"></div>
|
|
2793
|
-
}
|
|
2794
|
-
<!-- Drawer panel — always in DOM so the CSS slide animation works -->
|
|
2795
|
-
<div class="amf-drawer-panel"
|
|
2796
|
-
[class.is-open]="isOpen()"
|
|
2797
|
-
[style.width]="config()?.size || '420px'"
|
|
2798
|
-
[class.position-left]="config()?.position === 'left'"
|
|
2799
|
-
(click)="$event.stopPropagation()">
|
|
2800
|
-
@if (isOpen() && config()) {
|
|
2801
|
-
<div class="amf-drawer-header">
|
|
2802
|
-
<h3>{{ config()?.title }}</h3>
|
|
2803
|
-
<button class="amf-drawer-close" (click)="close()" aria-label="Close drawer">×</button>
|
|
2804
|
-
</div>
|
|
2805
|
-
<div class="amf-drawer-content">
|
|
2806
|
-
@if (config()?.content) {
|
|
2807
|
-
<amf-renderer [section]="config()!.content" [context]="{}"></amf-renderer>
|
|
2808
|
-
}
|
|
2809
|
-
</div>
|
|
2810
|
-
@if (config()?.actions?.length) {
|
|
2811
|
-
<div class="amf-drawer-footer">
|
|
2812
|
-
@for (action of config()!.actions; track action.label) {
|
|
2813
|
-
<button [class]="'btn-' + (action.color || 'primary')" (click)="dispatchAction(action.action)">
|
|
2814
|
-
{{ action.label }}
|
|
2815
|
-
</button>
|
|
2816
|
-
}
|
|
2817
|
-
</div>
|
|
2818
|
-
}
|
|
2819
|
-
}
|
|
2820
|
-
</div>
|
|
2789
|
+
args: [{ selector: 'amf-drawer-host', standalone: true, imports: [MetaRendererComponent], template: `
|
|
2790
|
+
@if (isOpen()) {
|
|
2791
|
+
<!-- Backdrop -->
|
|
2792
|
+
<div class="amf-drawer-backdrop" (click)="closeOnBackdrop()"></div>
|
|
2793
|
+
}
|
|
2794
|
+
<!-- Drawer panel — always in DOM so the CSS slide animation works -->
|
|
2795
|
+
<div class="amf-drawer-panel"
|
|
2796
|
+
[class.is-open]="isOpen()"
|
|
2797
|
+
[style.width]="config()?.size || '420px'"
|
|
2798
|
+
[class.position-left]="config()?.position === 'left'"
|
|
2799
|
+
(click)="$event.stopPropagation()">
|
|
2800
|
+
@if (isOpen() && config()) {
|
|
2801
|
+
<div class="amf-drawer-header">
|
|
2802
|
+
<h3>{{ config()?.title }}</h3>
|
|
2803
|
+
<button class="amf-drawer-close" (click)="close()" aria-label="Close drawer">×</button>
|
|
2804
|
+
</div>
|
|
2805
|
+
<div class="amf-drawer-content">
|
|
2806
|
+
@if (config()?.content) {
|
|
2807
|
+
<amf-renderer [section]="config()!.content" [context]="{}"></amf-renderer>
|
|
2808
|
+
}
|
|
2809
|
+
</div>
|
|
2810
|
+
@if (config()?.actions?.length) {
|
|
2811
|
+
<div class="amf-drawer-footer">
|
|
2812
|
+
@for (action of config()!.actions; track action.label) {
|
|
2813
|
+
<button [class]="'btn-' + (action.color || 'primary')" (click)="dispatchAction(action.action)">
|
|
2814
|
+
{{ action.label }}
|
|
2815
|
+
</button>
|
|
2816
|
+
}
|
|
2817
|
+
</div>
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2820
|
+
</div>
|
|
2821
2821
|
`, styles: [".amf-drawer-backdrop{position:fixed;inset:0;background:#0000008c;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1200;animation:fadeIn .25s ease-out}.amf-drawer-panel{position:fixed;top:0;right:0;height:100%;max-width:95vw;background:var(--glass-bg, rgba(15, 20, 40, .97));border-left:1px solid var(--app-border, rgba(255,255,255,.08));box-shadow:-20px 0 60px #00000080;z-index:1201;display:flex;flex-direction:column;transform:translate(100%);transition:transform .35s cubic-bezier(.16,1,.3,1);will-change:transform;overflow:hidden}.amf-drawer-panel.position-left{right:auto;left:0;border-left:none;border-right:1px solid var(--app-border, rgba(255,255,255,.08));transform:translate(-100%)}.amf-drawer-panel.is-open{transform:translate(0)}.amf-drawer-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--app-border, rgba(255,255,255,.08));flex-shrink:0}.amf-drawer-header h3{margin:0;font-size:1.125rem;font-weight:700;color:var(--app-text, #f1f5f9);letter-spacing:-.01em}.amf-drawer-close{background:#ffffff0f;border:1px solid rgba(255,255,255,.08);color:var(--app-text-muted, #94a3b8);font-size:1.25rem;line-height:1;width:32px;height:32px;border-radius:8px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s;flex-shrink:0}.amf-drawer-close:hover{background:#ffffff1f;color:var(--app-text, #f1f5f9)}.amf-drawer-content{flex:1;overflow-y:auto;padding:24px}.amf-drawer-footer{flex-shrink:0;padding:16px 24px;border-top:1px solid var(--app-border, rgba(255,255,255,.08));display:flex;justify-content:flex-end;gap:12px;background:#00000026}.btn-primary{background:linear-gradient(135deg,var(--app-primary, #6366f1),var(--app-accent, #c084fc));color:#fff;padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:600;transition:all .2s}.btn-primary:hover{transform:translateY(-1px);box-shadow:0 6px 20px var(--app-glow)}.btn-outline{background:transparent;border:1px solid #475569;color:#e2e8f0;padding:10px 20px;border-radius:8px;cursor:pointer;font-weight:600;transition:all .2s}.btn-outline:hover{background:#ffffff0f}.btn-danger{background:#ef4444;color:#fff;padding:10px 20px;border-radius:8px;border:none;cursor:pointer;font-weight:600}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}\n"] }]
|
|
2822
2822
|
}] });
|
|
2823
2823
|
|
|
@@ -3035,10 +3035,10 @@ class MetaAuthService {
|
|
|
3035
3035
|
const storage = this.getStorage();
|
|
3036
3036
|
return storage.getItem(key);
|
|
3037
3037
|
}
|
|
3038
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
3039
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
3038
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3039
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaAuthService, providedIn: 'root' });
|
|
3040
3040
|
}
|
|
3041
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
3041
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: MetaAuthService, decorators: [{
|
|
3042
3042
|
type: Injectable,
|
|
3043
3043
|
args: [{ providedIn: 'root' }]
|
|
3044
3044
|
}] });
|
|
@@ -3096,10 +3096,10 @@ class ValidatorFactoryService {
|
|
|
3096
3096
|
return error.message;
|
|
3097
3097
|
return 'Invalid field';
|
|
3098
3098
|
}
|
|
3099
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
3100
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
3099
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ValidatorFactoryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
3100
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ValidatorFactoryService, providedIn: 'root' });
|
|
3101
3101
|
}
|
|
3102
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
3102
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ValidatorFactoryService, decorators: [{
|
|
3103
3103
|
type: Injectable,
|
|
3104
3104
|
args: [{ providedIn: 'root' }]
|
|
3105
3105
|
}] });
|
|
@@ -3147,119 +3147,119 @@ class RepeaterFieldComponent {
|
|
|
3147
3147
|
return;
|
|
3148
3148
|
this.formArray.removeAt(index);
|
|
3149
3149
|
}
|
|
3150
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
3151
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
3152
|
-
<div class="amf-repeater" [class]="field.cssClass">
|
|
3153
|
-
<!-- ── Header & Global Add ── -->
|
|
3154
|
-
<div class="repeater-header">
|
|
3155
|
-
<label class="repeater-label">{{ field.label }}</label>
|
|
3156
|
-
@if (canAdd) {
|
|
3157
|
-
<button type="button" class="btn-repeater-add" (click)="addItem()" [disabled]="formDisabled">
|
|
3158
|
-
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
|
3159
|
-
{{ field.addLabel || 'Add Item' }}
|
|
3160
|
-
</button>
|
|
3161
|
-
}
|
|
3162
|
-
</div>
|
|
3163
|
-
|
|
3164
|
-
@if (field.description) {
|
|
3165
|
-
<p class="repeater-description">{{ field.description }}</p>
|
|
3166
|
-
}
|
|
3167
|
-
|
|
3168
|
-
<div class="repeater-list">
|
|
3169
|
-
@for (ctrl of formArray.controls; track $index) {
|
|
3170
|
-
<div class="repeater-item-card">
|
|
3171
|
-
<div class="repeater-item-header">
|
|
3172
|
-
<span class="item-title">Item {{ $index + 1 }}</span>
|
|
3173
|
-
@if (canRemove) {
|
|
3174
|
-
<button type="button" class="btn-repeater-remove" (click)="removeItem($index)" [disabled]="formDisabled" title="Remove Item">
|
|
3175
|
-
<svg viewBox="0 0 24 24"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zm2.46-7.12l1.41-1.41L12 12.59l2.12-2.12 1.41 1.41L13.41 14l2.12 2.12-1.41 1.41L12 15.41l-2.12 2.12-1.41-1.41L10.59 14l-2.12-2.12zM15.5 4l-1-1h-5l-1 1H5v2h14V4z"/></svg>
|
|
3176
|
-
</button>
|
|
3177
|
-
}
|
|
3178
|
-
</div>
|
|
3179
|
-
|
|
3180
|
-
<div class="repeater-item-body">
|
|
3181
|
-
<div class="repeater-fields-grid" [style.grid-template-columns]="getGridStyle(field)">
|
|
3182
|
-
@for (child of field.children || []; track child.key) {
|
|
3183
|
-
<amf-field-renderer
|
|
3184
|
-
[field]="child"
|
|
3185
|
-
[form]="getFormGroup(ctrl)"
|
|
3186
|
-
[formDisabled]="formDisabled"
|
|
3187
|
-
[actionDispatcher]="actionDispatcher"
|
|
3188
|
-
[context]="context"
|
|
3189
|
-
[style.grid-column]="child.colSpan ? 'span ' + child.colSpan : null">
|
|
3190
|
-
</amf-field-renderer>
|
|
3191
|
-
}
|
|
3192
|
-
</div>
|
|
3193
|
-
</div>
|
|
3194
|
-
</div>
|
|
3195
|
-
}
|
|
3196
|
-
|
|
3197
|
-
@if (formArray.controls.length === 0) {
|
|
3198
|
-
<div class="repeater-empty-state">
|
|
3199
|
-
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
|
3200
|
-
<p>No items added yet. Click "{{ field.addLabel || 'Add Item' }}" to begin.</p>
|
|
3201
|
-
</div>
|
|
3202
|
-
}
|
|
3203
|
-
</div>
|
|
3204
|
-
</div>
|
|
3150
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: RepeaterFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3151
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: RepeaterFieldComponent, isStandalone: true, selector: "amf-repeater-field", inputs: { field: "field", formArray: "formArray", formDisabled: "formDisabled", actionDispatcher: "actionDispatcher", context: "context" }, ngImport: i0, template: `
|
|
3152
|
+
<div class="amf-repeater" [class]="field.cssClass">
|
|
3153
|
+
<!-- ── Header & Global Add ── -->
|
|
3154
|
+
<div class="repeater-header">
|
|
3155
|
+
<label class="repeater-label">{{ field.label }}</label>
|
|
3156
|
+
@if (canAdd) {
|
|
3157
|
+
<button type="button" class="btn-repeater-add" (click)="addItem()" [disabled]="formDisabled">
|
|
3158
|
+
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
|
3159
|
+
{{ field.addLabel || 'Add Item' }}
|
|
3160
|
+
</button>
|
|
3161
|
+
}
|
|
3162
|
+
</div>
|
|
3163
|
+
|
|
3164
|
+
@if (field.description) {
|
|
3165
|
+
<p class="repeater-description">{{ field.description }}</p>
|
|
3166
|
+
}
|
|
3167
|
+
|
|
3168
|
+
<div class="repeater-list">
|
|
3169
|
+
@for (ctrl of formArray.controls; track $index) {
|
|
3170
|
+
<div class="repeater-item-card">
|
|
3171
|
+
<div class="repeater-item-header">
|
|
3172
|
+
<span class="item-title">Item {{ $index + 1 }}</span>
|
|
3173
|
+
@if (canRemove) {
|
|
3174
|
+
<button type="button" class="btn-repeater-remove" (click)="removeItem($index)" [disabled]="formDisabled" title="Remove Item">
|
|
3175
|
+
<svg viewBox="0 0 24 24"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zm2.46-7.12l1.41-1.41L12 12.59l2.12-2.12 1.41 1.41L13.41 14l2.12 2.12-1.41 1.41L12 15.41l-2.12 2.12-1.41-1.41L10.59 14l-2.12-2.12zM15.5 4l-1-1h-5l-1 1H5v2h14V4z"/></svg>
|
|
3176
|
+
</button>
|
|
3177
|
+
}
|
|
3178
|
+
</div>
|
|
3179
|
+
|
|
3180
|
+
<div class="repeater-item-body">
|
|
3181
|
+
<div class="repeater-fields-grid" [style.grid-template-columns]="getGridStyle(field)">
|
|
3182
|
+
@for (child of field.children || []; track child.key) {
|
|
3183
|
+
<amf-field-renderer
|
|
3184
|
+
[field]="child"
|
|
3185
|
+
[form]="getFormGroup(ctrl)"
|
|
3186
|
+
[formDisabled]="formDisabled"
|
|
3187
|
+
[actionDispatcher]="actionDispatcher"
|
|
3188
|
+
[context]="context"
|
|
3189
|
+
[style.grid-column]="child.colSpan ? 'span ' + child.colSpan : null">
|
|
3190
|
+
</amf-field-renderer>
|
|
3191
|
+
}
|
|
3192
|
+
</div>
|
|
3193
|
+
</div>
|
|
3194
|
+
</div>
|
|
3195
|
+
}
|
|
3196
|
+
|
|
3197
|
+
@if (formArray.controls.length === 0) {
|
|
3198
|
+
<div class="repeater-empty-state">
|
|
3199
|
+
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
|
3200
|
+
<p>No items added yet. Click "{{ field.addLabel || 'Add Item' }}" to begin.</p>
|
|
3201
|
+
</div>
|
|
3202
|
+
}
|
|
3203
|
+
</div>
|
|
3204
|
+
</div>
|
|
3205
3205
|
`, isInline: true, styles: [".amf-repeater{margin-bottom:24px}.repeater-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.repeater-label{font-size:.9375rem;font-weight:600;color:var(--app-text);margin:0}.repeater-description{font-size:.8125rem;color:var(--app-text-muted);margin:0 0 16px}.btn-repeater-add{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;font-size:.8125rem;font-weight:500;font-family:inherit;cursor:pointer;border:1px solid rgba(59,130,246,.3);border-radius:6px;background:#3b82f61a;color:#3b82f6;transition:all .2s}.btn-repeater-add svg{width:14px;height:14px;fill:currentColor}.btn-repeater-add:hover:not(:disabled){background:#3b82f633}.btn-repeater-add:disabled{opacity:.5;cursor:not-allowed}.repeater-list{display:flex;flex-direction:column;gap:16px}.repeater-item-card{background:var(--app-surface-hover);border:1px solid var(--app-border);border-radius:8px;overflow:hidden;transition:box-shadow .2s}.repeater-item-card:hover{border-color:#3b82f64d}.repeater-item-header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-bottom:1px solid var(--app-border);background:#00000005}:host-context(body.amf-dark) .repeater-item-header{background:#ffffff05}.item-title{font-size:.8125rem;font-weight:600;color:var(--app-text);text-transform:uppercase;letter-spacing:.5px}.btn-repeater-remove{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:4px;background:transparent;color:#ef4444;cursor:pointer;transition:background .2s}.btn-repeater-remove svg{width:18px;height:18px;fill:currentColor}.btn-repeater-remove:hover:not(:disabled){background:#ef44441a}.btn-repeater-remove:disabled{opacity:.5;cursor:not-allowed}.repeater-item-body{padding:16px}.repeater-fields-grid{display:grid;gap:16px}.repeater-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:32px 16px;text-align:center;border:1.5px dashed var(--app-border);border-radius:8px;color:var(--app-text-muted);background:var(--app-surface-hover)}.repeater-empty-state svg{width:32px;height:32px;fill:currentColor;opacity:.5;margin-bottom:12px}.repeater-empty-state p{font-size:.875rem;margin:0}\n"], dependencies: [{ kind: "ngmodule", type: i0.forwardRef(() => ReactiveFormsModule) }, { kind: "component", type: i0.forwardRef(() => FieldRendererComponent), selector: "amf-field-renderer", inputs: ["field", "form", "formDisabled", "actionDispatcher", "context"] }] });
|
|
3206
3206
|
}
|
|
3207
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
3207
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: RepeaterFieldComponent, decorators: [{
|
|
3208
3208
|
type: Component,
|
|
3209
|
-
args: [{ selector: 'amf-repeater-field', standalone: true, imports: [ReactiveFormsModule, forwardRef(() => FieldRendererComponent)], template: `
|
|
3210
|
-
<div class="amf-repeater" [class]="field.cssClass">
|
|
3211
|
-
<!-- ── Header & Global Add ── -->
|
|
3212
|
-
<div class="repeater-header">
|
|
3213
|
-
<label class="repeater-label">{{ field.label }}</label>
|
|
3214
|
-
@if (canAdd) {
|
|
3215
|
-
<button type="button" class="btn-repeater-add" (click)="addItem()" [disabled]="formDisabled">
|
|
3216
|
-
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
|
3217
|
-
{{ field.addLabel || 'Add Item' }}
|
|
3218
|
-
</button>
|
|
3219
|
-
}
|
|
3220
|
-
</div>
|
|
3221
|
-
|
|
3222
|
-
@if (field.description) {
|
|
3223
|
-
<p class="repeater-description">{{ field.description }}</p>
|
|
3224
|
-
}
|
|
3225
|
-
|
|
3226
|
-
<div class="repeater-list">
|
|
3227
|
-
@for (ctrl of formArray.controls; track $index) {
|
|
3228
|
-
<div class="repeater-item-card">
|
|
3229
|
-
<div class="repeater-item-header">
|
|
3230
|
-
<span class="item-title">Item {{ $index + 1 }}</span>
|
|
3231
|
-
@if (canRemove) {
|
|
3232
|
-
<button type="button" class="btn-repeater-remove" (click)="removeItem($index)" [disabled]="formDisabled" title="Remove Item">
|
|
3233
|
-
<svg viewBox="0 0 24 24"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zm2.46-7.12l1.41-1.41L12 12.59l2.12-2.12 1.41 1.41L13.41 14l2.12 2.12-1.41 1.41L12 15.41l-2.12 2.12-1.41-1.41L10.59 14l-2.12-2.12zM15.5 4l-1-1h-5l-1 1H5v2h14V4z"/></svg>
|
|
3234
|
-
</button>
|
|
3235
|
-
}
|
|
3236
|
-
</div>
|
|
3237
|
-
|
|
3238
|
-
<div class="repeater-item-body">
|
|
3239
|
-
<div class="repeater-fields-grid" [style.grid-template-columns]="getGridStyle(field)">
|
|
3240
|
-
@for (child of field.children || []; track child.key) {
|
|
3241
|
-
<amf-field-renderer
|
|
3242
|
-
[field]="child"
|
|
3243
|
-
[form]="getFormGroup(ctrl)"
|
|
3244
|
-
[formDisabled]="formDisabled"
|
|
3245
|
-
[actionDispatcher]="actionDispatcher"
|
|
3246
|
-
[context]="context"
|
|
3247
|
-
[style.grid-column]="child.colSpan ? 'span ' + child.colSpan : null">
|
|
3248
|
-
</amf-field-renderer>
|
|
3249
|
-
}
|
|
3250
|
-
</div>
|
|
3251
|
-
</div>
|
|
3252
|
-
</div>
|
|
3253
|
-
}
|
|
3254
|
-
|
|
3255
|
-
@if (formArray.controls.length === 0) {
|
|
3256
|
-
<div class="repeater-empty-state">
|
|
3257
|
-
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
|
3258
|
-
<p>No items added yet. Click "{{ field.addLabel || 'Add Item' }}" to begin.</p>
|
|
3259
|
-
</div>
|
|
3260
|
-
}
|
|
3261
|
-
</div>
|
|
3262
|
-
</div>
|
|
3209
|
+
args: [{ selector: 'amf-repeater-field', standalone: true, imports: [ReactiveFormsModule, forwardRef(() => FieldRendererComponent)], template: `
|
|
3210
|
+
<div class="amf-repeater" [class]="field.cssClass">
|
|
3211
|
+
<!-- ── Header & Global Add ── -->
|
|
3212
|
+
<div class="repeater-header">
|
|
3213
|
+
<label class="repeater-label">{{ field.label }}</label>
|
|
3214
|
+
@if (canAdd) {
|
|
3215
|
+
<button type="button" class="btn-repeater-add" (click)="addItem()" [disabled]="formDisabled">
|
|
3216
|
+
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
|
3217
|
+
{{ field.addLabel || 'Add Item' }}
|
|
3218
|
+
</button>
|
|
3219
|
+
}
|
|
3220
|
+
</div>
|
|
3221
|
+
|
|
3222
|
+
@if (field.description) {
|
|
3223
|
+
<p class="repeater-description">{{ field.description }}</p>
|
|
3224
|
+
}
|
|
3225
|
+
|
|
3226
|
+
<div class="repeater-list">
|
|
3227
|
+
@for (ctrl of formArray.controls; track $index) {
|
|
3228
|
+
<div class="repeater-item-card">
|
|
3229
|
+
<div class="repeater-item-header">
|
|
3230
|
+
<span class="item-title">Item {{ $index + 1 }}</span>
|
|
3231
|
+
@if (canRemove) {
|
|
3232
|
+
<button type="button" class="btn-repeater-remove" (click)="removeItem($index)" [disabled]="formDisabled" title="Remove Item">
|
|
3233
|
+
<svg viewBox="0 0 24 24"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zm2.46-7.12l1.41-1.41L12 12.59l2.12-2.12 1.41 1.41L13.41 14l2.12 2.12-1.41 1.41L12 15.41l-2.12 2.12-1.41-1.41L10.59 14l-2.12-2.12zM15.5 4l-1-1h-5l-1 1H5v2h14V4z"/></svg>
|
|
3234
|
+
</button>
|
|
3235
|
+
}
|
|
3236
|
+
</div>
|
|
3237
|
+
|
|
3238
|
+
<div class="repeater-item-body">
|
|
3239
|
+
<div class="repeater-fields-grid" [style.grid-template-columns]="getGridStyle(field)">
|
|
3240
|
+
@for (child of field.children || []; track child.key) {
|
|
3241
|
+
<amf-field-renderer
|
|
3242
|
+
[field]="child"
|
|
3243
|
+
[form]="getFormGroup(ctrl)"
|
|
3244
|
+
[formDisabled]="formDisabled"
|
|
3245
|
+
[actionDispatcher]="actionDispatcher"
|
|
3246
|
+
[context]="context"
|
|
3247
|
+
[style.grid-column]="child.colSpan ? 'span ' + child.colSpan : null">
|
|
3248
|
+
</amf-field-renderer>
|
|
3249
|
+
}
|
|
3250
|
+
</div>
|
|
3251
|
+
</div>
|
|
3252
|
+
</div>
|
|
3253
|
+
}
|
|
3254
|
+
|
|
3255
|
+
@if (formArray.controls.length === 0) {
|
|
3256
|
+
<div class="repeater-empty-state">
|
|
3257
|
+
<svg viewBox="0 0 24 24"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>
|
|
3258
|
+
<p>No items added yet. Click "{{ field.addLabel || 'Add Item' }}" to begin.</p>
|
|
3259
|
+
</div>
|
|
3260
|
+
}
|
|
3261
|
+
</div>
|
|
3262
|
+
</div>
|
|
3263
3263
|
`, styles: [".amf-repeater{margin-bottom:24px}.repeater-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}.repeater-label{font-size:.9375rem;font-weight:600;color:var(--app-text);margin:0}.repeater-description{font-size:.8125rem;color:var(--app-text-muted);margin:0 0 16px}.btn-repeater-add{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;font-size:.8125rem;font-weight:500;font-family:inherit;cursor:pointer;border:1px solid rgba(59,130,246,.3);border-radius:6px;background:#3b82f61a;color:#3b82f6;transition:all .2s}.btn-repeater-add svg{width:14px;height:14px;fill:currentColor}.btn-repeater-add:hover:not(:disabled){background:#3b82f633}.btn-repeater-add:disabled{opacity:.5;cursor:not-allowed}.repeater-list{display:flex;flex-direction:column;gap:16px}.repeater-item-card{background:var(--app-surface-hover);border:1px solid var(--app-border);border-radius:8px;overflow:hidden;transition:box-shadow .2s}.repeater-item-card:hover{border-color:#3b82f64d}.repeater-item-header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-bottom:1px solid var(--app-border);background:#00000005}:host-context(body.amf-dark) .repeater-item-header{background:#ffffff05}.item-title{font-size:.8125rem;font-weight:600;color:var(--app-text);text-transform:uppercase;letter-spacing:.5px}.btn-repeater-remove{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:4px;background:transparent;color:#ef4444;cursor:pointer;transition:background .2s}.btn-repeater-remove svg{width:18px;height:18px;fill:currentColor}.btn-repeater-remove:hover:not(:disabled){background:#ef44441a}.btn-repeater-remove:disabled{opacity:.5;cursor:not-allowed}.repeater-item-body{padding:16px}.repeater-fields-grid{display:grid;gap:16px}.repeater-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:32px 16px;text-align:center;border:1.5px dashed var(--app-border);border-radius:8px;color:var(--app-text-muted);background:var(--app-surface-hover)}.repeater-empty-state svg{width:32px;height:32px;fill:currentColor;opacity:.5;margin-bottom:12px}.repeater-empty-state p{font-size:.875rem;margin:0}\n"] }]
|
|
3264
3264
|
}], propDecorators: { field: [{
|
|
3265
3265
|
type: Input
|
|
@@ -3388,231 +3388,231 @@ class FieldRendererComponent {
|
|
|
3388
3388
|
this.actionDispatcher.dispatch(onClick, this.context);
|
|
3389
3389
|
}
|
|
3390
3390
|
}
|
|
3391
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
3392
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
3393
|
-
@if (field.type !== 'hidden') {
|
|
3394
|
-
<div class="amf-field" [class]="field.cssClass" [class.has-error]="hasError" [class.field-disabled]="isFieldDisabled">
|
|
3395
|
-
@if (field.type === 'heading') { <h3 class="field-heading">{{ field.text || field.label }}</h3> }
|
|
3396
|
-
@else if (field.type === 'divider') { <hr class="field-divider" /> }
|
|
3397
|
-
@else {
|
|
3398
|
-
@if (field.label && field.type !== 'repeater') { <label class="field-label" [for]="field.key">{{ field.label }} @if (isRequired) { <span class="required-mark">*</span> } </label> }
|
|
3399
|
-
<div class="field-input-wrapper" [class.has-prefix]="!!field.prefix" [class.has-suffix]="!!field.suffix">
|
|
3400
|
-
@if (field.prefix) { <span class="field-prefix">{{ field.prefix }}</span> }
|
|
3401
|
-
@switch (field.type) {
|
|
3402
|
-
@case ('button') {
|
|
3403
|
-
<button type="button" class="field-button" [class]="'btn-' + (field.color || 'primary')" [disabled]="isFieldDisabled" (click)="handleButtonClick()">
|
|
3404
|
-
{{ field.label }}
|
|
3405
|
-
</button>
|
|
3406
|
-
}
|
|
3407
|
-
@case ('textarea') { <textarea class="field-input field-textarea" [id]="field.key" [formControl]="control" [placeholder]="field.placeholder || ''" [rows]="field.rows || 3" [readOnly]="field.readOnly || false"></textarea> }
|
|
3408
|
-
@case ('select') {
|
|
3409
|
-
<select class="field-input field-select" [id]="field.key" [formControl]="control">
|
|
3410
|
-
<option value="" disabled>{{ field.placeholder || 'Select...' }}</option>
|
|
3411
|
-
@for (opt of field.options || []; track opt.value) { <option [value]="opt.value" [disabled]="opt.disabled || false">{{ opt.label }}</option> }
|
|
3412
|
-
</select>
|
|
3413
|
-
}
|
|
3414
|
-
@case ('checkbox') {
|
|
3415
|
-
<label class="field-checkbox-label"><input type="checkbox" class="field-checkbox" [id]="field.key" [formControl]="control" /><span>{{ field.placeholder || field.label }}</span></label>
|
|
3416
|
-
}
|
|
3417
|
-
@case ('toggle') {
|
|
3418
|
-
<label class="field-toggle-label"><input type="checkbox" class="field-toggle-input" [id]="field.key" [formControl]="control" /><span class="field-toggle-track"><span class="field-toggle-thumb"></span></span>@if (field.placeholder) { <span class="field-toggle-text">{{ field.placeholder }}</span> }</label>
|
|
3419
|
-
}
|
|
3420
|
-
@case ('switch') {
|
|
3421
|
-
<label class="field-toggle-label"><input type="checkbox" class="field-toggle-input" [id]="field.key" [formControl]="control" /><span class="field-toggle-track"><span class="field-toggle-thumb"></span></span>@if (field.placeholder) { <span class="field-toggle-text">{{ field.placeholder }}</span> }</label>
|
|
3422
|
-
}
|
|
3423
|
-
@case ('radio') {
|
|
3424
|
-
<div class="field-radio-group">
|
|
3425
|
-
@for (opt of field.options || []; track opt.value) {
|
|
3426
|
-
<label class="field-radio-label"><input type="radio" [name]="field.key" [value]="opt.value" [formControl]="control" [attr.disabled]="opt.disabled ? '' : null" /><span>{{ opt.label }}</span></label>
|
|
3427
|
-
}
|
|
3428
|
-
</div>
|
|
3429
|
-
}
|
|
3430
|
-
@case ('otp') {
|
|
3431
|
-
<div class="field-otp-group">
|
|
3432
|
-
@for (val of otpArray; track $index) {
|
|
3433
|
-
<input class="field-input otp-digit" type="text" inputmode="numeric" [value]="val" (input)="onOtpInput($event, $index)" (keydown)="onOtpKeydown($event, $index)" [disabled]="isFieldDisabled" placeholder="•" />
|
|
3434
|
-
}
|
|
3435
|
-
</div>
|
|
3436
|
-
}
|
|
3437
|
-
@case ('repeater') {
|
|
3438
|
-
<amf-repeater-field
|
|
3439
|
-
[field]="field"
|
|
3440
|
-
[formArray]="getFormArray(field.key)"
|
|
3441
|
-
[formDisabled]="isFieldDisabled"
|
|
3442
|
-
[actionDispatcher]="actionDispatcher"
|
|
3443
|
-
[context]="context">
|
|
3444
|
-
</amf-repeater-field>
|
|
3445
|
-
}
|
|
3446
|
-
@case ('password') {
|
|
3447
|
-
<div class="password-wrapper">
|
|
3448
|
-
<input
|
|
3449
|
-
class="field-input password-input"
|
|
3450
|
-
[type]="showPassword() ? 'text' : 'password'"
|
|
3451
|
-
[id]="field.key"
|
|
3452
|
-
[formControl]="control"
|
|
3453
|
-
[placeholder]="field.placeholder || ''"
|
|
3454
|
-
[readOnly]="field.readOnly || false"
|
|
3455
|
-
[attr.autocomplete]="field.autocomplete" />
|
|
3456
|
-
<button
|
|
3457
|
-
type="button"
|
|
3458
|
-
class="pwd-toggle-btn"
|
|
3459
|
-
[attr.aria-label]="showPassword() ? 'Hide password' : 'Show password'"
|
|
3460
|
-
(click)="togglePasswordVisibility()">
|
|
3461
|
-
@if (showPassword()) {
|
|
3462
|
-
<!-- Eye-slash: password visible -->
|
|
3463
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
3464
|
-
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/>
|
|
3465
|
-
<path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/>
|
|
3466
|
-
<line x1="1" y1="1" x2="23" y2="23"/>
|
|
3467
|
-
</svg>
|
|
3468
|
-
} @else {
|
|
3469
|
-
<!-- Eye: password hidden -->
|
|
3470
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
3471
|
-
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
|
3472
|
-
<circle cx="12" cy="12" r="3"/>
|
|
3473
|
-
</svg>
|
|
3474
|
-
}
|
|
3475
|
-
</button>
|
|
3476
|
-
</div>
|
|
3477
|
-
}
|
|
3478
|
-
@case ('currency') {
|
|
3479
|
-
<div class="currency-wrapper">
|
|
3480
|
-
<span class="currency-symbol">{{ currencySymbol }}</span>
|
|
3481
|
-
<input
|
|
3482
|
-
class="field-input currency-input"
|
|
3483
|
-
type="text"
|
|
3484
|
-
inputmode="decimal"
|
|
3485
|
-
[id]="field.key"
|
|
3486
|
-
[value]="formattedCurrencyValue"
|
|
3487
|
-
[placeholder]="field.placeholder || '0.00'"
|
|
3488
|
-
[disabled]="isFieldDisabled"
|
|
3489
|
-
(input)="onCurrencyInput($event)"
|
|
3490
|
-
(blur)="onCurrencyBlur($event)" />
|
|
3491
|
-
</div>
|
|
3492
|
-
}
|
|
3493
|
-
@default { <input class="field-input" [type]="field.type" [id]="field.key" [formControl]="control" [placeholder]="field.placeholder || ''" [readOnly]="field.readOnly || false" [attr.min]="field.min" [attr.max]="field.max" [attr.step]="field.step" [attr.accept]="field.accept" [attr.multiple]="field.multiple ? '' : null" [attr.autocomplete]="field.autocomplete" /> }
|
|
3494
|
-
}
|
|
3495
|
-
@if (field.suffix) { <span class="field-suffix">{{ field.suffix }}</span> }
|
|
3496
|
-
</div>
|
|
3497
|
-
@if (field.hint && !hasError) { <span class="field-hint">{{ field.hint }}</span> }
|
|
3498
|
-
@if (hasError) { <span class="field-error">{{ errorMessage }}</span> }
|
|
3499
|
-
}
|
|
3500
|
-
</div>
|
|
3501
|
-
}
|
|
3391
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: FieldRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3392
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: FieldRendererComponent, isStandalone: true, selector: "amf-field-renderer", inputs: { field: "field", form: "form", formDisabled: "formDisabled", actionDispatcher: "actionDispatcher", context: "context" }, ngImport: i0, template: `
|
|
3393
|
+
@if (field.type !== 'hidden') {
|
|
3394
|
+
<div class="amf-field" [class]="field.cssClass" [class.has-error]="hasError" [class.field-disabled]="isFieldDisabled">
|
|
3395
|
+
@if (field.type === 'heading') { <h3 class="field-heading">{{ field.text || field.label }}</h3> }
|
|
3396
|
+
@else if (field.type === 'divider') { <hr class="field-divider" /> }
|
|
3397
|
+
@else {
|
|
3398
|
+
@if (field.label && field.type !== 'repeater') { <label class="field-label" [for]="field.key">{{ field.label }} @if (isRequired) { <span class="required-mark">*</span> } </label> }
|
|
3399
|
+
<div class="field-input-wrapper" [class.has-prefix]="!!field.prefix" [class.has-suffix]="!!field.suffix">
|
|
3400
|
+
@if (field.prefix) { <span class="field-prefix">{{ field.prefix }}</span> }
|
|
3401
|
+
@switch (field.type) {
|
|
3402
|
+
@case ('button') {
|
|
3403
|
+
<button type="button" class="field-button" [class]="'btn-' + (field.color || 'primary')" [disabled]="isFieldDisabled" (click)="handleButtonClick()">
|
|
3404
|
+
{{ field.label }}
|
|
3405
|
+
</button>
|
|
3406
|
+
}
|
|
3407
|
+
@case ('textarea') { <textarea class="field-input field-textarea" [id]="field.key" [formControl]="control" [placeholder]="field.placeholder || ''" [rows]="field.rows || 3" [readOnly]="field.readOnly || false"></textarea> }
|
|
3408
|
+
@case ('select') {
|
|
3409
|
+
<select class="field-input field-select" [id]="field.key" [formControl]="control">
|
|
3410
|
+
<option value="" disabled>{{ field.placeholder || 'Select...' }}</option>
|
|
3411
|
+
@for (opt of field.options || []; track opt.value) { <option [value]="opt.value" [disabled]="opt.disabled || false">{{ opt.label }}</option> }
|
|
3412
|
+
</select>
|
|
3413
|
+
}
|
|
3414
|
+
@case ('checkbox') {
|
|
3415
|
+
<label class="field-checkbox-label"><input type="checkbox" class="field-checkbox" [id]="field.key" [formControl]="control" /><span>{{ field.placeholder || field.label }}</span></label>
|
|
3416
|
+
}
|
|
3417
|
+
@case ('toggle') {
|
|
3418
|
+
<label class="field-toggle-label"><input type="checkbox" class="field-toggle-input" [id]="field.key" [formControl]="control" /><span class="field-toggle-track"><span class="field-toggle-thumb"></span></span>@if (field.placeholder) { <span class="field-toggle-text">{{ field.placeholder }}</span> }</label>
|
|
3419
|
+
}
|
|
3420
|
+
@case ('switch') {
|
|
3421
|
+
<label class="field-toggle-label"><input type="checkbox" class="field-toggle-input" [id]="field.key" [formControl]="control" /><span class="field-toggle-track"><span class="field-toggle-thumb"></span></span>@if (field.placeholder) { <span class="field-toggle-text">{{ field.placeholder }}</span> }</label>
|
|
3422
|
+
}
|
|
3423
|
+
@case ('radio') {
|
|
3424
|
+
<div class="field-radio-group">
|
|
3425
|
+
@for (opt of field.options || []; track opt.value) {
|
|
3426
|
+
<label class="field-radio-label"><input type="radio" [name]="field.key" [value]="opt.value" [formControl]="control" [attr.disabled]="opt.disabled ? '' : null" /><span>{{ opt.label }}</span></label>
|
|
3427
|
+
}
|
|
3428
|
+
</div>
|
|
3429
|
+
}
|
|
3430
|
+
@case ('otp') {
|
|
3431
|
+
<div class="field-otp-group">
|
|
3432
|
+
@for (val of otpArray; track $index) {
|
|
3433
|
+
<input class="field-input otp-digit" type="text" inputmode="numeric" [value]="val" (input)="onOtpInput($event, $index)" (keydown)="onOtpKeydown($event, $index)" [disabled]="isFieldDisabled" placeholder="•" />
|
|
3434
|
+
}
|
|
3435
|
+
</div>
|
|
3436
|
+
}
|
|
3437
|
+
@case ('repeater') {
|
|
3438
|
+
<amf-repeater-field
|
|
3439
|
+
[field]="field"
|
|
3440
|
+
[formArray]="getFormArray(field.key)"
|
|
3441
|
+
[formDisabled]="isFieldDisabled"
|
|
3442
|
+
[actionDispatcher]="actionDispatcher"
|
|
3443
|
+
[context]="context">
|
|
3444
|
+
</amf-repeater-field>
|
|
3445
|
+
}
|
|
3446
|
+
@case ('password') {
|
|
3447
|
+
<div class="password-wrapper">
|
|
3448
|
+
<input
|
|
3449
|
+
class="field-input password-input"
|
|
3450
|
+
[type]="showPassword() ? 'text' : 'password'"
|
|
3451
|
+
[id]="field.key"
|
|
3452
|
+
[formControl]="control"
|
|
3453
|
+
[placeholder]="field.placeholder || ''"
|
|
3454
|
+
[readOnly]="field.readOnly || false"
|
|
3455
|
+
[attr.autocomplete]="field.autocomplete" />
|
|
3456
|
+
<button
|
|
3457
|
+
type="button"
|
|
3458
|
+
class="pwd-toggle-btn"
|
|
3459
|
+
[attr.aria-label]="showPassword() ? 'Hide password' : 'Show password'"
|
|
3460
|
+
(click)="togglePasswordVisibility()">
|
|
3461
|
+
@if (showPassword()) {
|
|
3462
|
+
<!-- Eye-slash: password visible -->
|
|
3463
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
3464
|
+
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/>
|
|
3465
|
+
<path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/>
|
|
3466
|
+
<line x1="1" y1="1" x2="23" y2="23"/>
|
|
3467
|
+
</svg>
|
|
3468
|
+
} @else {
|
|
3469
|
+
<!-- Eye: password hidden -->
|
|
3470
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
3471
|
+
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
|
3472
|
+
<circle cx="12" cy="12" r="3"/>
|
|
3473
|
+
</svg>
|
|
3474
|
+
}
|
|
3475
|
+
</button>
|
|
3476
|
+
</div>
|
|
3477
|
+
}
|
|
3478
|
+
@case ('currency') {
|
|
3479
|
+
<div class="currency-wrapper">
|
|
3480
|
+
<span class="currency-symbol">{{ currencySymbol }}</span>
|
|
3481
|
+
<input
|
|
3482
|
+
class="field-input currency-input"
|
|
3483
|
+
type="text"
|
|
3484
|
+
inputmode="decimal"
|
|
3485
|
+
[id]="field.key"
|
|
3486
|
+
[value]="formattedCurrencyValue"
|
|
3487
|
+
[placeholder]="field.placeholder || '0.00'"
|
|
3488
|
+
[disabled]="isFieldDisabled"
|
|
3489
|
+
(input)="onCurrencyInput($event)"
|
|
3490
|
+
(blur)="onCurrencyBlur($event)" />
|
|
3491
|
+
</div>
|
|
3492
|
+
}
|
|
3493
|
+
@default { <input class="field-input" [type]="field.type" [id]="field.key" [formControl]="control" [placeholder]="field.placeholder || ''" [readOnly]="field.readOnly || false" [attr.min]="field.min" [attr.max]="field.max" [attr.step]="field.step" [attr.accept]="field.accept" [attr.multiple]="field.multiple ? '' : null" [attr.autocomplete]="field.autocomplete" /> }
|
|
3494
|
+
}
|
|
3495
|
+
@if (field.suffix) { <span class="field-suffix">{{ field.suffix }}</span> }
|
|
3496
|
+
</div>
|
|
3497
|
+
@if (field.hint && !hasError) { <span class="field-hint">{{ field.hint }}</span> }
|
|
3498
|
+
@if (hasError) { <span class="field-error">{{ errorMessage }}</span> }
|
|
3499
|
+
}
|
|
3500
|
+
</div>
|
|
3501
|
+
}
|
|
3502
3502
|
`, isInline: true, styles: [".amf-field{display:flex;flex-direction:column;gap:6px}.amf-field.field-disabled{opacity:.5;pointer-events:none}.field-label{font-size:.875rem;font-weight:600;color:var(--app-text)}.required-mark{color:#f43f5e;margin-left:2px}.field-input-wrapper{display:flex;align-items:stretch;position:relative}.field-prefix,.field-suffix{padding:10px 12px;font-size:.875rem;color:var(--app-text-muted);background:var(--glass-bg);border:1px solid var(--app-border);display:flex;align-items:center;justify-content:center;white-space:nowrap;box-sizing:border-box}.field-prefix{border-right:none;border-radius:8px 0 0 8px}.field-suffix{border-left:none;border-radius:0 8px 8px 0}.field-input{flex:1;width:100%;padding:10px 14px;border:1px solid var(--app-border);border-radius:8px;background:var(--glass-bg);color:var(--app-text);font-size:.875rem;font-family:inherit;outline:none;transition:border-color .2s,box-shadow .2s;box-sizing:border-box}.has-prefix .field-input{border-top-left-radius:0;border-bottom-left-radius:0}.has-suffix .field-input{border-top-right-radius:0;border-bottom-right-radius:0}.field-input:focus{border-color:var(--app-primary);box-shadow:0 0 0 3px var(--app-primary-light);z-index:3;position:relative}.field-input::placeholder{color:var(--app-text-muted);opacity:.6}.field-input[readonly]{opacity:.7;cursor:not-allowed}.field-input:disabled{opacity:.5;cursor:not-allowed}.has-error .field-input{border-color:#f43f5e}.has-error .field-input:focus{box-shadow:0 0 0 3px #f43f5e26}.field-select{appearance:none;cursor:pointer;padding-right:36px;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24'%3E%3Cpath fill='%2394a3b8' d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right 12px center;color-scheme:dark}.field-select option{background-color:#1e1e2d;color:#fff}:host-context([data-color-scheme=\"light\"]) .field-select{color-scheme:light}:host-context([data-color-scheme=\"light\"]) .field-select option{background-color:#fff;color:#000}.field-textarea{resize:vertical;min-height:80px}.field-checkbox-label,.field-radio-label{display:flex;align-items:center;gap:8px;font-size:.875rem;color:var(--app-text);cursor:pointer}.field-radio-group{display:flex;flex-direction:column;gap:8px}.field-otp-group{display:flex;gap:8px;justify-content:center;width:100%}.otp-digit{width:44px;height:50px;text-align:center;font-size:1.25rem;font-weight:600;padding:0;letter-spacing:0}.field-toggle-label{display:flex;align-items:center;gap:10px;cursor:pointer}.field-toggle-input{display:none}.field-toggle-track{width:44px;height:24px;background:var(--app-border);border-radius:12px;position:relative;transition:background .2s}.field-toggle-input:checked+.field-toggle-track{background:var(--app-primary)}.field-toggle-thumb{position:absolute;top:2px;left:2px;width:20px;height:20px;background:#fff;border-radius:50%;transition:transform .2s}.field-toggle-input:checked+.field-toggle-track .field-toggle-thumb{transform:translate(20px)}.field-toggle-text{font-size:.875rem;color:var(--app-text)}.field-hint{font-size:.75rem;color:var(--app-text-muted)}.field-error{font-size:.75rem;color:#f43f5e;font-weight:500}.field-heading{font-size:1.125rem;margin-top:8px;color:var(--app-text)}.field-divider{border:none;border-top:1px solid var(--app-border);margin:8px 0}.field-button{padding:10px 20px;border-radius:10px;font-weight:600;font-size:.875rem;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);border:none;width:100%}.field-button.btn-primary{background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff}.field-button.btn-primary:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 24px -4px var(--app-glow)}.field-button.btn-secondary{background:var(--glass-bg);color:var(--app-text);border:1px solid var(--app-border)}.field-button.btn-secondary:hover:not(:disabled){background:var(--glass-bg-hover);border-color:var(--glass-border-light)}.field-button.btn-outline{background:transparent;color:var(--app-text);border:1px solid var(--app-border)}.field-button.btn-outline:hover:not(:disabled){background:var(--glass-bg-hover)}.field-button.btn-success{background:linear-gradient(135deg,#10b981,#34d399);color:#fff}.field-button.btn-success:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 24px -4px #10b9814d}.field-button.btn-accent{background:linear-gradient(135deg,var(--app-accent),var(--app-primary));color:#fff}.field-button.btn-accent:hover:not(:disabled){transform:translateY(-2px)}.field-button:disabled{opacity:.5;cursor:not-allowed;transform:none}.password-wrapper{position:relative;display:flex;align-items:stretch;width:100%}.password-input{padding-right:44px!important}.pwd-toggle-btn{position:absolute;right:0;top:0;bottom:0;width:42px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;color:var(--app-text-muted);border-radius:0 8px 8px 0;transition:color .2s;z-index:2}.pwd-toggle-btn:hover{color:var(--app-primary)}.pwd-toggle-btn svg{width:18px;height:18px}.currency-wrapper{display:flex;align-items:stretch;width:100%}.currency-symbol{padding:10px 12px;font-size:.875rem;font-weight:600;color:var(--app-text-muted);background:var(--glass-bg);border:1px solid var(--app-border);border-right:none;border-radius:8px 0 0 8px;display:flex;align-items:center;white-space:nowrap;box-sizing:border-box}.currency-input{border-top-left-radius:0!important;border-bottom-left-radius:0!important}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.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$2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i1$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormArrayDirective, selector: "[formArray]", inputs: ["formArray"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: RepeaterFieldComponent, selector: "amf-repeater-field", inputs: ["field", "formArray", "formDisabled", "actionDispatcher", "context"] }] });
|
|
3503
3503
|
}
|
|
3504
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
3504
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: FieldRendererComponent, decorators: [{
|
|
3505
3505
|
type: Component,
|
|
3506
|
-
args: [{ selector: 'amf-field-renderer', standalone: true, imports: [ReactiveFormsModule, RepeaterFieldComponent], template: `
|
|
3507
|
-
@if (field.type !== 'hidden') {
|
|
3508
|
-
<div class="amf-field" [class]="field.cssClass" [class.has-error]="hasError" [class.field-disabled]="isFieldDisabled">
|
|
3509
|
-
@if (field.type === 'heading') { <h3 class="field-heading">{{ field.text || field.label }}</h3> }
|
|
3510
|
-
@else if (field.type === 'divider') { <hr class="field-divider" /> }
|
|
3511
|
-
@else {
|
|
3512
|
-
@if (field.label && field.type !== 'repeater') { <label class="field-label" [for]="field.key">{{ field.label }} @if (isRequired) { <span class="required-mark">*</span> } </label> }
|
|
3513
|
-
<div class="field-input-wrapper" [class.has-prefix]="!!field.prefix" [class.has-suffix]="!!field.suffix">
|
|
3514
|
-
@if (field.prefix) { <span class="field-prefix">{{ field.prefix }}</span> }
|
|
3515
|
-
@switch (field.type) {
|
|
3516
|
-
@case ('button') {
|
|
3517
|
-
<button type="button" class="field-button" [class]="'btn-' + (field.color || 'primary')" [disabled]="isFieldDisabled" (click)="handleButtonClick()">
|
|
3518
|
-
{{ field.label }}
|
|
3519
|
-
</button>
|
|
3520
|
-
}
|
|
3521
|
-
@case ('textarea') { <textarea class="field-input field-textarea" [id]="field.key" [formControl]="control" [placeholder]="field.placeholder || ''" [rows]="field.rows || 3" [readOnly]="field.readOnly || false"></textarea> }
|
|
3522
|
-
@case ('select') {
|
|
3523
|
-
<select class="field-input field-select" [id]="field.key" [formControl]="control">
|
|
3524
|
-
<option value="" disabled>{{ field.placeholder || 'Select...' }}</option>
|
|
3525
|
-
@for (opt of field.options || []; track opt.value) { <option [value]="opt.value" [disabled]="opt.disabled || false">{{ opt.label }}</option> }
|
|
3526
|
-
</select>
|
|
3527
|
-
}
|
|
3528
|
-
@case ('checkbox') {
|
|
3529
|
-
<label class="field-checkbox-label"><input type="checkbox" class="field-checkbox" [id]="field.key" [formControl]="control" /><span>{{ field.placeholder || field.label }}</span></label>
|
|
3530
|
-
}
|
|
3531
|
-
@case ('toggle') {
|
|
3532
|
-
<label class="field-toggle-label"><input type="checkbox" class="field-toggle-input" [id]="field.key" [formControl]="control" /><span class="field-toggle-track"><span class="field-toggle-thumb"></span></span>@if (field.placeholder) { <span class="field-toggle-text">{{ field.placeholder }}</span> }</label>
|
|
3533
|
-
}
|
|
3534
|
-
@case ('switch') {
|
|
3535
|
-
<label class="field-toggle-label"><input type="checkbox" class="field-toggle-input" [id]="field.key" [formControl]="control" /><span class="field-toggle-track"><span class="field-toggle-thumb"></span></span>@if (field.placeholder) { <span class="field-toggle-text">{{ field.placeholder }}</span> }</label>
|
|
3536
|
-
}
|
|
3537
|
-
@case ('radio') {
|
|
3538
|
-
<div class="field-radio-group">
|
|
3539
|
-
@for (opt of field.options || []; track opt.value) {
|
|
3540
|
-
<label class="field-radio-label"><input type="radio" [name]="field.key" [value]="opt.value" [formControl]="control" [attr.disabled]="opt.disabled ? '' : null" /><span>{{ opt.label }}</span></label>
|
|
3541
|
-
}
|
|
3542
|
-
</div>
|
|
3543
|
-
}
|
|
3544
|
-
@case ('otp') {
|
|
3545
|
-
<div class="field-otp-group">
|
|
3546
|
-
@for (val of otpArray; track $index) {
|
|
3547
|
-
<input class="field-input otp-digit" type="text" inputmode="numeric" [value]="val" (input)="onOtpInput($event, $index)" (keydown)="onOtpKeydown($event, $index)" [disabled]="isFieldDisabled" placeholder="•" />
|
|
3548
|
-
}
|
|
3549
|
-
</div>
|
|
3550
|
-
}
|
|
3551
|
-
@case ('repeater') {
|
|
3552
|
-
<amf-repeater-field
|
|
3553
|
-
[field]="field"
|
|
3554
|
-
[formArray]="getFormArray(field.key)"
|
|
3555
|
-
[formDisabled]="isFieldDisabled"
|
|
3556
|
-
[actionDispatcher]="actionDispatcher"
|
|
3557
|
-
[context]="context">
|
|
3558
|
-
</amf-repeater-field>
|
|
3559
|
-
}
|
|
3560
|
-
@case ('password') {
|
|
3561
|
-
<div class="password-wrapper">
|
|
3562
|
-
<input
|
|
3563
|
-
class="field-input password-input"
|
|
3564
|
-
[type]="showPassword() ? 'text' : 'password'"
|
|
3565
|
-
[id]="field.key"
|
|
3566
|
-
[formControl]="control"
|
|
3567
|
-
[placeholder]="field.placeholder || ''"
|
|
3568
|
-
[readOnly]="field.readOnly || false"
|
|
3569
|
-
[attr.autocomplete]="field.autocomplete" />
|
|
3570
|
-
<button
|
|
3571
|
-
type="button"
|
|
3572
|
-
class="pwd-toggle-btn"
|
|
3573
|
-
[attr.aria-label]="showPassword() ? 'Hide password' : 'Show password'"
|
|
3574
|
-
(click)="togglePasswordVisibility()">
|
|
3575
|
-
@if (showPassword()) {
|
|
3576
|
-
<!-- Eye-slash: password visible -->
|
|
3577
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
3578
|
-
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/>
|
|
3579
|
-
<path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/>
|
|
3580
|
-
<line x1="1" y1="1" x2="23" y2="23"/>
|
|
3581
|
-
</svg>
|
|
3582
|
-
} @else {
|
|
3583
|
-
<!-- Eye: password hidden -->
|
|
3584
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
3585
|
-
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
|
3586
|
-
<circle cx="12" cy="12" r="3"/>
|
|
3587
|
-
</svg>
|
|
3588
|
-
}
|
|
3589
|
-
</button>
|
|
3590
|
-
</div>
|
|
3591
|
-
}
|
|
3592
|
-
@case ('currency') {
|
|
3593
|
-
<div class="currency-wrapper">
|
|
3594
|
-
<span class="currency-symbol">{{ currencySymbol }}</span>
|
|
3595
|
-
<input
|
|
3596
|
-
class="field-input currency-input"
|
|
3597
|
-
type="text"
|
|
3598
|
-
inputmode="decimal"
|
|
3599
|
-
[id]="field.key"
|
|
3600
|
-
[value]="formattedCurrencyValue"
|
|
3601
|
-
[placeholder]="field.placeholder || '0.00'"
|
|
3602
|
-
[disabled]="isFieldDisabled"
|
|
3603
|
-
(input)="onCurrencyInput($event)"
|
|
3604
|
-
(blur)="onCurrencyBlur($event)" />
|
|
3605
|
-
</div>
|
|
3606
|
-
}
|
|
3607
|
-
@default { <input class="field-input" [type]="field.type" [id]="field.key" [formControl]="control" [placeholder]="field.placeholder || ''" [readOnly]="field.readOnly || false" [attr.min]="field.min" [attr.max]="field.max" [attr.step]="field.step" [attr.accept]="field.accept" [attr.multiple]="field.multiple ? '' : null" [attr.autocomplete]="field.autocomplete" /> }
|
|
3608
|
-
}
|
|
3609
|
-
@if (field.suffix) { <span class="field-suffix">{{ field.suffix }}</span> }
|
|
3610
|
-
</div>
|
|
3611
|
-
@if (field.hint && !hasError) { <span class="field-hint">{{ field.hint }}</span> }
|
|
3612
|
-
@if (hasError) { <span class="field-error">{{ errorMessage }}</span> }
|
|
3613
|
-
}
|
|
3614
|
-
</div>
|
|
3615
|
-
}
|
|
3506
|
+
args: [{ selector: 'amf-field-renderer', standalone: true, imports: [ReactiveFormsModule, RepeaterFieldComponent], template: `
|
|
3507
|
+
@if (field.type !== 'hidden') {
|
|
3508
|
+
<div class="amf-field" [class]="field.cssClass" [class.has-error]="hasError" [class.field-disabled]="isFieldDisabled">
|
|
3509
|
+
@if (field.type === 'heading') { <h3 class="field-heading">{{ field.text || field.label }}</h3> }
|
|
3510
|
+
@else if (field.type === 'divider') { <hr class="field-divider" /> }
|
|
3511
|
+
@else {
|
|
3512
|
+
@if (field.label && field.type !== 'repeater') { <label class="field-label" [for]="field.key">{{ field.label }} @if (isRequired) { <span class="required-mark">*</span> } </label> }
|
|
3513
|
+
<div class="field-input-wrapper" [class.has-prefix]="!!field.prefix" [class.has-suffix]="!!field.suffix">
|
|
3514
|
+
@if (field.prefix) { <span class="field-prefix">{{ field.prefix }}</span> }
|
|
3515
|
+
@switch (field.type) {
|
|
3516
|
+
@case ('button') {
|
|
3517
|
+
<button type="button" class="field-button" [class]="'btn-' + (field.color || 'primary')" [disabled]="isFieldDisabled" (click)="handleButtonClick()">
|
|
3518
|
+
{{ field.label }}
|
|
3519
|
+
</button>
|
|
3520
|
+
}
|
|
3521
|
+
@case ('textarea') { <textarea class="field-input field-textarea" [id]="field.key" [formControl]="control" [placeholder]="field.placeholder || ''" [rows]="field.rows || 3" [readOnly]="field.readOnly || false"></textarea> }
|
|
3522
|
+
@case ('select') {
|
|
3523
|
+
<select class="field-input field-select" [id]="field.key" [formControl]="control">
|
|
3524
|
+
<option value="" disabled>{{ field.placeholder || 'Select...' }}</option>
|
|
3525
|
+
@for (opt of field.options || []; track opt.value) { <option [value]="opt.value" [disabled]="opt.disabled || false">{{ opt.label }}</option> }
|
|
3526
|
+
</select>
|
|
3527
|
+
}
|
|
3528
|
+
@case ('checkbox') {
|
|
3529
|
+
<label class="field-checkbox-label"><input type="checkbox" class="field-checkbox" [id]="field.key" [formControl]="control" /><span>{{ field.placeholder || field.label }}</span></label>
|
|
3530
|
+
}
|
|
3531
|
+
@case ('toggle') {
|
|
3532
|
+
<label class="field-toggle-label"><input type="checkbox" class="field-toggle-input" [id]="field.key" [formControl]="control" /><span class="field-toggle-track"><span class="field-toggle-thumb"></span></span>@if (field.placeholder) { <span class="field-toggle-text">{{ field.placeholder }}</span> }</label>
|
|
3533
|
+
}
|
|
3534
|
+
@case ('switch') {
|
|
3535
|
+
<label class="field-toggle-label"><input type="checkbox" class="field-toggle-input" [id]="field.key" [formControl]="control" /><span class="field-toggle-track"><span class="field-toggle-thumb"></span></span>@if (field.placeholder) { <span class="field-toggle-text">{{ field.placeholder }}</span> }</label>
|
|
3536
|
+
}
|
|
3537
|
+
@case ('radio') {
|
|
3538
|
+
<div class="field-radio-group">
|
|
3539
|
+
@for (opt of field.options || []; track opt.value) {
|
|
3540
|
+
<label class="field-radio-label"><input type="radio" [name]="field.key" [value]="opt.value" [formControl]="control" [attr.disabled]="opt.disabled ? '' : null" /><span>{{ opt.label }}</span></label>
|
|
3541
|
+
}
|
|
3542
|
+
</div>
|
|
3543
|
+
}
|
|
3544
|
+
@case ('otp') {
|
|
3545
|
+
<div class="field-otp-group">
|
|
3546
|
+
@for (val of otpArray; track $index) {
|
|
3547
|
+
<input class="field-input otp-digit" type="text" inputmode="numeric" [value]="val" (input)="onOtpInput($event, $index)" (keydown)="onOtpKeydown($event, $index)" [disabled]="isFieldDisabled" placeholder="•" />
|
|
3548
|
+
}
|
|
3549
|
+
</div>
|
|
3550
|
+
}
|
|
3551
|
+
@case ('repeater') {
|
|
3552
|
+
<amf-repeater-field
|
|
3553
|
+
[field]="field"
|
|
3554
|
+
[formArray]="getFormArray(field.key)"
|
|
3555
|
+
[formDisabled]="isFieldDisabled"
|
|
3556
|
+
[actionDispatcher]="actionDispatcher"
|
|
3557
|
+
[context]="context">
|
|
3558
|
+
</amf-repeater-field>
|
|
3559
|
+
}
|
|
3560
|
+
@case ('password') {
|
|
3561
|
+
<div class="password-wrapper">
|
|
3562
|
+
<input
|
|
3563
|
+
class="field-input password-input"
|
|
3564
|
+
[type]="showPassword() ? 'text' : 'password'"
|
|
3565
|
+
[id]="field.key"
|
|
3566
|
+
[formControl]="control"
|
|
3567
|
+
[placeholder]="field.placeholder || ''"
|
|
3568
|
+
[readOnly]="field.readOnly || false"
|
|
3569
|
+
[attr.autocomplete]="field.autocomplete" />
|
|
3570
|
+
<button
|
|
3571
|
+
type="button"
|
|
3572
|
+
class="pwd-toggle-btn"
|
|
3573
|
+
[attr.aria-label]="showPassword() ? 'Hide password' : 'Show password'"
|
|
3574
|
+
(click)="togglePasswordVisibility()">
|
|
3575
|
+
@if (showPassword()) {
|
|
3576
|
+
<!-- Eye-slash: password visible -->
|
|
3577
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
3578
|
+
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"/>
|
|
3579
|
+
<path d="M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"/>
|
|
3580
|
+
<line x1="1" y1="1" x2="23" y2="23"/>
|
|
3581
|
+
</svg>
|
|
3582
|
+
} @else {
|
|
3583
|
+
<!-- Eye: password hidden -->
|
|
3584
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
3585
|
+
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
|
3586
|
+
<circle cx="12" cy="12" r="3"/>
|
|
3587
|
+
</svg>
|
|
3588
|
+
}
|
|
3589
|
+
</button>
|
|
3590
|
+
</div>
|
|
3591
|
+
}
|
|
3592
|
+
@case ('currency') {
|
|
3593
|
+
<div class="currency-wrapper">
|
|
3594
|
+
<span class="currency-symbol">{{ currencySymbol }}</span>
|
|
3595
|
+
<input
|
|
3596
|
+
class="field-input currency-input"
|
|
3597
|
+
type="text"
|
|
3598
|
+
inputmode="decimal"
|
|
3599
|
+
[id]="field.key"
|
|
3600
|
+
[value]="formattedCurrencyValue"
|
|
3601
|
+
[placeholder]="field.placeholder || '0.00'"
|
|
3602
|
+
[disabled]="isFieldDisabled"
|
|
3603
|
+
(input)="onCurrencyInput($event)"
|
|
3604
|
+
(blur)="onCurrencyBlur($event)" />
|
|
3605
|
+
</div>
|
|
3606
|
+
}
|
|
3607
|
+
@default { <input class="field-input" [type]="field.type" [id]="field.key" [formControl]="control" [placeholder]="field.placeholder || ''" [readOnly]="field.readOnly || false" [attr.min]="field.min" [attr.max]="field.max" [attr.step]="field.step" [attr.accept]="field.accept" [attr.multiple]="field.multiple ? '' : null" [attr.autocomplete]="field.autocomplete" /> }
|
|
3608
|
+
}
|
|
3609
|
+
@if (field.suffix) { <span class="field-suffix">{{ field.suffix }}</span> }
|
|
3610
|
+
</div>
|
|
3611
|
+
@if (field.hint && !hasError) { <span class="field-hint">{{ field.hint }}</span> }
|
|
3612
|
+
@if (hasError) { <span class="field-error">{{ errorMessage }}</span> }
|
|
3613
|
+
}
|
|
3614
|
+
</div>
|
|
3615
|
+
}
|
|
3616
3616
|
`, styles: [".amf-field{display:flex;flex-direction:column;gap:6px}.amf-field.field-disabled{opacity:.5;pointer-events:none}.field-label{font-size:.875rem;font-weight:600;color:var(--app-text)}.required-mark{color:#f43f5e;margin-left:2px}.field-input-wrapper{display:flex;align-items:stretch;position:relative}.field-prefix,.field-suffix{padding:10px 12px;font-size:.875rem;color:var(--app-text-muted);background:var(--glass-bg);border:1px solid var(--app-border);display:flex;align-items:center;justify-content:center;white-space:nowrap;box-sizing:border-box}.field-prefix{border-right:none;border-radius:8px 0 0 8px}.field-suffix{border-left:none;border-radius:0 8px 8px 0}.field-input{flex:1;width:100%;padding:10px 14px;border:1px solid var(--app-border);border-radius:8px;background:var(--glass-bg);color:var(--app-text);font-size:.875rem;font-family:inherit;outline:none;transition:border-color .2s,box-shadow .2s;box-sizing:border-box}.has-prefix .field-input{border-top-left-radius:0;border-bottom-left-radius:0}.has-suffix .field-input{border-top-right-radius:0;border-bottom-right-radius:0}.field-input:focus{border-color:var(--app-primary);box-shadow:0 0 0 3px var(--app-primary-light);z-index:3;position:relative}.field-input::placeholder{color:var(--app-text-muted);opacity:.6}.field-input[readonly]{opacity:.7;cursor:not-allowed}.field-input:disabled{opacity:.5;cursor:not-allowed}.has-error .field-input{border-color:#f43f5e}.has-error .field-input:focus{box-shadow:0 0 0 3px #f43f5e26}.field-select{appearance:none;cursor:pointer;padding-right:36px;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24'%3E%3Cpath fill='%2394a3b8' d='M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6z'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right 12px center;color-scheme:dark}.field-select option{background-color:#1e1e2d;color:#fff}:host-context([data-color-scheme=\"light\"]) .field-select{color-scheme:light}:host-context([data-color-scheme=\"light\"]) .field-select option{background-color:#fff;color:#000}.field-textarea{resize:vertical;min-height:80px}.field-checkbox-label,.field-radio-label{display:flex;align-items:center;gap:8px;font-size:.875rem;color:var(--app-text);cursor:pointer}.field-radio-group{display:flex;flex-direction:column;gap:8px}.field-otp-group{display:flex;gap:8px;justify-content:center;width:100%}.otp-digit{width:44px;height:50px;text-align:center;font-size:1.25rem;font-weight:600;padding:0;letter-spacing:0}.field-toggle-label{display:flex;align-items:center;gap:10px;cursor:pointer}.field-toggle-input{display:none}.field-toggle-track{width:44px;height:24px;background:var(--app-border);border-radius:12px;position:relative;transition:background .2s}.field-toggle-input:checked+.field-toggle-track{background:var(--app-primary)}.field-toggle-thumb{position:absolute;top:2px;left:2px;width:20px;height:20px;background:#fff;border-radius:50%;transition:transform .2s}.field-toggle-input:checked+.field-toggle-track .field-toggle-thumb{transform:translate(20px)}.field-toggle-text{font-size:.875rem;color:var(--app-text)}.field-hint{font-size:.75rem;color:var(--app-text-muted)}.field-error{font-size:.75rem;color:#f43f5e;font-weight:500}.field-heading{font-size:1.125rem;margin-top:8px;color:var(--app-text)}.field-divider{border:none;border-top:1px solid var(--app-border);margin:8px 0}.field-button{padding:10px 20px;border-radius:10px;font-weight:600;font-size:.875rem;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);border:none;width:100%}.field-button.btn-primary{background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff}.field-button.btn-primary:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 24px -4px var(--app-glow)}.field-button.btn-secondary{background:var(--glass-bg);color:var(--app-text);border:1px solid var(--app-border)}.field-button.btn-secondary:hover:not(:disabled){background:var(--glass-bg-hover);border-color:var(--glass-border-light)}.field-button.btn-outline{background:transparent;color:var(--app-text);border:1px solid var(--app-border)}.field-button.btn-outline:hover:not(:disabled){background:var(--glass-bg-hover)}.field-button.btn-success{background:linear-gradient(135deg,#10b981,#34d399);color:#fff}.field-button.btn-success:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 24px -4px #10b9814d}.field-button.btn-accent{background:linear-gradient(135deg,var(--app-accent),var(--app-primary));color:#fff}.field-button.btn-accent:hover:not(:disabled){transform:translateY(-2px)}.field-button:disabled{opacity:.5;cursor:not-allowed;transform:none}.password-wrapper{position:relative;display:flex;align-items:stretch;width:100%}.password-input{padding-right:44px!important}.pwd-toggle-btn{position:absolute;right:0;top:0;bottom:0;width:42px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;color:var(--app-text-muted);border-radius:0 8px 8px 0;transition:color .2s;z-index:2}.pwd-toggle-btn:hover{color:var(--app-primary)}.pwd-toggle-btn svg{width:18px;height:18px}.currency-wrapper{display:flex;align-items:stretch;width:100%}.currency-symbol{padding:10px 12px;font-size:.875rem;font-weight:600;color:var(--app-text-muted);background:var(--glass-bg);border:1px solid var(--app-border);border-right:none;border-radius:8px 0 0 8px;display:flex;align-items:center;white-space:nowrap;box-sizing:border-box}.currency-input{border-top-left-radius:0!important;border-bottom-left-radius:0!important}\n"] }]
|
|
3617
3617
|
}], propDecorators: { field: [{
|
|
3618
3618
|
type: Input
|
|
@@ -3757,41 +3757,41 @@ class FormRendererComponent {
|
|
|
3757
3757
|
return controls;
|
|
3758
3758
|
}
|
|
3759
3759
|
markAllTouched() { Object.values(this.formGroup.controls).forEach(c => c.markAsTouched()); }
|
|
3760
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
3761
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
3762
|
-
<form [formGroup]="formGroup" (ngSubmit)="onSubmit()" class="amf-form" [class]="config.cssClass" [class.form-disabled]="config.disabled">
|
|
3763
|
-
<div class="amf-form-fields" [class]="layoutClass" [style.grid-template-columns]="gridColumns">
|
|
3764
|
-
@for (field of visibleFields; track field.key) {
|
|
3765
|
-
<amf-field-renderer [field]="field" [form]="formGroup" [formDisabled]="!!config.disabled" [actionDispatcher]="actionDispatcher" [context]="context" [style.grid-column]="field.colSpan ? 'span ' + field.colSpan : null"></amf-field-renderer>
|
|
3766
|
-
}
|
|
3767
|
-
</div>
|
|
3768
|
-
@if (!config.hideSubmit) {
|
|
3769
|
-
<div class="amf-form-actions">
|
|
3770
|
-
@if (config.showCancel) { <button type="button" class="btn-secondary" (click)="handleCancel()" [disabled]="config.disabled">{{ config.cancelLabel || 'Cancel' }}</button> }
|
|
3771
|
-
@if (config.showReset) { <button type="button" class="btn-secondary" (click)="formGroup.reset()" [disabled]="config.disabled">Reset</button> }
|
|
3772
|
-
<button type="submit" class="btn-primary" [disabled]="formGroup.invalid || config.disabled">{{ config.submitLabel || 'Submit' }}</button>
|
|
3773
|
-
</div>
|
|
3774
|
-
}
|
|
3775
|
-
</form>
|
|
3760
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: FormRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3761
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: FormRendererComponent, isStandalone: true, selector: "amf-form-renderer", inputs: { config: "config", context: "context" }, outputs: { formSubmit: "formSubmit", formCancel: "formCancel", formChange: "formChange" }, usesOnChanges: true, ngImport: i0, template: `
|
|
3762
|
+
<form [formGroup]="formGroup" (ngSubmit)="onSubmit()" class="amf-form" [class]="config.cssClass" [class.form-disabled]="config.disabled">
|
|
3763
|
+
<div class="amf-form-fields" [class]="layoutClass" [style.grid-template-columns]="gridColumns">
|
|
3764
|
+
@for (field of visibleFields; track field.key) {
|
|
3765
|
+
<amf-field-renderer [field]="field" [form]="formGroup" [formDisabled]="!!config.disabled" [actionDispatcher]="actionDispatcher" [context]="context" [style.grid-column]="field.colSpan ? 'span ' + field.colSpan : null"></amf-field-renderer>
|
|
3766
|
+
}
|
|
3767
|
+
</div>
|
|
3768
|
+
@if (!config.hideSubmit) {
|
|
3769
|
+
<div class="amf-form-actions">
|
|
3770
|
+
@if (config.showCancel) { <button type="button" class="btn-secondary" (click)="handleCancel()" [disabled]="config.disabled">{{ config.cancelLabel || 'Cancel' }}</button> }
|
|
3771
|
+
@if (config.showReset) { <button type="button" class="btn-secondary" (click)="formGroup.reset()" [disabled]="config.disabled">Reset</button> }
|
|
3772
|
+
<button type="submit" class="btn-primary" [disabled]="formGroup.invalid || config.disabled">{{ config.submitLabel || 'Submit' }}</button>
|
|
3773
|
+
</div>
|
|
3774
|
+
}
|
|
3775
|
+
</form>
|
|
3776
3776
|
`, isInline: true, styles: [".amf-form{display:flex;flex-direction:column;gap:24px}.amf-form.form-disabled{opacity:.6;pointer-events:none}.amf-form-fields{display:flex;flex-direction:column;gap:20px}.amf-form-fields.layout-grid{display:grid;gap:20px}.amf-form-fields.layout-horizontal{flex-direction:row;flex-wrap:wrap;gap:16px}.amf-form-fields.layout-horizontal>*{flex:1;min-width:200px}.amf-form-fields.layout-inline{flex-direction:row;align-items:flex-end;gap:12px}.amf-form-actions{display:flex;justify-content:flex-end;gap:12px;padding-top:8px;border-top:1px solid var(--app-border)}.btn-primary{background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:var(--app-on-primary, #fff);border:none;padding:10px 24px;border-radius:10px;font-weight:600;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1)}.btn-primary:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 24px -4px var(--app-glow)}.btn-primary:disabled{opacity:.5;cursor:not-allowed;transform:none}.btn-secondary{background:var(--glass-bg);color:var(--app-text);border:1px solid var(--app-border);padding:10px 24px;border-radius:10px;font-weight:600;cursor:pointer;transition:all .2s}.btn-secondary:hover{background:var(--glass-bg-hover);border-color:var(--glass-border-light)}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: FieldRendererComponent, selector: "amf-field-renderer", inputs: ["field", "form", "formDisabled", "actionDispatcher", "context"] }] });
|
|
3777
3777
|
}
|
|
3778
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
3778
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: FormRendererComponent, decorators: [{
|
|
3779
3779
|
type: Component,
|
|
3780
|
-
args: [{ selector: 'amf-form-renderer', standalone: true, imports: [ReactiveFormsModule, FieldRendererComponent], template: `
|
|
3781
|
-
<form [formGroup]="formGroup" (ngSubmit)="onSubmit()" class="amf-form" [class]="config.cssClass" [class.form-disabled]="config.disabled">
|
|
3782
|
-
<div class="amf-form-fields" [class]="layoutClass" [style.grid-template-columns]="gridColumns">
|
|
3783
|
-
@for (field of visibleFields; track field.key) {
|
|
3784
|
-
<amf-field-renderer [field]="field" [form]="formGroup" [formDisabled]="!!config.disabled" [actionDispatcher]="actionDispatcher" [context]="context" [style.grid-column]="field.colSpan ? 'span ' + field.colSpan : null"></amf-field-renderer>
|
|
3785
|
-
}
|
|
3786
|
-
</div>
|
|
3787
|
-
@if (!config.hideSubmit) {
|
|
3788
|
-
<div class="amf-form-actions">
|
|
3789
|
-
@if (config.showCancel) { <button type="button" class="btn-secondary" (click)="handleCancel()" [disabled]="config.disabled">{{ config.cancelLabel || 'Cancel' }}</button> }
|
|
3790
|
-
@if (config.showReset) { <button type="button" class="btn-secondary" (click)="formGroup.reset()" [disabled]="config.disabled">Reset</button> }
|
|
3791
|
-
<button type="submit" class="btn-primary" [disabled]="formGroup.invalid || config.disabled">{{ config.submitLabel || 'Submit' }}</button>
|
|
3792
|
-
</div>
|
|
3793
|
-
}
|
|
3794
|
-
</form>
|
|
3780
|
+
args: [{ selector: 'amf-form-renderer', standalone: true, imports: [ReactiveFormsModule, FieldRendererComponent], template: `
|
|
3781
|
+
<form [formGroup]="formGroup" (ngSubmit)="onSubmit()" class="amf-form" [class]="config.cssClass" [class.form-disabled]="config.disabled">
|
|
3782
|
+
<div class="amf-form-fields" [class]="layoutClass" [style.grid-template-columns]="gridColumns">
|
|
3783
|
+
@for (field of visibleFields; track field.key) {
|
|
3784
|
+
<amf-field-renderer [field]="field" [form]="formGroup" [formDisabled]="!!config.disabled" [actionDispatcher]="actionDispatcher" [context]="context" [style.grid-column]="field.colSpan ? 'span ' + field.colSpan : null"></amf-field-renderer>
|
|
3785
|
+
}
|
|
3786
|
+
</div>
|
|
3787
|
+
@if (!config.hideSubmit) {
|
|
3788
|
+
<div class="amf-form-actions">
|
|
3789
|
+
@if (config.showCancel) { <button type="button" class="btn-secondary" (click)="handleCancel()" [disabled]="config.disabled">{{ config.cancelLabel || 'Cancel' }}</button> }
|
|
3790
|
+
@if (config.showReset) { <button type="button" class="btn-secondary" (click)="formGroup.reset()" [disabled]="config.disabled">Reset</button> }
|
|
3791
|
+
<button type="submit" class="btn-primary" [disabled]="formGroup.invalid || config.disabled">{{ config.submitLabel || 'Submit' }}</button>
|
|
3792
|
+
</div>
|
|
3793
|
+
}
|
|
3794
|
+
</form>
|
|
3795
3795
|
`, styles: [".amf-form{display:flex;flex-direction:column;gap:24px}.amf-form.form-disabled{opacity:.6;pointer-events:none}.amf-form-fields{display:flex;flex-direction:column;gap:20px}.amf-form-fields.layout-grid{display:grid;gap:20px}.amf-form-fields.layout-horizontal{flex-direction:row;flex-wrap:wrap;gap:16px}.amf-form-fields.layout-horizontal>*{flex:1;min-width:200px}.amf-form-fields.layout-inline{flex-direction:row;align-items:flex-end;gap:12px}.amf-form-actions{display:flex;justify-content:flex-end;gap:12px;padding-top:8px;border-top:1px solid var(--app-border)}.btn-primary{background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:var(--app-on-primary, #fff);border:none;padding:10px 24px;border-radius:10px;font-weight:600;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1)}.btn-primary:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 24px -4px var(--app-glow)}.btn-primary:disabled{opacity:.5;cursor:not-allowed;transform:none}.btn-secondary{background:var(--glass-bg);color:var(--app-text);border:1px solid var(--app-border);padding:10px 24px;border-radius:10px;font-weight:600;cursor:pointer;transition:all .2s}.btn-secondary:hover{background:var(--glass-bg-hover);border-color:var(--glass-border-light)}\n"] }]
|
|
3796
3796
|
}], propDecorators: { config: [{
|
|
3797
3797
|
type: Input
|
|
@@ -4045,215 +4045,215 @@ class StepperFormRendererComponent {
|
|
|
4045
4045
|
}
|
|
4046
4046
|
return controls;
|
|
4047
4047
|
}
|
|
4048
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
4049
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
4050
|
-
<div class="amf-stepper" [class]="config.cssClass" [class.stepper-disabled]="config.disabled">
|
|
4051
|
-
|
|
4052
|
-
<!-- ─── Step Header ──────────────────────────────────── -->
|
|
4053
|
-
<div class="stepper-header">
|
|
4054
|
-
@for (step of resolvedSteps(); track $index) {
|
|
4055
|
-
<div class="step-item"
|
|
4056
|
-
[class.active]="$index === currentStep()"
|
|
4057
|
-
[class.completed]="isCompleted($index)"
|
|
4058
|
-
[class.skipped]="isSkipped($index)"
|
|
4059
|
-
[class.navigable]="canNavigateTo($index)"
|
|
4060
|
-
(click)="canNavigateTo($index) && goToStep($index)">
|
|
4061
|
-
<div class="step-indicator">
|
|
4062
|
-
@if (isCompleted($index)) {
|
|
4063
|
-
<svg class="check-icon" viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
|
|
4064
|
-
} @else if (isSkipped($index)) {
|
|
4065
|
-
<svg class="skip-icon" viewBox="0 0 24 24"><path d="M6 18l8.5-6L6 6v12zm2-8.14L11.03 12 8 14.14V9.86zM16 6h2v12h-2z"/></svg>
|
|
4066
|
-
} @else {
|
|
4067
|
-
<span class="step-number">{{ $index + 1 }}</span>
|
|
4068
|
-
}
|
|
4069
|
-
</div>
|
|
4070
|
-
<div class="step-label-group">
|
|
4071
|
-
<span class="step-title">{{ step.title }}</span>
|
|
4072
|
-
@if (step.description) { <span class="step-description">{{ step.description }}</span> }
|
|
4073
|
-
</div>
|
|
4074
|
-
@if ($index < resolvedSteps().length - 1) {
|
|
4075
|
-
<div class="step-connector" [class.completed]="isCompleted($index)"></div>
|
|
4076
|
-
}
|
|
4077
|
-
</div>
|
|
4078
|
-
}
|
|
4079
|
-
</div>
|
|
4080
|
-
|
|
4081
|
-
<!-- ─── Mobile Progress Bar ───────────────────────────── -->
|
|
4082
|
-
<div class="stepper-progress-mobile">
|
|
4083
|
-
<span class="progress-label">Step {{ currentStep() + 1 }} of {{ resolvedSteps().length }}: {{ resolvedSteps()[currentStep()]?.title }}</span>
|
|
4084
|
-
<div class="progress-bar-track">
|
|
4085
|
-
<div class="progress-bar-fill" [style.width.%]="progressPercent()"></div>
|
|
4086
|
-
</div>
|
|
4087
|
-
</div>
|
|
4088
|
-
|
|
4089
|
-
<!-- ─── Step Content ─────────────────────────────────── -->
|
|
4090
|
-
<form [formGroup]="formGroup" (ngSubmit)="onSubmit()" class="stepper-form-body">
|
|
4091
|
-
<div class="step-content">
|
|
4092
|
-
<div class="step-fields" [style.grid-template-columns]="currentGridColumns()">
|
|
4093
|
-
@for (field of currentStepVisibleFields(); track field.key) {
|
|
4094
|
-
<amf-field-renderer
|
|
4095
|
-
[field]="field"
|
|
4096
|
-
[form]="formGroup"
|
|
4097
|
-
[formDisabled]="!!config.disabled"
|
|
4098
|
-
[actionDispatcher]="actionDispatcher"
|
|
4099
|
-
[context]="context"
|
|
4100
|
-
[style.grid-column]="field.colSpan ? 'span ' + field.colSpan : null">
|
|
4101
|
-
</amf-field-renderer>
|
|
4102
|
-
}
|
|
4103
|
-
</div>
|
|
4104
|
-
|
|
4105
|
-
<!-- Step-level validation error summary -->
|
|
4106
|
-
@if (stepErrors().length) {
|
|
4107
|
-
<div class="step-error-summary">
|
|
4108
|
-
<svg viewBox="0 0 24 24" class="error-summary-icon"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/></svg>
|
|
4109
|
-
<span>Please fix {{ stepErrors().length }} error{{ stepErrors().length > 1 ? 's' : '' }} before continuing.</span>
|
|
4110
|
-
</div>
|
|
4111
|
-
}
|
|
4112
|
-
</div>
|
|
4113
|
-
|
|
4114
|
-
<!-- ─── Navigation Actions ────────────────────────────── -->
|
|
4115
|
-
<div class="stepper-actions">
|
|
4116
|
-
<div class="stepper-actions-left">
|
|
4117
|
-
@if (config.showReset) {
|
|
4118
|
-
<button type="button" class="btn-reset" (click)="resetForm()" [disabled]="config.disabled">
|
|
4119
|
-
<svg viewBox="0 0 24 24"><path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/></svg>
|
|
4120
|
-
{{ config.resetLabel || 'Start Over' }}
|
|
4121
|
-
</button>
|
|
4122
|
-
}
|
|
4123
|
-
@if (currentStep() > 0) {
|
|
4124
|
-
<button type="button" class="btn-back" (click)="goBack()" [disabled]="config.disabled">
|
|
4125
|
-
<svg viewBox="0 0 24 24"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></svg>
|
|
4126
|
-
Back
|
|
4127
|
-
</button>
|
|
4128
|
-
}
|
|
4129
|
-
</div>
|
|
4130
|
-
<div class="stepper-actions-right">
|
|
4131
|
-
@if (resolvedSteps()[currentStep()]?.optional) {
|
|
4132
|
-
<button type="button" class="btn-skip" (click)="skipStep()" [disabled]="config.disabled">Skip</button>
|
|
4133
|
-
}
|
|
4134
|
-
@if (currentStep() < resolvedSteps().length - 1) {
|
|
4135
|
-
<button type="button" class="btn-next" (click)="goNext()" [disabled]="config.disabled">
|
|
4136
|
-
{{ resolvedSteps()[currentStep() + 1] ? 'Next' : 'Review' }}
|
|
4137
|
-
<svg viewBox="0 0 24 24"><path d="M4 11v2h12l-5.59 5.59L12 20l8-8-8-8-1.41 1.41L16 11H4z"/></svg>
|
|
4138
|
-
</button>
|
|
4139
|
-
} @else {
|
|
4140
|
-
@if (!config.hideSubmit) {
|
|
4141
|
-
<button type="submit" class="btn-submit" [disabled]="formGroup.invalid || config.disabled">
|
|
4142
|
-
{{ config.submitLabel || 'Submit' }}
|
|
4143
|
-
<svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
|
|
4144
|
-
</button>
|
|
4145
|
-
}
|
|
4146
|
-
}
|
|
4147
|
-
</div>
|
|
4148
|
-
</div>
|
|
4149
|
-
</form>
|
|
4150
|
-
</div>
|
|
4048
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: StepperFormRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4049
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: StepperFormRendererComponent, isStandalone: true, selector: "amf-stepper-form-renderer", inputs: { config: "config", context: "context" }, outputs: { formSubmit: "formSubmit", formCancel: "formCancel" }, usesOnChanges: true, ngImport: i0, template: `
|
|
4050
|
+
<div class="amf-stepper" [class]="config.cssClass" [class.stepper-disabled]="config.disabled">
|
|
4051
|
+
|
|
4052
|
+
<!-- ─── Step Header ──────────────────────────────────── -->
|
|
4053
|
+
<div class="stepper-header">
|
|
4054
|
+
@for (step of resolvedSteps(); track $index) {
|
|
4055
|
+
<div class="step-item"
|
|
4056
|
+
[class.active]="$index === currentStep()"
|
|
4057
|
+
[class.completed]="isCompleted($index)"
|
|
4058
|
+
[class.skipped]="isSkipped($index)"
|
|
4059
|
+
[class.navigable]="canNavigateTo($index)"
|
|
4060
|
+
(click)="canNavigateTo($index) && goToStep($index)">
|
|
4061
|
+
<div class="step-indicator">
|
|
4062
|
+
@if (isCompleted($index)) {
|
|
4063
|
+
<svg class="check-icon" viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
|
|
4064
|
+
} @else if (isSkipped($index)) {
|
|
4065
|
+
<svg class="skip-icon" viewBox="0 0 24 24"><path d="M6 18l8.5-6L6 6v12zm2-8.14L11.03 12 8 14.14V9.86zM16 6h2v12h-2z"/></svg>
|
|
4066
|
+
} @else {
|
|
4067
|
+
<span class="step-number">{{ $index + 1 }}</span>
|
|
4068
|
+
}
|
|
4069
|
+
</div>
|
|
4070
|
+
<div class="step-label-group">
|
|
4071
|
+
<span class="step-title">{{ step.title }}</span>
|
|
4072
|
+
@if (step.description) { <span class="step-description">{{ step.description }}</span> }
|
|
4073
|
+
</div>
|
|
4074
|
+
@if ($index < resolvedSteps().length - 1) {
|
|
4075
|
+
<div class="step-connector" [class.completed]="isCompleted($index)"></div>
|
|
4076
|
+
}
|
|
4077
|
+
</div>
|
|
4078
|
+
}
|
|
4079
|
+
</div>
|
|
4080
|
+
|
|
4081
|
+
<!-- ─── Mobile Progress Bar ───────────────────────────── -->
|
|
4082
|
+
<div class="stepper-progress-mobile">
|
|
4083
|
+
<span class="progress-label">Step {{ currentStep() + 1 }} of {{ resolvedSteps().length }}: {{ resolvedSteps()[currentStep()]?.title }}</span>
|
|
4084
|
+
<div class="progress-bar-track">
|
|
4085
|
+
<div class="progress-bar-fill" [style.width.%]="progressPercent()"></div>
|
|
4086
|
+
</div>
|
|
4087
|
+
</div>
|
|
4088
|
+
|
|
4089
|
+
<!-- ─── Step Content ─────────────────────────────────── -->
|
|
4090
|
+
<form [formGroup]="formGroup" (ngSubmit)="onSubmit()" class="stepper-form-body">
|
|
4091
|
+
<div class="step-content">
|
|
4092
|
+
<div class="step-fields" [style.grid-template-columns]="currentGridColumns()">
|
|
4093
|
+
@for (field of currentStepVisibleFields(); track field.key) {
|
|
4094
|
+
<amf-field-renderer
|
|
4095
|
+
[field]="field"
|
|
4096
|
+
[form]="formGroup"
|
|
4097
|
+
[formDisabled]="!!config.disabled"
|
|
4098
|
+
[actionDispatcher]="actionDispatcher"
|
|
4099
|
+
[context]="context"
|
|
4100
|
+
[style.grid-column]="field.colSpan ? 'span ' + field.colSpan : null">
|
|
4101
|
+
</amf-field-renderer>
|
|
4102
|
+
}
|
|
4103
|
+
</div>
|
|
4104
|
+
|
|
4105
|
+
<!-- Step-level validation error summary -->
|
|
4106
|
+
@if (stepErrors().length) {
|
|
4107
|
+
<div class="step-error-summary">
|
|
4108
|
+
<svg viewBox="0 0 24 24" class="error-summary-icon"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/></svg>
|
|
4109
|
+
<span>Please fix {{ stepErrors().length }} error{{ stepErrors().length > 1 ? 's' : '' }} before continuing.</span>
|
|
4110
|
+
</div>
|
|
4111
|
+
}
|
|
4112
|
+
</div>
|
|
4113
|
+
|
|
4114
|
+
<!-- ─── Navigation Actions ────────────────────────────── -->
|
|
4115
|
+
<div class="stepper-actions">
|
|
4116
|
+
<div class="stepper-actions-left">
|
|
4117
|
+
@if (config.showReset) {
|
|
4118
|
+
<button type="button" class="btn-reset" (click)="resetForm()" [disabled]="config.disabled">
|
|
4119
|
+
<svg viewBox="0 0 24 24"><path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/></svg>
|
|
4120
|
+
{{ config.resetLabel || 'Start Over' }}
|
|
4121
|
+
</button>
|
|
4122
|
+
}
|
|
4123
|
+
@if (currentStep() > 0) {
|
|
4124
|
+
<button type="button" class="btn-back" (click)="goBack()" [disabled]="config.disabled">
|
|
4125
|
+
<svg viewBox="0 0 24 24"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></svg>
|
|
4126
|
+
Back
|
|
4127
|
+
</button>
|
|
4128
|
+
}
|
|
4129
|
+
</div>
|
|
4130
|
+
<div class="stepper-actions-right">
|
|
4131
|
+
@if (resolvedSteps()[currentStep()]?.optional) {
|
|
4132
|
+
<button type="button" class="btn-skip" (click)="skipStep()" [disabled]="config.disabled">Skip</button>
|
|
4133
|
+
}
|
|
4134
|
+
@if (currentStep() < resolvedSteps().length - 1) {
|
|
4135
|
+
<button type="button" class="btn-next" (click)="goNext()" [disabled]="config.disabled">
|
|
4136
|
+
{{ resolvedSteps()[currentStep() + 1] ? 'Next' : 'Review' }}
|
|
4137
|
+
<svg viewBox="0 0 24 24"><path d="M4 11v2h12l-5.59 5.59L12 20l8-8-8-8-1.41 1.41L16 11H4z"/></svg>
|
|
4138
|
+
</button>
|
|
4139
|
+
} @else {
|
|
4140
|
+
@if (!config.hideSubmit) {
|
|
4141
|
+
<button type="submit" class="btn-submit" [disabled]="formGroup.invalid || config.disabled">
|
|
4142
|
+
{{ config.submitLabel || 'Submit' }}
|
|
4143
|
+
<svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
|
|
4144
|
+
</button>
|
|
4145
|
+
}
|
|
4146
|
+
}
|
|
4147
|
+
</div>
|
|
4148
|
+
</div>
|
|
4149
|
+
</form>
|
|
4150
|
+
</div>
|
|
4151
4151
|
`, isInline: true, styles: [".amf-stepper{display:flex;flex-direction:column;gap:0}.amf-stepper.stepper-disabled{opacity:.6;pointer-events:none}.stepper-header{display:flex;align-items:flex-start;gap:0;padding:20px 24px 0;overflow-x:auto;scrollbar-width:none}.stepper-header::-webkit-scrollbar{display:none}.step-item{display:flex;align-items:center;flex:1;min-width:0;cursor:default;position:relative}.step-item.navigable{cursor:pointer}.step-item.navigable:hover .step-indicator{border-color:var(--app-primary)}.step-item.navigable:hover .step-title{color:var(--app-text)}.step-indicator{flex-shrink:0;width:36px;height:36px;border-radius:50%;border:2px solid var(--app-border);background:var(--app-surface);display:flex;align-items:center;justify-content:center;transition:all .35s cubic-bezier(.4,0,.2,1);position:relative;z-index:1}.step-item.active .step-indicator{border-color:var(--app-primary);background:var(--app-primary);box-shadow:0 0 0 4px rgba(var(--app-primary-rgb, 99 102 241),.18)}.step-item.completed .step-indicator{border-color:#22c55e;background:#22c55e}.step-item.skipped .step-indicator{border-color:var(--app-text-muted);background:var(--glass-bg)}.step-number{font-size:.8125rem;font-weight:700;color:var(--app-text-muted)}.step-item.active .step-number{color:#fff}.check-icon,.skip-icon{width:18px;height:18px;fill:#fff}.skip-icon{fill:var(--app-text-muted)}.step-label-group{display:flex;flex-direction:column;margin-left:10px;min-width:0;flex-shrink:0}.step-title{font-size:.8125rem;font-weight:600;color:var(--app-text-muted);white-space:nowrap;transition:color .2s}.step-item.active .step-title{color:var(--app-text)}.step-item.completed .step-title{color:var(--app-text-muted)}.step-description{font-size:.6875rem;color:var(--app-text-muted);opacity:.7;white-space:nowrap;margin-top:1px}.step-connector{flex:1;height:2px;background:var(--app-border);margin:0 10px 14px;border-radius:1px;transition:background .4s ease;align-self:center}.step-connector.completed{background:linear-gradient(90deg,#22c55e,var(--app-primary))}.stepper-progress-mobile{display:none;flex-direction:column;gap:8px;padding:16px 24px 0}@media(max-width:640px){.stepper-header{display:none}.stepper-progress-mobile{display:flex}}.progress-label{font-size:.8125rem;font-weight:600;color:var(--app-text)}.progress-bar-track{width:100%;height:6px;background:var(--app-border);border-radius:3px;overflow:hidden}.progress-bar-fill{height:100%;background:linear-gradient(90deg,var(--app-primary),var(--app-accent));border-radius:3px;transition:width .4s cubic-bezier(.4,0,.2,1)}.stepper-form-body{display:flex;flex-direction:column;gap:24px;padding:24px}.step-content{animation:stepFadeIn .3s ease-out}@keyframes stepFadeIn{0%{opacity:0;transform:translate(12px)}to{opacity:1;transform:translate(0)}}.step-fields{display:grid;grid-template-columns:1fr;gap:20px}.step-error-summary{display:flex;align-items:center;gap:10px;padding:12px 16px;background:#f43f5e14;border:1px solid rgba(244,63,94,.25);border-radius:10px;margin-top:8px;animation:stepFadeIn .2s ease-out}.error-summary-icon{width:18px;height:18px;fill:#f43f5e;flex-shrink:0}.step-error-summary span{font-size:.8125rem;color:#f43f5e;font-weight:500}.stepper-actions{display:flex;justify-content:space-between;align-items:center;padding-top:8px;border-top:1px solid var(--app-border)}.stepper-actions-left,.stepper-actions-right{display:flex;gap:10px;align-items:center}.btn-reset{display:flex;align-items:center;gap:6px;background:transparent;color:#ef4444;border:1px solid rgba(239,68,68,.3);padding:10px 20px;border-radius:10px;font-weight:600;font-size:.875rem;cursor:pointer;transition:all .2s}.btn-reset svg{width:16px;height:16px;fill:currentColor}.btn-reset:hover{background:#ef44441a;border-color:#ef444480}.btn-reset:disabled{opacity:.5;cursor:not-allowed}.btn-back{display:flex;align-items:center;gap:6px;background:var(--glass-bg);color:var(--app-text);border:1px solid var(--app-border);padding:10px 20px;border-radius:10px;font-weight:600;font-size:.875rem;cursor:pointer;transition:all .2s}.btn-back svg{width:16px;height:16px;fill:currentColor}.btn-back:hover{background:var(--glass-bg-hover);border-color:var(--glass-border-light)}.btn-back:disabled{opacity:.5;cursor:not-allowed}.btn-skip{background:transparent;color:var(--app-text-muted);border:none;padding:10px 16px;border-radius:10px;font-weight:500;font-size:.8125rem;cursor:pointer;transition:color .2s}.btn-skip:hover{color:var(--app-primary)}.btn-skip:disabled{opacity:.5;cursor:not-allowed}.btn-next{display:flex;align-items:center;gap:6px;background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff;border:none;padding:10px 24px;border-radius:10px;font-weight:600;font-size:.875rem;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1)}.btn-next svg{width:16px;height:16px;fill:currentColor}.btn-next:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 24px -4px var(--app-glow)}.btn-next:disabled{opacity:.5;cursor:not-allowed;transform:none}.btn-submit{display:flex;align-items:center;gap:6px;background:linear-gradient(135deg,#22c55e,#16a34a);color:#fff;border:none;padding:10px 28px;border-radius:10px;font-weight:600;font-size:.875rem;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1)}.btn-submit svg{width:16px;height:16px;fill:currentColor}.btn-submit:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 24px -4px #22c55e59}.btn-submit:disabled{opacity:.5;cursor:not-allowed;transform:none}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: FieldRendererComponent, selector: "amf-field-renderer", inputs: ["field", "form", "formDisabled", "actionDispatcher", "context"] }] });
|
|
4152
4152
|
}
|
|
4153
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
4153
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: StepperFormRendererComponent, decorators: [{
|
|
4154
4154
|
type: Component,
|
|
4155
|
-
args: [{ selector: 'amf-stepper-form-renderer', standalone: true, imports: [ReactiveFormsModule, FieldRendererComponent], template: `
|
|
4156
|
-
<div class="amf-stepper" [class]="config.cssClass" [class.stepper-disabled]="config.disabled">
|
|
4157
|
-
|
|
4158
|
-
<!-- ─── Step Header ──────────────────────────────────── -->
|
|
4159
|
-
<div class="stepper-header">
|
|
4160
|
-
@for (step of resolvedSteps(); track $index) {
|
|
4161
|
-
<div class="step-item"
|
|
4162
|
-
[class.active]="$index === currentStep()"
|
|
4163
|
-
[class.completed]="isCompleted($index)"
|
|
4164
|
-
[class.skipped]="isSkipped($index)"
|
|
4165
|
-
[class.navigable]="canNavigateTo($index)"
|
|
4166
|
-
(click)="canNavigateTo($index) && goToStep($index)">
|
|
4167
|
-
<div class="step-indicator">
|
|
4168
|
-
@if (isCompleted($index)) {
|
|
4169
|
-
<svg class="check-icon" viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
|
|
4170
|
-
} @else if (isSkipped($index)) {
|
|
4171
|
-
<svg class="skip-icon" viewBox="0 0 24 24"><path d="M6 18l8.5-6L6 6v12zm2-8.14L11.03 12 8 14.14V9.86zM16 6h2v12h-2z"/></svg>
|
|
4172
|
-
} @else {
|
|
4173
|
-
<span class="step-number">{{ $index + 1 }}</span>
|
|
4174
|
-
}
|
|
4175
|
-
</div>
|
|
4176
|
-
<div class="step-label-group">
|
|
4177
|
-
<span class="step-title">{{ step.title }}</span>
|
|
4178
|
-
@if (step.description) { <span class="step-description">{{ step.description }}</span> }
|
|
4179
|
-
</div>
|
|
4180
|
-
@if ($index < resolvedSteps().length - 1) {
|
|
4181
|
-
<div class="step-connector" [class.completed]="isCompleted($index)"></div>
|
|
4182
|
-
}
|
|
4183
|
-
</div>
|
|
4184
|
-
}
|
|
4185
|
-
</div>
|
|
4186
|
-
|
|
4187
|
-
<!-- ─── Mobile Progress Bar ───────────────────────────── -->
|
|
4188
|
-
<div class="stepper-progress-mobile">
|
|
4189
|
-
<span class="progress-label">Step {{ currentStep() + 1 }} of {{ resolvedSteps().length }}: {{ resolvedSteps()[currentStep()]?.title }}</span>
|
|
4190
|
-
<div class="progress-bar-track">
|
|
4191
|
-
<div class="progress-bar-fill" [style.width.%]="progressPercent()"></div>
|
|
4192
|
-
</div>
|
|
4193
|
-
</div>
|
|
4194
|
-
|
|
4195
|
-
<!-- ─── Step Content ─────────────────────────────────── -->
|
|
4196
|
-
<form [formGroup]="formGroup" (ngSubmit)="onSubmit()" class="stepper-form-body">
|
|
4197
|
-
<div class="step-content">
|
|
4198
|
-
<div class="step-fields" [style.grid-template-columns]="currentGridColumns()">
|
|
4199
|
-
@for (field of currentStepVisibleFields(); track field.key) {
|
|
4200
|
-
<amf-field-renderer
|
|
4201
|
-
[field]="field"
|
|
4202
|
-
[form]="formGroup"
|
|
4203
|
-
[formDisabled]="!!config.disabled"
|
|
4204
|
-
[actionDispatcher]="actionDispatcher"
|
|
4205
|
-
[context]="context"
|
|
4206
|
-
[style.grid-column]="field.colSpan ? 'span ' + field.colSpan : null">
|
|
4207
|
-
</amf-field-renderer>
|
|
4208
|
-
}
|
|
4209
|
-
</div>
|
|
4210
|
-
|
|
4211
|
-
<!-- Step-level validation error summary -->
|
|
4212
|
-
@if (stepErrors().length) {
|
|
4213
|
-
<div class="step-error-summary">
|
|
4214
|
-
<svg viewBox="0 0 24 24" class="error-summary-icon"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/></svg>
|
|
4215
|
-
<span>Please fix {{ stepErrors().length }} error{{ stepErrors().length > 1 ? 's' : '' }} before continuing.</span>
|
|
4216
|
-
</div>
|
|
4217
|
-
}
|
|
4218
|
-
</div>
|
|
4219
|
-
|
|
4220
|
-
<!-- ─── Navigation Actions ────────────────────────────── -->
|
|
4221
|
-
<div class="stepper-actions">
|
|
4222
|
-
<div class="stepper-actions-left">
|
|
4223
|
-
@if (config.showReset) {
|
|
4224
|
-
<button type="button" class="btn-reset" (click)="resetForm()" [disabled]="config.disabled">
|
|
4225
|
-
<svg viewBox="0 0 24 24"><path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/></svg>
|
|
4226
|
-
{{ config.resetLabel || 'Start Over' }}
|
|
4227
|
-
</button>
|
|
4228
|
-
}
|
|
4229
|
-
@if (currentStep() > 0) {
|
|
4230
|
-
<button type="button" class="btn-back" (click)="goBack()" [disabled]="config.disabled">
|
|
4231
|
-
<svg viewBox="0 0 24 24"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></svg>
|
|
4232
|
-
Back
|
|
4233
|
-
</button>
|
|
4234
|
-
}
|
|
4235
|
-
</div>
|
|
4236
|
-
<div class="stepper-actions-right">
|
|
4237
|
-
@if (resolvedSteps()[currentStep()]?.optional) {
|
|
4238
|
-
<button type="button" class="btn-skip" (click)="skipStep()" [disabled]="config.disabled">Skip</button>
|
|
4239
|
-
}
|
|
4240
|
-
@if (currentStep() < resolvedSteps().length - 1) {
|
|
4241
|
-
<button type="button" class="btn-next" (click)="goNext()" [disabled]="config.disabled">
|
|
4242
|
-
{{ resolvedSteps()[currentStep() + 1] ? 'Next' : 'Review' }}
|
|
4243
|
-
<svg viewBox="0 0 24 24"><path d="M4 11v2h12l-5.59 5.59L12 20l8-8-8-8-1.41 1.41L16 11H4z"/></svg>
|
|
4244
|
-
</button>
|
|
4245
|
-
} @else {
|
|
4246
|
-
@if (!config.hideSubmit) {
|
|
4247
|
-
<button type="submit" class="btn-submit" [disabled]="formGroup.invalid || config.disabled">
|
|
4248
|
-
{{ config.submitLabel || 'Submit' }}
|
|
4249
|
-
<svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
|
|
4250
|
-
</button>
|
|
4251
|
-
}
|
|
4252
|
-
}
|
|
4253
|
-
</div>
|
|
4254
|
-
</div>
|
|
4255
|
-
</form>
|
|
4256
|
-
</div>
|
|
4155
|
+
args: [{ selector: 'amf-stepper-form-renderer', standalone: true, imports: [ReactiveFormsModule, FieldRendererComponent], template: `
|
|
4156
|
+
<div class="amf-stepper" [class]="config.cssClass" [class.stepper-disabled]="config.disabled">
|
|
4157
|
+
|
|
4158
|
+
<!-- ─── Step Header ──────────────────────────────────── -->
|
|
4159
|
+
<div class="stepper-header">
|
|
4160
|
+
@for (step of resolvedSteps(); track $index) {
|
|
4161
|
+
<div class="step-item"
|
|
4162
|
+
[class.active]="$index === currentStep()"
|
|
4163
|
+
[class.completed]="isCompleted($index)"
|
|
4164
|
+
[class.skipped]="isSkipped($index)"
|
|
4165
|
+
[class.navigable]="canNavigateTo($index)"
|
|
4166
|
+
(click)="canNavigateTo($index) && goToStep($index)">
|
|
4167
|
+
<div class="step-indicator">
|
|
4168
|
+
@if (isCompleted($index)) {
|
|
4169
|
+
<svg class="check-icon" viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
|
|
4170
|
+
} @else if (isSkipped($index)) {
|
|
4171
|
+
<svg class="skip-icon" viewBox="0 0 24 24"><path d="M6 18l8.5-6L6 6v12zm2-8.14L11.03 12 8 14.14V9.86zM16 6h2v12h-2z"/></svg>
|
|
4172
|
+
} @else {
|
|
4173
|
+
<span class="step-number">{{ $index + 1 }}</span>
|
|
4174
|
+
}
|
|
4175
|
+
</div>
|
|
4176
|
+
<div class="step-label-group">
|
|
4177
|
+
<span class="step-title">{{ step.title }}</span>
|
|
4178
|
+
@if (step.description) { <span class="step-description">{{ step.description }}</span> }
|
|
4179
|
+
</div>
|
|
4180
|
+
@if ($index < resolvedSteps().length - 1) {
|
|
4181
|
+
<div class="step-connector" [class.completed]="isCompleted($index)"></div>
|
|
4182
|
+
}
|
|
4183
|
+
</div>
|
|
4184
|
+
}
|
|
4185
|
+
</div>
|
|
4186
|
+
|
|
4187
|
+
<!-- ─── Mobile Progress Bar ───────────────────────────── -->
|
|
4188
|
+
<div class="stepper-progress-mobile">
|
|
4189
|
+
<span class="progress-label">Step {{ currentStep() + 1 }} of {{ resolvedSteps().length }}: {{ resolvedSteps()[currentStep()]?.title }}</span>
|
|
4190
|
+
<div class="progress-bar-track">
|
|
4191
|
+
<div class="progress-bar-fill" [style.width.%]="progressPercent()"></div>
|
|
4192
|
+
</div>
|
|
4193
|
+
</div>
|
|
4194
|
+
|
|
4195
|
+
<!-- ─── Step Content ─────────────────────────────────── -->
|
|
4196
|
+
<form [formGroup]="formGroup" (ngSubmit)="onSubmit()" class="stepper-form-body">
|
|
4197
|
+
<div class="step-content">
|
|
4198
|
+
<div class="step-fields" [style.grid-template-columns]="currentGridColumns()">
|
|
4199
|
+
@for (field of currentStepVisibleFields(); track field.key) {
|
|
4200
|
+
<amf-field-renderer
|
|
4201
|
+
[field]="field"
|
|
4202
|
+
[form]="formGroup"
|
|
4203
|
+
[formDisabled]="!!config.disabled"
|
|
4204
|
+
[actionDispatcher]="actionDispatcher"
|
|
4205
|
+
[context]="context"
|
|
4206
|
+
[style.grid-column]="field.colSpan ? 'span ' + field.colSpan : null">
|
|
4207
|
+
</amf-field-renderer>
|
|
4208
|
+
}
|
|
4209
|
+
</div>
|
|
4210
|
+
|
|
4211
|
+
<!-- Step-level validation error summary -->
|
|
4212
|
+
@if (stepErrors().length) {
|
|
4213
|
+
<div class="step-error-summary">
|
|
4214
|
+
<svg viewBox="0 0 24 24" class="error-summary-icon"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/></svg>
|
|
4215
|
+
<span>Please fix {{ stepErrors().length }} error{{ stepErrors().length > 1 ? 's' : '' }} before continuing.</span>
|
|
4216
|
+
</div>
|
|
4217
|
+
}
|
|
4218
|
+
</div>
|
|
4219
|
+
|
|
4220
|
+
<!-- ─── Navigation Actions ────────────────────────────── -->
|
|
4221
|
+
<div class="stepper-actions">
|
|
4222
|
+
<div class="stepper-actions-left">
|
|
4223
|
+
@if (config.showReset) {
|
|
4224
|
+
<button type="button" class="btn-reset" (click)="resetForm()" [disabled]="config.disabled">
|
|
4225
|
+
<svg viewBox="0 0 24 24"><path d="M12 5V1L7 6l5 5V7c3.31 0 6 2.69 6 6s-2.69 6-6 6-6-2.69-6-6H4c0 4.42 3.58 8 8 8s8-3.58 8-8-3.58-8-8-8z"/></svg>
|
|
4226
|
+
{{ config.resetLabel || 'Start Over' }}
|
|
4227
|
+
</button>
|
|
4228
|
+
}
|
|
4229
|
+
@if (currentStep() > 0) {
|
|
4230
|
+
<button type="button" class="btn-back" (click)="goBack()" [disabled]="config.disabled">
|
|
4231
|
+
<svg viewBox="0 0 24 24"><path d="M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"/></svg>
|
|
4232
|
+
Back
|
|
4233
|
+
</button>
|
|
4234
|
+
}
|
|
4235
|
+
</div>
|
|
4236
|
+
<div class="stepper-actions-right">
|
|
4237
|
+
@if (resolvedSteps()[currentStep()]?.optional) {
|
|
4238
|
+
<button type="button" class="btn-skip" (click)="skipStep()" [disabled]="config.disabled">Skip</button>
|
|
4239
|
+
}
|
|
4240
|
+
@if (currentStep() < resolvedSteps().length - 1) {
|
|
4241
|
+
<button type="button" class="btn-next" (click)="goNext()" [disabled]="config.disabled">
|
|
4242
|
+
{{ resolvedSteps()[currentStep() + 1] ? 'Next' : 'Review' }}
|
|
4243
|
+
<svg viewBox="0 0 24 24"><path d="M4 11v2h12l-5.59 5.59L12 20l8-8-8-8-1.41 1.41L16 11H4z"/></svg>
|
|
4244
|
+
</button>
|
|
4245
|
+
} @else {
|
|
4246
|
+
@if (!config.hideSubmit) {
|
|
4247
|
+
<button type="submit" class="btn-submit" [disabled]="formGroup.invalid || config.disabled">
|
|
4248
|
+
{{ config.submitLabel || 'Submit' }}
|
|
4249
|
+
<svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
|
|
4250
|
+
</button>
|
|
4251
|
+
}
|
|
4252
|
+
}
|
|
4253
|
+
</div>
|
|
4254
|
+
</div>
|
|
4255
|
+
</form>
|
|
4256
|
+
</div>
|
|
4257
4257
|
`, styles: [".amf-stepper{display:flex;flex-direction:column;gap:0}.amf-stepper.stepper-disabled{opacity:.6;pointer-events:none}.stepper-header{display:flex;align-items:flex-start;gap:0;padding:20px 24px 0;overflow-x:auto;scrollbar-width:none}.stepper-header::-webkit-scrollbar{display:none}.step-item{display:flex;align-items:center;flex:1;min-width:0;cursor:default;position:relative}.step-item.navigable{cursor:pointer}.step-item.navigable:hover .step-indicator{border-color:var(--app-primary)}.step-item.navigable:hover .step-title{color:var(--app-text)}.step-indicator{flex-shrink:0;width:36px;height:36px;border-radius:50%;border:2px solid var(--app-border);background:var(--app-surface);display:flex;align-items:center;justify-content:center;transition:all .35s cubic-bezier(.4,0,.2,1);position:relative;z-index:1}.step-item.active .step-indicator{border-color:var(--app-primary);background:var(--app-primary);box-shadow:0 0 0 4px rgba(var(--app-primary-rgb, 99 102 241),.18)}.step-item.completed .step-indicator{border-color:#22c55e;background:#22c55e}.step-item.skipped .step-indicator{border-color:var(--app-text-muted);background:var(--glass-bg)}.step-number{font-size:.8125rem;font-weight:700;color:var(--app-text-muted)}.step-item.active .step-number{color:#fff}.check-icon,.skip-icon{width:18px;height:18px;fill:#fff}.skip-icon{fill:var(--app-text-muted)}.step-label-group{display:flex;flex-direction:column;margin-left:10px;min-width:0;flex-shrink:0}.step-title{font-size:.8125rem;font-weight:600;color:var(--app-text-muted);white-space:nowrap;transition:color .2s}.step-item.active .step-title{color:var(--app-text)}.step-item.completed .step-title{color:var(--app-text-muted)}.step-description{font-size:.6875rem;color:var(--app-text-muted);opacity:.7;white-space:nowrap;margin-top:1px}.step-connector{flex:1;height:2px;background:var(--app-border);margin:0 10px 14px;border-radius:1px;transition:background .4s ease;align-self:center}.step-connector.completed{background:linear-gradient(90deg,#22c55e,var(--app-primary))}.stepper-progress-mobile{display:none;flex-direction:column;gap:8px;padding:16px 24px 0}@media(max-width:640px){.stepper-header{display:none}.stepper-progress-mobile{display:flex}}.progress-label{font-size:.8125rem;font-weight:600;color:var(--app-text)}.progress-bar-track{width:100%;height:6px;background:var(--app-border);border-radius:3px;overflow:hidden}.progress-bar-fill{height:100%;background:linear-gradient(90deg,var(--app-primary),var(--app-accent));border-radius:3px;transition:width .4s cubic-bezier(.4,0,.2,1)}.stepper-form-body{display:flex;flex-direction:column;gap:24px;padding:24px}.step-content{animation:stepFadeIn .3s ease-out}@keyframes stepFadeIn{0%{opacity:0;transform:translate(12px)}to{opacity:1;transform:translate(0)}}.step-fields{display:grid;grid-template-columns:1fr;gap:20px}.step-error-summary{display:flex;align-items:center;gap:10px;padding:12px 16px;background:#f43f5e14;border:1px solid rgba(244,63,94,.25);border-radius:10px;margin-top:8px;animation:stepFadeIn .2s ease-out}.error-summary-icon{width:18px;height:18px;fill:#f43f5e;flex-shrink:0}.step-error-summary span{font-size:.8125rem;color:#f43f5e;font-weight:500}.stepper-actions{display:flex;justify-content:space-between;align-items:center;padding-top:8px;border-top:1px solid var(--app-border)}.stepper-actions-left,.stepper-actions-right{display:flex;gap:10px;align-items:center}.btn-reset{display:flex;align-items:center;gap:6px;background:transparent;color:#ef4444;border:1px solid rgba(239,68,68,.3);padding:10px 20px;border-radius:10px;font-weight:600;font-size:.875rem;cursor:pointer;transition:all .2s}.btn-reset svg{width:16px;height:16px;fill:currentColor}.btn-reset:hover{background:#ef44441a;border-color:#ef444480}.btn-reset:disabled{opacity:.5;cursor:not-allowed}.btn-back{display:flex;align-items:center;gap:6px;background:var(--glass-bg);color:var(--app-text);border:1px solid var(--app-border);padding:10px 20px;border-radius:10px;font-weight:600;font-size:.875rem;cursor:pointer;transition:all .2s}.btn-back svg{width:16px;height:16px;fill:currentColor}.btn-back:hover{background:var(--glass-bg-hover);border-color:var(--glass-border-light)}.btn-back:disabled{opacity:.5;cursor:not-allowed}.btn-skip{background:transparent;color:var(--app-text-muted);border:none;padding:10px 16px;border-radius:10px;font-weight:500;font-size:.8125rem;cursor:pointer;transition:color .2s}.btn-skip:hover{color:var(--app-primary)}.btn-skip:disabled{opacity:.5;cursor:not-allowed}.btn-next{display:flex;align-items:center;gap:6px;background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff;border:none;padding:10px 24px;border-radius:10px;font-weight:600;font-size:.875rem;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1)}.btn-next svg{width:16px;height:16px;fill:currentColor}.btn-next:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 24px -4px var(--app-glow)}.btn-next:disabled{opacity:.5;cursor:not-allowed;transform:none}.btn-submit{display:flex;align-items:center;gap:6px;background:linear-gradient(135deg,#22c55e,#16a34a);color:#fff;border:none;padding:10px 28px;border-radius:10px;font-weight:600;font-size:.875rem;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1)}.btn-submit svg{width:16px;height:16px;fill:currentColor}.btn-submit:hover:not(:disabled){transform:translateY(-2px);box-shadow:0 8px 24px -4px #22c55e59}.btn-submit:disabled{opacity:.5;cursor:not-allowed;transform:none}\n"] }]
|
|
4258
4258
|
}], propDecorators: { config: [{
|
|
4259
4259
|
type: Input
|
|
@@ -4285,61 +4285,61 @@ class CellRendererComponent {
|
|
|
4285
4285
|
return '';
|
|
4286
4286
|
return path.split('.').reduce((c, k) => c?.[k], obj) ?? '';
|
|
4287
4287
|
}
|
|
4288
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
4289
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
4290
|
-
@switch (column.type || 'text') {
|
|
4291
|
-
@case ('badge') { <span class="cell-badge" [class]="getBadgeClass()">{{ value | titlecase }}</span> }
|
|
4292
|
-
@case ('avatar') {
|
|
4293
|
-
<div class="cell-avatar">
|
|
4294
|
-
<div class="avatar-circle">{{ getInitial() }}</div>
|
|
4295
|
-
<div class="avatar-info">
|
|
4296
|
-
<span class="avatar-name">{{ value }}</span>
|
|
4297
|
-
@if (column.subtitleKey) { <span class="avatar-subtitle">{{ getNestedValue(row, column.subtitleKey) }}</span> }
|
|
4298
|
-
</div>
|
|
4299
|
-
</div>
|
|
4300
|
-
}
|
|
4301
|
-
@case ('date') { <span>{{ value | date:(column.dateFormat || 'mediumDate') }}</span> }
|
|
4302
|
-
@case ('datetime') { <span>{{ value | date:(column.dateFormat || 'medium') }}</span> }
|
|
4303
|
-
@case ('currency') { <span>{{ value | currency:(column.currencyCodeKey ? getNestedValue(row, column.currencyCodeKey) : (column.currencyCode || 'USD')):(column.currencyDisplay !== undefined ? column.currencyDisplay : 'symbol') }}</span> }
|
|
4304
|
-
@case ('boolean') { <span class="cell-boolean" [class.is-true]="value">{{ value ? '✓' : '✗' }}</span> }
|
|
4305
|
-
@case ('number') { <span class="cell-number">{{ value }}</span> }
|
|
4306
|
-
@case ('progress') {
|
|
4307
|
-
<div class="cell-progress">
|
|
4308
|
-
<div class="progress-bar"><div class="progress-fill" [style.width.%]="value"></div></div>
|
|
4309
|
-
<span class="progress-text">{{ value }}%</span>
|
|
4310
|
-
</div>
|
|
4311
|
-
}
|
|
4312
|
-
@default { <span>{{ value }}</span> }
|
|
4313
|
-
}
|
|
4288
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CellRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4289
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: CellRendererComponent, isStandalone: true, selector: "amf-cell-renderer", inputs: { column: "column", row: "row", value: "value" }, ngImport: i0, template: `
|
|
4290
|
+
@switch (column.type || 'text') {
|
|
4291
|
+
@case ('badge') { <span class="cell-badge" [class]="getBadgeClass()">{{ value | titlecase }}</span> }
|
|
4292
|
+
@case ('avatar') {
|
|
4293
|
+
<div class="cell-avatar">
|
|
4294
|
+
<div class="avatar-circle">{{ getInitial() }}</div>
|
|
4295
|
+
<div class="avatar-info">
|
|
4296
|
+
<span class="avatar-name">{{ value }}</span>
|
|
4297
|
+
@if (column.subtitleKey) { <span class="avatar-subtitle">{{ getNestedValue(row, column.subtitleKey) }}</span> }
|
|
4298
|
+
</div>
|
|
4299
|
+
</div>
|
|
4300
|
+
}
|
|
4301
|
+
@case ('date') { <span>{{ value | date:(column.dateFormat || 'mediumDate') }}</span> }
|
|
4302
|
+
@case ('datetime') { <span>{{ value | date:(column.dateFormat || 'medium') }}</span> }
|
|
4303
|
+
@case ('currency') { <span>{{ value | currency:(column.currencyCodeKey ? getNestedValue(row, column.currencyCodeKey) : (column.currencyCode || 'USD')):(column.currencyDisplay !== undefined ? column.currencyDisplay : 'symbol') }}</span> }
|
|
4304
|
+
@case ('boolean') { <span class="cell-boolean" [class.is-true]="value">{{ value ? '✓' : '✗' }}</span> }
|
|
4305
|
+
@case ('number') { <span class="cell-number">{{ value }}</span> }
|
|
4306
|
+
@case ('progress') {
|
|
4307
|
+
<div class="cell-progress">
|
|
4308
|
+
<div class="progress-bar"><div class="progress-fill" [style.width.%]="value"></div></div>
|
|
4309
|
+
<span class="progress-text">{{ value }}%</span>
|
|
4310
|
+
</div>
|
|
4311
|
+
}
|
|
4312
|
+
@default { <span>{{ value }}</span> }
|
|
4313
|
+
}
|
|
4314
4314
|
`, isInline: true, styles: [":host{display:contents}.cell-badge{padding:4px 10px;border-radius:6px;font-size:.75rem;font-weight:600;display:inline-block}.cell-badge.success,.cell-badge.active{background:#34d39926;color:#34d399}.cell-badge.danger,.cell-badge.inactive{background:#f43f5e26;color:#fb7185}.cell-badge.warning,.cell-badge.pending{background:#fbbf2426;color:#fbbf24}.cell-badge.info{background:#3b82f626;color:#60a5fa}.cell-badge.muted{background:var(--glass-bg);color:var(--app-text-muted)}.cell-avatar{display:flex;align-items:center;gap:12px}.avatar-circle{width:34px;height:34px;border-radius:50%;background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.875rem;flex-shrink:0}.avatar-info{display:flex;flex-direction:column}.avatar-name{font-weight:600;color:var(--app-text);font-size:.875rem}.avatar-subtitle{font-size:.75rem;color:var(--app-text-muted)}.cell-boolean{font-weight:700}.cell-boolean.is-true{color:#34d399}.cell-boolean:not(.is-true){color:#fb7185}.cell-number{font-variant-numeric:tabular-nums}.cell-progress{display:flex;align-items:center;gap:8px}.progress-bar{flex:1;height:6px;background:var(--glass-bg);border-radius:3px;overflow:hidden}.progress-fill{height:100%;background:linear-gradient(90deg,var(--app-primary),var(--app-accent));border-radius:3px;transition:width .3s}.progress-text{font-size:.75rem;color:var(--app-text-muted);min-width:36px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1$1.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i1$1.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i1$1.DatePipe, name: "date" }] });
|
|
4315
4315
|
}
|
|
4316
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
4316
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CellRendererComponent, decorators: [{
|
|
4317
4317
|
type: Component,
|
|
4318
|
-
args: [{ selector: 'amf-cell-renderer', standalone: true, imports: [CommonModule, TitleCasePipe, DatePipe, CurrencyPipe], template: `
|
|
4319
|
-
@switch (column.type || 'text') {
|
|
4320
|
-
@case ('badge') { <span class="cell-badge" [class]="getBadgeClass()">{{ value | titlecase }}</span> }
|
|
4321
|
-
@case ('avatar') {
|
|
4322
|
-
<div class="cell-avatar">
|
|
4323
|
-
<div class="avatar-circle">{{ getInitial() }}</div>
|
|
4324
|
-
<div class="avatar-info">
|
|
4325
|
-
<span class="avatar-name">{{ value }}</span>
|
|
4326
|
-
@if (column.subtitleKey) { <span class="avatar-subtitle">{{ getNestedValue(row, column.subtitleKey) }}</span> }
|
|
4327
|
-
</div>
|
|
4328
|
-
</div>
|
|
4329
|
-
}
|
|
4330
|
-
@case ('date') { <span>{{ value | date:(column.dateFormat || 'mediumDate') }}</span> }
|
|
4331
|
-
@case ('datetime') { <span>{{ value | date:(column.dateFormat || 'medium') }}</span> }
|
|
4332
|
-
@case ('currency') { <span>{{ value | currency:(column.currencyCodeKey ? getNestedValue(row, column.currencyCodeKey) : (column.currencyCode || 'USD')):(column.currencyDisplay !== undefined ? column.currencyDisplay : 'symbol') }}</span> }
|
|
4333
|
-
@case ('boolean') { <span class="cell-boolean" [class.is-true]="value">{{ value ? '✓' : '✗' }}</span> }
|
|
4334
|
-
@case ('number') { <span class="cell-number">{{ value }}</span> }
|
|
4335
|
-
@case ('progress') {
|
|
4336
|
-
<div class="cell-progress">
|
|
4337
|
-
<div class="progress-bar"><div class="progress-fill" [style.width.%]="value"></div></div>
|
|
4338
|
-
<span class="progress-text">{{ value }}%</span>
|
|
4339
|
-
</div>
|
|
4340
|
-
}
|
|
4341
|
-
@default { <span>{{ value }}</span> }
|
|
4342
|
-
}
|
|
4318
|
+
args: [{ selector: 'amf-cell-renderer', standalone: true, imports: [CommonModule, TitleCasePipe, DatePipe, CurrencyPipe], template: `
|
|
4319
|
+
@switch (column.type || 'text') {
|
|
4320
|
+
@case ('badge') { <span class="cell-badge" [class]="getBadgeClass()">{{ value | titlecase }}</span> }
|
|
4321
|
+
@case ('avatar') {
|
|
4322
|
+
<div class="cell-avatar">
|
|
4323
|
+
<div class="avatar-circle">{{ getInitial() }}</div>
|
|
4324
|
+
<div class="avatar-info">
|
|
4325
|
+
<span class="avatar-name">{{ value }}</span>
|
|
4326
|
+
@if (column.subtitleKey) { <span class="avatar-subtitle">{{ getNestedValue(row, column.subtitleKey) }}</span> }
|
|
4327
|
+
</div>
|
|
4328
|
+
</div>
|
|
4329
|
+
}
|
|
4330
|
+
@case ('date') { <span>{{ value | date:(column.dateFormat || 'mediumDate') }}</span> }
|
|
4331
|
+
@case ('datetime') { <span>{{ value | date:(column.dateFormat || 'medium') }}</span> }
|
|
4332
|
+
@case ('currency') { <span>{{ value | currency:(column.currencyCodeKey ? getNestedValue(row, column.currencyCodeKey) : (column.currencyCode || 'USD')):(column.currencyDisplay !== undefined ? column.currencyDisplay : 'symbol') }}</span> }
|
|
4333
|
+
@case ('boolean') { <span class="cell-boolean" [class.is-true]="value">{{ value ? '✓' : '✗' }}</span> }
|
|
4334
|
+
@case ('number') { <span class="cell-number">{{ value }}</span> }
|
|
4335
|
+
@case ('progress') {
|
|
4336
|
+
<div class="cell-progress">
|
|
4337
|
+
<div class="progress-bar"><div class="progress-fill" [style.width.%]="value"></div></div>
|
|
4338
|
+
<span class="progress-text">{{ value }}%</span>
|
|
4339
|
+
</div>
|
|
4340
|
+
}
|
|
4341
|
+
@default { <span>{{ value }}</span> }
|
|
4342
|
+
}
|
|
4343
4343
|
`, styles: [":host{display:contents}.cell-badge{padding:4px 10px;border-radius:6px;font-size:.75rem;font-weight:600;display:inline-block}.cell-badge.success,.cell-badge.active{background:#34d39926;color:#34d399}.cell-badge.danger,.cell-badge.inactive{background:#f43f5e26;color:#fb7185}.cell-badge.warning,.cell-badge.pending{background:#fbbf2426;color:#fbbf24}.cell-badge.info{background:#3b82f626;color:#60a5fa}.cell-badge.muted{background:var(--glass-bg);color:var(--app-text-muted)}.cell-avatar{display:flex;align-items:center;gap:12px}.avatar-circle{width:34px;height:34px;border-radius:50%;background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.875rem;flex-shrink:0}.avatar-info{display:flex;flex-direction:column}.avatar-name{font-weight:600;color:var(--app-text);font-size:.875rem}.avatar-subtitle{font-size:.75rem;color:var(--app-text-muted)}.cell-boolean{font-weight:700}.cell-boolean.is-true{color:#34d399}.cell-boolean:not(.is-true){color:#fb7185}.cell-number{font-variant-numeric:tabular-nums}.cell-progress{display:flex;align-items:center;gap:8px}.progress-bar{flex:1;height:6px;background:var(--glass-bg);border-radius:3px;overflow:hidden}.progress-fill{height:100%;background:linear-gradient(90deg,var(--app-primary),var(--app-accent));border-radius:3px;transition:width .3s}.progress-text{font-size:.75rem;color:var(--app-text-muted);min-width:36px}\n"] }]
|
|
4344
4344
|
}], propDecorators: { column: [{
|
|
4345
4345
|
type: Input
|
|
@@ -4776,405 +4776,405 @@ class TableRendererComponent {
|
|
|
4776
4776
|
this.actionDispatcher.dispatch(this.config.onReorder, { ...this.context, previousIndex: event.previousIndex, currentIndex: event.currentIndex });
|
|
4777
4777
|
}
|
|
4778
4778
|
}
|
|
4779
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
4780
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
4781
|
-
<div class="amf-table-card" [class]="'variant-' + (config.variant || 'default') + ' ' + (config.cssClass || '')">
|
|
4782
|
-
<div class="table-header">
|
|
4783
|
-
<div class="table-header-left">
|
|
4784
|
-
@if (config.searchable) {
|
|
4785
|
-
<div class="search-box">
|
|
4786
|
-
<svg viewBox="0 0 24 24" class="search-icon"><path [attr.d]="iconRegistry.getIcon('search')"></path></svg>
|
|
4787
|
-
<input type="text" [placeholder]="config.searchPlaceholder || 'Search...'" [ngModel]="searchQuery()" (ngModelChange)="searchQuery.set($event)" />
|
|
4788
|
-
</div>
|
|
4789
|
-
}
|
|
4790
|
-
@for (filter of config.filters || []; track filter.key) {
|
|
4791
|
-
<select class="filter-select" [ngModel]="getFilterValue(filter.key)" (ngModelChange)="setFilterValue(filter.key, $event)">
|
|
4792
|
-
<option value="">{{ filter.label }}</option>
|
|
4793
|
-
@for (opt of filter.options; track opt.value) { <option [value]="opt.value">{{ opt.label }}</option> }
|
|
4794
|
-
</select>
|
|
4795
|
-
}
|
|
4796
|
-
</div>
|
|
4797
|
-
<div class="table-header-right">
|
|
4798
|
-
@for (action of config.headerActions || []; track action.id) {
|
|
4799
|
-
<button class="btn-primary btn-sm" (click)="handleAction(action, null)">
|
|
4800
|
-
@if (action.icon) { <svg viewBox="0 0 24 24" class="btn-icon"><path [attr.d]="iconRegistry.getIcon(action.icon)"></path></svg> }
|
|
4801
|
-
{{ action.label }}
|
|
4802
|
-
</button>
|
|
4803
|
-
}
|
|
4804
|
-
|
|
4805
|
-
@if (config.exportable) {
|
|
4806
|
-
<div class="export-container">
|
|
4807
|
-
<button class="btn-ghost btn-sm" (click)="exportMenuOpen.set(!exportMenuOpen())">
|
|
4808
|
-
<svg viewBox="0 0 24 24" class="btn-icon"><path [attr.d]="iconRegistry.getIcon('download')"></path></svg>
|
|
4809
|
-
Export
|
|
4810
|
-
</button>
|
|
4811
|
-
@if (exportMenuOpen()) {
|
|
4812
|
-
<div class="dropdown-menu export-menu">
|
|
4813
|
-
@for (format of config.exportFormats || ['csv', 'json']; track format) {
|
|
4814
|
-
<div class="dropdown-item" (click)="exportData(format); exportMenuOpen.set(false)">
|
|
4815
|
-
Export as {{ format | uppercase }}
|
|
4816
|
-
</div>
|
|
4817
|
-
}
|
|
4818
|
-
</div>
|
|
4819
|
-
}
|
|
4820
|
-
</div>
|
|
4821
|
-
}
|
|
4822
|
-
</div>
|
|
4823
|
-
</div>
|
|
4824
|
-
<div class="table-wrapper">
|
|
4825
|
-
<table class="data-table" [class.striped]="config.striped" [class.hoverable]="config.hoverable !== false">
|
|
4826
|
-
<thead>
|
|
4827
|
-
<tr cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropColumn($event)">
|
|
4828
|
-
@if (config.reorderable) { <th class="drag-col" style="width: 40px; text-align: center;"></th> }
|
|
4829
|
-
@if (config.selectionMode === 'checkbox') {
|
|
4830
|
-
<th class="selection-col" style="width: 40px; text-align: center;">
|
|
4831
|
-
@if (config.showSelectAll !== false) {
|
|
4832
|
-
<input type="checkbox"
|
|
4833
|
-
class="amf-checkbox"
|
|
4834
|
-
[checked]="selectedRows().size > 0 && selectedRows().size === filteredData().length"
|
|
4835
|
-
(change)="toggleAllSelection($event)" />
|
|
4836
|
-
}
|
|
4837
|
-
</th>
|
|
4838
|
-
}
|
|
4839
|
-
@if (config.expandable) {
|
|
4840
|
-
<th style="width: 36px;"></th>
|
|
4841
|
-
}
|
|
4842
|
-
@for (col of visibleColumns(); track col.key) {
|
|
4843
|
-
<th cdkDrag [cdkDragDisabled]="!config.columnReorder" [style.width]="col.width" [style.min-width]="col.minWidth" [style.text-align]="col.align || 'left'" [class.sortable]="col.sortable" (click)="col.sortable ? toggleSort(col.key) : null">
|
|
4844
|
-
{{ col.label }} @if (col.sortable && sortKey() === col.key) { <span class="sort-indicator">{{ sortDirection() === 'asc' ? '↑' : '↓' }}</span> }
|
|
4845
|
-
</th>
|
|
4846
|
-
}
|
|
4847
|
-
@if (config.actions?.length) { <th class="actions-col">Actions</th> }
|
|
4848
|
-
</tr>
|
|
4849
|
-
</thead>
|
|
4850
|
-
<tbody cdkDropList (cdkDropListDropped)="dropRow($event)">
|
|
4851
|
-
@for (row of groupedRows(); track $index) {
|
|
4852
|
-
@if (row.__isGroupHeader) {
|
|
4853
|
-
<tr class="group-header-row">
|
|
4854
|
-
<td [attr.colspan]="visibleColumns().length + (config.reorderable ? 1 : 0) + (config.selectionMode === 'checkbox' ? 1 : 0) + (config.expandable ? 1 : 0) + (config.actions?.length ? 1 : 0)">
|
|
4855
|
-
<button class="group-toggle" (click)="toggleGroup(row.__groupKey)">
|
|
4856
|
-
<span class="group-chevron" [class.open]="!collapsedGroups().has(row.__groupKey)">▶</span>
|
|
4857
|
-
{{ config.groupBy }}: <strong>{{ row.__groupKey }}</strong>
|
|
4858
|
-
<span class="group-count">({{ row.__count }} items)</span>
|
|
4859
|
-
</button>
|
|
4860
|
-
</td>
|
|
4861
|
-
</tr>
|
|
4862
|
-
} @else {
|
|
4863
|
-
<tr cdkDrag [cdkDragDisabled]="!config.reorderable" (click)="handleRowClick(row)" [class.clickable]="config.rowClick || config.selectionMode === 'single' || config.selectionMode === 'multi'" [class.selected]="selectedRows().has(row)" [class.expanded]="expandedRows().has(row)">
|
|
4864
|
-
@if (config.reorderable) {
|
|
4865
|
-
<td class="drag-cell" (click)="$event.stopPropagation()" cdkDragHandle>
|
|
4866
|
-
<svg viewBox="0 0 24 24" style="width:16px;height:16px;fill:var(--app-text-muted)"><path [attr.d]="iconRegistry.getIcon('menu')"></path></svg>
|
|
4867
|
-
</td>
|
|
4868
|
-
}
|
|
4869
|
-
@if (config.selectionMode === 'checkbox') {
|
|
4870
|
-
<td class="selection-cell" (click)="$event.stopPropagation(); toggleSelection(row)">
|
|
4871
|
-
<input type="checkbox" class="amf-checkbox" [checked]="selectedRows().has(row)" (click)="$event.stopPropagation()" (change)="$event.stopPropagation(); toggleSelection(row)" />
|
|
4872
|
-
</td>
|
|
4873
|
-
}
|
|
4874
|
-
@if (config.expandable) {
|
|
4875
|
-
<td class="expand-cell" (click)="$event.stopPropagation(); toggleRowExpand(row)">
|
|
4876
|
-
<span class="expand-chevron" [class.open]="expandedRows().has(row)">▶</span>
|
|
4877
|
-
</td>
|
|
4878
|
-
}
|
|
4879
|
-
@for (col of visibleColumns(); track col.key) {
|
|
4880
|
-
<td [style.text-align]="col.align || 'left'" (dblclick)="config.inlineEdit && col.editable !== false ? startEdit(row, col.key, $event) : null" [class.editable-cell]="config.inlineEdit && col.editable !== false">
|
|
4881
|
-
@if (isEditing(row, col.key)) {
|
|
4882
|
-
<div class="inline-edit-wrap" (click)="$event.stopPropagation()">
|
|
4883
|
-
<div class="inline-edit-row">
|
|
4884
|
-
@if (col.editType === 'select' && col.editOptions) {
|
|
4885
|
-
<select class="inline-input" [(ngModel)]="editBuffer[col.key]">
|
|
4886
|
-
@for (opt of col.editOptions; track opt.value) { <option [value]="opt.value">{{ opt.label }}</option> }
|
|
4887
|
-
</select>
|
|
4888
|
-
} @else {
|
|
4889
|
-
<input class="inline-input" [type]="col.editType || 'text'" [(ngModel)]="editBuffer[col.key]" (keydown.enter)="commitEdit(row, col.key)" (keydown.escape)="cancelEdit()" />
|
|
4890
|
-
}
|
|
4891
|
-
<div class="inline-edit-actions">
|
|
4892
|
-
<button class="ie-btn ie-save" title="Save (Enter)" (click)="commitEdit(row, col.key)">
|
|
4893
|
-
<svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
|
|
4894
|
-
</button>
|
|
4895
|
-
<button class="ie-btn ie-cancel" title="Cancel (Esc)" (click)="cancelEdit()">
|
|
4896
|
-
<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
|
4897
|
-
</button>
|
|
4898
|
-
</div>
|
|
4899
|
-
</div>
|
|
4900
|
-
@if (editError()) {
|
|
4901
|
-
<span class="inline-edit-error">{{ editError() }}</span>
|
|
4902
|
-
}
|
|
4903
|
-
</div>
|
|
4904
|
-
} @else {
|
|
4905
|
-
<amf-cell-renderer [column]="col" [row]="row" [value]="getCellValue(row, col.key)"></amf-cell-renderer>
|
|
4906
|
-
}
|
|
4907
|
-
</td>
|
|
4908
|
-
}
|
|
4909
|
-
@if (config.actions?.length) {
|
|
4910
|
-
<td class="actions-cell">
|
|
4911
|
-
<div class="action-btns">
|
|
4912
|
-
@for (action of config.actions; track action.id) {
|
|
4913
|
-
<button class="action-btn" [class]="action.variant || 'ghost'" [title]="action.label" (click)="handleAction(action, row); $event.stopPropagation()">
|
|
4914
|
-
@if (action.icon) { <svg viewBox="0 0 24 24"><path [attr.d]="iconRegistry.getIcon(action.icon)"></path></svg> } @else { {{ action.label }} }
|
|
4915
|
-
</button>
|
|
4916
|
-
}
|
|
4917
|
-
</div>
|
|
4918
|
-
</td>
|
|
4919
|
-
}
|
|
4920
|
-
</tr>
|
|
4921
|
-
@if (config.expandable && expandedRows().has(row)) {
|
|
4922
|
-
<tr class="expanded-row">
|
|
4923
|
-
<td [attr.colspan]="visibleColumns().length + (config.reorderable ? 1 : 0) + (config.selectionMode === 'checkbox' ? 1 : 0) + 1 + (config.actions?.length ? 1 : 0)" class="expanded-content">
|
|
4924
|
-
@if (config.expandSection) {
|
|
4925
|
-
<div class="expand-section">Row detail: {{ row | json }}</div>
|
|
4926
|
-
} @else {
|
|
4927
|
-
<div class="expand-section">
|
|
4928
|
-
@for (col of visibleColumns(); track col.key) {
|
|
4929
|
-
<div class="expand-field"><span class="expand-label">{{ col.label }}:</span> <span>{{ getCellValue(row, col.key) }}</span></div>
|
|
4930
|
-
}
|
|
4931
|
-
</div>
|
|
4932
|
-
}
|
|
4933
|
-
</td>
|
|
4934
|
-
</tr>
|
|
4935
|
-
}
|
|
4936
|
-
}
|
|
4937
|
-
} @empty { <tr><td [attr.colspan]="visibleColumns().length + (config.actions?.length ? 1 : 0)" class="empty-state">{{ config.emptyMessage || 'No data found.' }}</td></tr> }
|
|
4938
|
-
@if (config.aggregates?.length) {
|
|
4939
|
-
<tr class="aggregate-row">
|
|
4940
|
-
@if (config.reorderable) { <td></td> }
|
|
4941
|
-
@if (config.selectionMode === 'checkbox') { <td></td> }
|
|
4942
|
-
@if (config.expandable) { <td></td> }
|
|
4943
|
-
@for (col of visibleColumns(); track col.key) {
|
|
4944
|
-
<td class="aggregate-cell" [style.text-align]="col.align || 'right'">
|
|
4945
|
-
@if (getAggregate(col.key); as agg) { <span class="agg-value">{{ agg.label ? agg.label + ': ' : '' }}{{ agg.value }}</span> }
|
|
4946
|
-
</td>
|
|
4947
|
-
}
|
|
4948
|
-
@if (config.actions?.length) { <td></td> }
|
|
4949
|
-
</tr>
|
|
4950
|
-
}
|
|
4951
|
-
</tbody>
|
|
4952
|
-
</table>
|
|
4953
|
-
</div>
|
|
4954
|
-
@if (config.pagination?.enabled) {
|
|
4955
|
-
<div class="table-footer">
|
|
4956
|
-
<div class="footer-left">
|
|
4957
|
-
<span class="results-count">Showing {{ paginatedData().length }} of {{ filteredData().length }} @if (config.pagination?.showTotal) { (total: {{ allData().length }}) }</span>
|
|
4958
|
-
@if ((config.pagination?.pageSizeOptions || [5, 10, 25, 50]).length > 1) {
|
|
4959
|
-
<div class="page-size-wrap">
|
|
4960
|
-
<label class="page-size-label">Rows:</label>
|
|
4961
|
-
<select class="page-size-select" [ngModel]="activePageSize()" (ngModelChange)="setPageSize($event)">
|
|
4962
|
-
@for (opt of config.pagination?.pageSizeOptions || [5, 10, 25, 50]; track opt) {
|
|
4963
|
-
<option [value]="opt">{{ opt }}</option>
|
|
4964
|
-
}
|
|
4965
|
-
</select>
|
|
4966
|
-
</div>
|
|
4967
|
-
}
|
|
4968
|
-
</div>
|
|
4969
|
-
<div class="pagination">
|
|
4970
|
-
<button class="btn-page-nav" [disabled]="currentPage() <= 1" (click)="currentPage.set(currentPage() - 1)">Previous</button>
|
|
4971
|
-
@for (p of pageNumbers(); track p) { <button class="btn-page" [class.active]="p === currentPage()" (click)="currentPage.set(p)">{{ p }}</button> }
|
|
4972
|
-
<button class="btn-page-nav" [disabled]="currentPage() >= totalPages()" (click)="currentPage.set(currentPage() + 1)">Next</button>
|
|
4973
|
-
</div>
|
|
4974
|
-
</div>
|
|
4975
|
-
}
|
|
4976
|
-
</div>
|
|
4779
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: TableRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4780
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: TableRendererComponent, isStandalone: true, selector: "amf-table-renderer", inputs: { config: "config", context: "context" }, outputs: { rowAction: "rowAction" }, ngImport: i0, template: `
|
|
4781
|
+
<div class="amf-table-card" [class]="'variant-' + (config.variant || 'default') + ' ' + (config.cssClass || '')">
|
|
4782
|
+
<div class="table-header">
|
|
4783
|
+
<div class="table-header-left">
|
|
4784
|
+
@if (config.searchable) {
|
|
4785
|
+
<div class="search-box">
|
|
4786
|
+
<svg viewBox="0 0 24 24" class="search-icon"><path [attr.d]="iconRegistry.getIcon('search')"></path></svg>
|
|
4787
|
+
<input type="text" [placeholder]="config.searchPlaceholder || 'Search...'" [ngModel]="searchQuery()" (ngModelChange)="searchQuery.set($event)" />
|
|
4788
|
+
</div>
|
|
4789
|
+
}
|
|
4790
|
+
@for (filter of config.filters || []; track filter.key) {
|
|
4791
|
+
<select class="filter-select" [ngModel]="getFilterValue(filter.key)" (ngModelChange)="setFilterValue(filter.key, $event)">
|
|
4792
|
+
<option value="">{{ filter.label }}</option>
|
|
4793
|
+
@for (opt of filter.options; track opt.value) { <option [value]="opt.value">{{ opt.label }}</option> }
|
|
4794
|
+
</select>
|
|
4795
|
+
}
|
|
4796
|
+
</div>
|
|
4797
|
+
<div class="table-header-right">
|
|
4798
|
+
@for (action of config.headerActions || []; track action.id) {
|
|
4799
|
+
<button class="btn-primary btn-sm" (click)="handleAction(action, null)">
|
|
4800
|
+
@if (action.icon) { <svg viewBox="0 0 24 24" class="btn-icon"><path [attr.d]="iconRegistry.getIcon(action.icon)"></path></svg> }
|
|
4801
|
+
{{ action.label }}
|
|
4802
|
+
</button>
|
|
4803
|
+
}
|
|
4804
|
+
|
|
4805
|
+
@if (config.exportable) {
|
|
4806
|
+
<div class="export-container">
|
|
4807
|
+
<button class="btn-ghost btn-sm" (click)="exportMenuOpen.set(!exportMenuOpen())">
|
|
4808
|
+
<svg viewBox="0 0 24 24" class="btn-icon"><path [attr.d]="iconRegistry.getIcon('download')"></path></svg>
|
|
4809
|
+
Export
|
|
4810
|
+
</button>
|
|
4811
|
+
@if (exportMenuOpen()) {
|
|
4812
|
+
<div class="dropdown-menu export-menu">
|
|
4813
|
+
@for (format of config.exportFormats || ['csv', 'json']; track format) {
|
|
4814
|
+
<div class="dropdown-item" (click)="exportData(format); exportMenuOpen.set(false)">
|
|
4815
|
+
Export as {{ format | uppercase }}
|
|
4816
|
+
</div>
|
|
4817
|
+
}
|
|
4818
|
+
</div>
|
|
4819
|
+
}
|
|
4820
|
+
</div>
|
|
4821
|
+
}
|
|
4822
|
+
</div>
|
|
4823
|
+
</div>
|
|
4824
|
+
<div class="table-wrapper">
|
|
4825
|
+
<table class="data-table" [class.striped]="config.striped" [class.hoverable]="config.hoverable !== false">
|
|
4826
|
+
<thead>
|
|
4827
|
+
<tr cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropColumn($event)">
|
|
4828
|
+
@if (config.reorderable) { <th class="drag-col" style="width: 40px; text-align: center;"></th> }
|
|
4829
|
+
@if (config.selectionMode === 'checkbox') {
|
|
4830
|
+
<th class="selection-col" style="width: 40px; text-align: center;">
|
|
4831
|
+
@if (config.showSelectAll !== false) {
|
|
4832
|
+
<input type="checkbox"
|
|
4833
|
+
class="amf-checkbox"
|
|
4834
|
+
[checked]="selectedRows().size > 0 && selectedRows().size === filteredData().length"
|
|
4835
|
+
(change)="toggleAllSelection($event)" />
|
|
4836
|
+
}
|
|
4837
|
+
</th>
|
|
4838
|
+
}
|
|
4839
|
+
@if (config.expandable) {
|
|
4840
|
+
<th style="width: 36px;"></th>
|
|
4841
|
+
}
|
|
4842
|
+
@for (col of visibleColumns(); track col.key) {
|
|
4843
|
+
<th cdkDrag [cdkDragDisabled]="!config.columnReorder" [style.width]="col.width" [style.min-width]="col.minWidth" [style.text-align]="col.align || 'left'" [class.sortable]="col.sortable" (click)="col.sortable ? toggleSort(col.key) : null">
|
|
4844
|
+
{{ col.label }} @if (col.sortable && sortKey() === col.key) { <span class="sort-indicator">{{ sortDirection() === 'asc' ? '↑' : '↓' }}</span> }
|
|
4845
|
+
</th>
|
|
4846
|
+
}
|
|
4847
|
+
@if (config.actions?.length) { <th class="actions-col">Actions</th> }
|
|
4848
|
+
</tr>
|
|
4849
|
+
</thead>
|
|
4850
|
+
<tbody cdkDropList (cdkDropListDropped)="dropRow($event)">
|
|
4851
|
+
@for (row of groupedRows(); track $index) {
|
|
4852
|
+
@if (row.__isGroupHeader) {
|
|
4853
|
+
<tr class="group-header-row">
|
|
4854
|
+
<td [attr.colspan]="visibleColumns().length + (config.reorderable ? 1 : 0) + (config.selectionMode === 'checkbox' ? 1 : 0) + (config.expandable ? 1 : 0) + (config.actions?.length ? 1 : 0)">
|
|
4855
|
+
<button class="group-toggle" (click)="toggleGroup(row.__groupKey)">
|
|
4856
|
+
<span class="group-chevron" [class.open]="!collapsedGroups().has(row.__groupKey)">▶</span>
|
|
4857
|
+
{{ config.groupBy }}: <strong>{{ row.__groupKey }}</strong>
|
|
4858
|
+
<span class="group-count">({{ row.__count }} items)</span>
|
|
4859
|
+
</button>
|
|
4860
|
+
</td>
|
|
4861
|
+
</tr>
|
|
4862
|
+
} @else {
|
|
4863
|
+
<tr cdkDrag [cdkDragDisabled]="!config.reorderable" (click)="handleRowClick(row)" [class.clickable]="config.rowClick || config.selectionMode === 'single' || config.selectionMode === 'multi'" [class.selected]="selectedRows().has(row)" [class.expanded]="expandedRows().has(row)">
|
|
4864
|
+
@if (config.reorderable) {
|
|
4865
|
+
<td class="drag-cell" (click)="$event.stopPropagation()" cdkDragHandle>
|
|
4866
|
+
<svg viewBox="0 0 24 24" style="width:16px;height:16px;fill:var(--app-text-muted)"><path [attr.d]="iconRegistry.getIcon('menu')"></path></svg>
|
|
4867
|
+
</td>
|
|
4868
|
+
}
|
|
4869
|
+
@if (config.selectionMode === 'checkbox') {
|
|
4870
|
+
<td class="selection-cell" (click)="$event.stopPropagation(); toggleSelection(row)">
|
|
4871
|
+
<input type="checkbox" class="amf-checkbox" [checked]="selectedRows().has(row)" (click)="$event.stopPropagation()" (change)="$event.stopPropagation(); toggleSelection(row)" />
|
|
4872
|
+
</td>
|
|
4873
|
+
}
|
|
4874
|
+
@if (config.expandable) {
|
|
4875
|
+
<td class="expand-cell" (click)="$event.stopPropagation(); toggleRowExpand(row)">
|
|
4876
|
+
<span class="expand-chevron" [class.open]="expandedRows().has(row)">▶</span>
|
|
4877
|
+
</td>
|
|
4878
|
+
}
|
|
4879
|
+
@for (col of visibleColumns(); track col.key) {
|
|
4880
|
+
<td [style.text-align]="col.align || 'left'" (dblclick)="config.inlineEdit && col.editable !== false ? startEdit(row, col.key, $event) : null" [class.editable-cell]="config.inlineEdit && col.editable !== false">
|
|
4881
|
+
@if (isEditing(row, col.key)) {
|
|
4882
|
+
<div class="inline-edit-wrap" (click)="$event.stopPropagation()">
|
|
4883
|
+
<div class="inline-edit-row">
|
|
4884
|
+
@if (col.editType === 'select' && col.editOptions) {
|
|
4885
|
+
<select class="inline-input" [(ngModel)]="editBuffer[col.key]">
|
|
4886
|
+
@for (opt of col.editOptions; track opt.value) { <option [value]="opt.value">{{ opt.label }}</option> }
|
|
4887
|
+
</select>
|
|
4888
|
+
} @else {
|
|
4889
|
+
<input class="inline-input" [type]="col.editType || 'text'" [(ngModel)]="editBuffer[col.key]" (keydown.enter)="commitEdit(row, col.key)" (keydown.escape)="cancelEdit()" />
|
|
4890
|
+
}
|
|
4891
|
+
<div class="inline-edit-actions">
|
|
4892
|
+
<button class="ie-btn ie-save" title="Save (Enter)" (click)="commitEdit(row, col.key)">
|
|
4893
|
+
<svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
|
|
4894
|
+
</button>
|
|
4895
|
+
<button class="ie-btn ie-cancel" title="Cancel (Esc)" (click)="cancelEdit()">
|
|
4896
|
+
<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
|
4897
|
+
</button>
|
|
4898
|
+
</div>
|
|
4899
|
+
</div>
|
|
4900
|
+
@if (editError()) {
|
|
4901
|
+
<span class="inline-edit-error">{{ editError() }}</span>
|
|
4902
|
+
}
|
|
4903
|
+
</div>
|
|
4904
|
+
} @else {
|
|
4905
|
+
<amf-cell-renderer [column]="col" [row]="row" [value]="getCellValue(row, col.key)"></amf-cell-renderer>
|
|
4906
|
+
}
|
|
4907
|
+
</td>
|
|
4908
|
+
}
|
|
4909
|
+
@if (config.actions?.length) {
|
|
4910
|
+
<td class="actions-cell">
|
|
4911
|
+
<div class="action-btns">
|
|
4912
|
+
@for (action of config.actions; track action.id) {
|
|
4913
|
+
<button class="action-btn" [class]="action.variant || 'ghost'" [title]="action.label" (click)="handleAction(action, row); $event.stopPropagation()">
|
|
4914
|
+
@if (action.icon) { <svg viewBox="0 0 24 24"><path [attr.d]="iconRegistry.getIcon(action.icon)"></path></svg> } @else { {{ action.label }} }
|
|
4915
|
+
</button>
|
|
4916
|
+
}
|
|
4917
|
+
</div>
|
|
4918
|
+
</td>
|
|
4919
|
+
}
|
|
4920
|
+
</tr>
|
|
4921
|
+
@if (config.expandable && expandedRows().has(row)) {
|
|
4922
|
+
<tr class="expanded-row">
|
|
4923
|
+
<td [attr.colspan]="visibleColumns().length + (config.reorderable ? 1 : 0) + (config.selectionMode === 'checkbox' ? 1 : 0) + 1 + (config.actions?.length ? 1 : 0)" class="expanded-content">
|
|
4924
|
+
@if (config.expandSection) {
|
|
4925
|
+
<div class="expand-section">Row detail: {{ row | json }}</div>
|
|
4926
|
+
} @else {
|
|
4927
|
+
<div class="expand-section">
|
|
4928
|
+
@for (col of visibleColumns(); track col.key) {
|
|
4929
|
+
<div class="expand-field"><span class="expand-label">{{ col.label }}:</span> <span>{{ getCellValue(row, col.key) }}</span></div>
|
|
4930
|
+
}
|
|
4931
|
+
</div>
|
|
4932
|
+
}
|
|
4933
|
+
</td>
|
|
4934
|
+
</tr>
|
|
4935
|
+
}
|
|
4936
|
+
}
|
|
4937
|
+
} @empty { <tr><td [attr.colspan]="visibleColumns().length + (config.actions?.length ? 1 : 0)" class="empty-state">{{ config.emptyMessage || 'No data found.' }}</td></tr> }
|
|
4938
|
+
@if (config.aggregates?.length) {
|
|
4939
|
+
<tr class="aggregate-row">
|
|
4940
|
+
@if (config.reorderable) { <td></td> }
|
|
4941
|
+
@if (config.selectionMode === 'checkbox') { <td></td> }
|
|
4942
|
+
@if (config.expandable) { <td></td> }
|
|
4943
|
+
@for (col of visibleColumns(); track col.key) {
|
|
4944
|
+
<td class="aggregate-cell" [style.text-align]="col.align || 'right'">
|
|
4945
|
+
@if (getAggregate(col.key); as agg) { <span class="agg-value">{{ agg.label ? agg.label + ': ' : '' }}{{ agg.value }}</span> }
|
|
4946
|
+
</td>
|
|
4947
|
+
}
|
|
4948
|
+
@if (config.actions?.length) { <td></td> }
|
|
4949
|
+
</tr>
|
|
4950
|
+
}
|
|
4951
|
+
</tbody>
|
|
4952
|
+
</table>
|
|
4953
|
+
</div>
|
|
4954
|
+
@if (config.pagination?.enabled) {
|
|
4955
|
+
<div class="table-footer">
|
|
4956
|
+
<div class="footer-left">
|
|
4957
|
+
<span class="results-count">Showing {{ paginatedData().length }} of {{ filteredData().length }} @if (config.pagination?.showTotal) { (total: {{ allData().length }}) }</span>
|
|
4958
|
+
@if ((config.pagination?.pageSizeOptions || [5, 10, 25, 50]).length > 1) {
|
|
4959
|
+
<div class="page-size-wrap">
|
|
4960
|
+
<label class="page-size-label">Rows:</label>
|
|
4961
|
+
<select class="page-size-select" [ngModel]="activePageSize()" (ngModelChange)="setPageSize($event)">
|
|
4962
|
+
@for (opt of config.pagination?.pageSizeOptions || [5, 10, 25, 50]; track opt) {
|
|
4963
|
+
<option [value]="opt">{{ opt }}</option>
|
|
4964
|
+
}
|
|
4965
|
+
</select>
|
|
4966
|
+
</div>
|
|
4967
|
+
}
|
|
4968
|
+
</div>
|
|
4969
|
+
<div class="pagination">
|
|
4970
|
+
<button class="btn-page-nav" [disabled]="currentPage() <= 1" (click)="currentPage.set(currentPage() - 1)">Previous</button>
|
|
4971
|
+
@for (p of pageNumbers(); track p) { <button class="btn-page" [class.active]="p === currentPage()" (click)="currentPage.set(p)">{{ p }}</button> }
|
|
4972
|
+
<button class="btn-page-nav" [disabled]="currentPage() >= totalPages()" (click)="currentPage.set(currentPage() + 1)">Next</button>
|
|
4973
|
+
</div>
|
|
4974
|
+
</div>
|
|
4975
|
+
}
|
|
4976
|
+
</div>
|
|
4977
4977
|
`, isInline: true, styles: [".amf-table-card{background:var(--app-surface);border:1px solid var(--app-border);border-radius:16px;overflow:hidden;box-shadow:0 1px 3px #0000000d}.table-header{padding:16px 20px;display:flex;justify-content:space-between;align-items:center;gap:16px;border-bottom:1px solid var(--app-border);flex-wrap:wrap}.table-header-left,.table-header-right{display:flex;align-items:center;gap:12px}.search-box{position:relative;min-width:240px}.search-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:16px;height:16px;fill:var(--app-text-muted)}.search-box input{width:100%;padding:8px 12px 8px 36px;border:1px solid var(--app-border);border-radius:8px;font-size:.8125rem;outline:none;background:var(--glass-bg);color:var(--app-text)}.search-box input:focus{border-color:var(--app-primary)}.filter-select{padding:8px 12px;border:1px solid var(--app-border);border-radius:8px;font-size:.8125rem;outline:none;background:var(--glass-bg);color:var(--app-text);color-scheme:dark}.filter-select option{background-color:#1e1e2d;color:#fff}:host-context([data-color-scheme=\"light\"]) .filter-select{color-scheme:light}:host-context([data-color-scheme=\"light\"]) .filter-select option{background-color:#fff;color:#000}.table-wrapper{width:100%;overflow-x:auto}.data-table{width:100%;border-collapse:collapse;white-space:normal;word-break:break-word}.data-table th{background:var(--app-bg);padding:10px 20px;font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--app-text-muted);border-bottom:1px solid var(--app-border);-webkit-user-select:none;user-select:none}.data-table th.sortable{cursor:pointer}.data-table th.sortable:hover{color:var(--app-primary)}.sort-indicator{margin-left:4px;font-size:.75rem}.data-table td{padding:14px 20px;border-bottom:1px solid var(--app-border);font-size:.875rem;color:var(--app-text)}.data-table.hoverable tbody tr:hover{background:var(--glass-bg)}.data-table.striped tbody tr:nth-child(2n){background:var(--glass-bg)}.variant-striped .data-table tbody tr:nth-child(2n){background:var(--glass-bg)}.variant-borderless{border:none!important;box-shadow:none!important;background:transparent!important}.variant-borderless .table-header{border-bottom:none;padding:0 0 16px}.variant-borderless .data-table th{background:transparent;border-bottom:2px solid var(--app-border)}.variant-borderless .data-table td{border-bottom:1px dashed var(--app-border)}.variant-borderless .table-footer{border-top:none;background:transparent;padding:16px 0 0}.variant-glass{background:var(--glass-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));border:1px solid var(--glass-border);box-shadow:var(--glass-shadow-sm)}.variant-glass .table-header,.variant-glass .table-footer,.variant-glass .data-table th{background:transparent;border-color:var(--glass-border)}.variant-glass .data-table td{border-bottom:1px solid var(--glass-border)}.variant-elevated{box-shadow:0 20px 40px var(--glass-shadow);transform:translateY(-2px);transition:all .3s ease}.variant-compact .table-header{padding:12px 16px}.variant-compact .data-table th{padding:8px 16px;font-size:.625rem}.variant-compact .data-table td{padding:8px 16px;font-size:.8125rem}.variant-compact .table-footer{padding:8px 16px}tr.clickable{cursor:pointer}.amf-checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--app-primary)}.data-table tbody tr.selected{background:#3b82f626!important}.actions-col{text-align:right!important;width:120px}.actions-cell{text-align:right}.action-btns{display:flex;justify-content:flex-end;gap:6px}.action-btn{width:30px;height:30px;border-radius:6px;border:1px solid var(--app-border);background:transparent;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s}.action-btn svg{width:14px;height:14px;fill:var(--app-text-muted)}.action-btn:hover{border-color:var(--app-primary)}.action-btn:hover svg{fill:var(--app-primary)}.action-btn.danger:hover{border-color:#f43f5e}.action-btn.danger:hover svg{fill:#f43f5e}.btn-primary{background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff;border:none;padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;cursor:pointer;display:flex;align-items:center;gap:6px;transition:all .2s}.btn-primary:hover{transform:translateY(-1px);box-shadow:0 4px 12px var(--app-glow)}.btn-icon{width:16px;height:16px;fill:currentColor}.btn-sm{padding:6px 12px;font-size:.75rem;border-radius:6px}.btn-ghost{background:transparent;border:1px solid var(--app-border);color:var(--app-text);padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;display:flex;align-items:center;gap:6px;cursor:pointer;transition:all .2s}.btn-ghost:hover{background:var(--glass-bg-hover);color:var(--app-primary)}.export-container{position:relative}.export-menu{position:absolute;top:calc(100% + 8px);right:0;background:var(--app-surface);border:1px solid var(--app-border);border-radius:12px;box-shadow:0 10px 40px #00000080;min-width:160px;z-index:100;overflow:hidden;animation:slideInDown .2s ease-out backwards}.export-menu .dropdown-item{padding:10px 16px;font-size:.8125rem;font-weight:500;cursor:pointer;color:var(--app-text);transition:background .2s}.export-menu .dropdown-item:hover{background:var(--glass-bg-hover);color:var(--app-primary)}.empty-state{text-align:center;padding:40px!important;color:var(--app-text-muted)}.table-footer{padding:12px 20px;display:flex;justify-content:space-between;align-items:center;background:var(--app-bg);border-top:1px solid var(--app-border)}.footer-left{display:flex;align-items:center;gap:16px}.results-count{font-size:.75rem;color:var(--app-text-muted)}.page-size-wrap{display:flex;align-items:center;gap:6px}.page-size-label{font-size:.75rem;color:var(--app-text-muted);white-space:nowrap}.page-size-select{padding:4px 8px;border:1px solid var(--app-border);border-radius:6px;font-size:.75rem;background:var(--glass-bg);color:var(--app-text);outline:none;cursor:pointer;color-scheme:dark}.page-size-select option{background-color:#1a1a2e;color:#fff}:host-context([data-color-scheme=\"light\"]) .page-size-select{color-scheme:light}:host-context([data-color-scheme=\"light\"]) .page-size-select option{background-color:#fff;color:#000}.pagination{display:flex;gap:4px}.btn-page,.btn-page-nav{padding:6px 10px;border:1px solid var(--app-border);background:transparent;border-radius:6px;font-size:.75rem;font-weight:500;color:var(--app-text);cursor:pointer}.btn-page.active{background:var(--app-primary);border-color:var(--app-primary);color:#fff}.btn-page-nav:disabled{opacity:.4;cursor:not-allowed}.editable-cell{position:relative}.editable-cell:hover{background:#3b82f614;cursor:text}.inline-edit-wrap{display:flex;flex-direction:column;gap:4px;min-width:0}.inline-edit-row{display:flex;align-items:center;gap:4px}.inline-input{flex:1;min-width:0;padding:5px 8px;border:1.5px solid var(--app-primary);border-radius:6px;background:var(--app-surface);color:var(--app-text);font-size:.875rem;outline:none}.inline-input.input-invalid{border-color:#f43f5e}.inline-edit-error{font-size:.6875rem;color:#f43f5e;font-weight:500;padding:0 2px;animation:fadeIn .15s ease-out}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.inline-edit-actions{display:flex;gap:3px;flex-shrink:0}.ie-btn{width:26px;height:26px;border-radius:5px;border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:opacity .15s}.ie-btn svg{width:14px;height:14px;fill:currentColor}.ie-btn:hover{opacity:.85}.ie-save{background:#22c55e;color:#fff}.ie-cancel{background:var(--app-border);color:var(--app-text-muted)}select.inline-input{color-scheme:dark;cursor:pointer}select.inline-input option{background-color:#1a1a2e;color:#fff}:host-context([data-color-scheme=\"light\"]) select.inline-input{color-scheme:light}:host-context([data-color-scheme=\"light\"]) select.inline-input option{background-color:#fff;color:#000}.expand-cell{width:36px;text-align:center;cursor:pointer}.expand-chevron{display:inline-block;transition:transform .2s;font-size:.625rem;color:var(--app-text-muted)}.expand-chevron.open{transform:rotate(90deg)}.expanded-row td,.expanded-content{padding:0!important}.expand-section{padding:14px 24px;display:flex;flex-wrap:wrap;gap:16px;background:var(--glass-bg);animation:fadeInUp .2s ease-out}.expand-field{display:flex;gap:8px;font-size:.8125rem}.expand-label{color:var(--app-text-muted);font-weight:600}.group-header-row td{background:var(--app-bg)}.group-toggle{display:flex;align-items:center;gap:8px;background:none;border:none;color:var(--app-text);cursor:pointer;font-size:.8125rem;padding:8px 16px}.group-chevron{display:inline-block;font-size:.625rem;transition:transform .2s;color:var(--app-text-muted)}.group-chevron.open{transform:rotate(90deg)}.group-count{color:var(--app-text-muted);font-size:.75rem}.aggregate-row td{background:var(--app-bg);border-top:2px solid var(--app-border)}.aggregate-cell{padding:10px 20px!important}.agg-value{font-size:.8125rem;font-weight:700;color:var(--app-primary)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$2.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$2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "component", type: CellRendererComponent, selector: "amf-cell-renderer", inputs: ["column", "row", "value"] }, { kind: "pipe", type: i1$1.UpperCasePipe, name: "uppercase" }, { kind: "pipe", type: i1$1.JsonPipe, name: "json" }] });
|
|
4978
4978
|
}
|
|
4979
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
4979
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: TableRendererComponent, decorators: [{
|
|
4980
4980
|
type: Component,
|
|
4981
|
-
args: [{ selector: 'amf-table-renderer', standalone: true, imports: [CommonModule, FormsModule, DragDropModule, CellRendererComponent], template: `
|
|
4982
|
-
<div class="amf-table-card" [class]="'variant-' + (config.variant || 'default') + ' ' + (config.cssClass || '')">
|
|
4983
|
-
<div class="table-header">
|
|
4984
|
-
<div class="table-header-left">
|
|
4985
|
-
@if (config.searchable) {
|
|
4986
|
-
<div class="search-box">
|
|
4987
|
-
<svg viewBox="0 0 24 24" class="search-icon"><path [attr.d]="iconRegistry.getIcon('search')"></path></svg>
|
|
4988
|
-
<input type="text" [placeholder]="config.searchPlaceholder || 'Search...'" [ngModel]="searchQuery()" (ngModelChange)="searchQuery.set($event)" />
|
|
4989
|
-
</div>
|
|
4990
|
-
}
|
|
4991
|
-
@for (filter of config.filters || []; track filter.key) {
|
|
4992
|
-
<select class="filter-select" [ngModel]="getFilterValue(filter.key)" (ngModelChange)="setFilterValue(filter.key, $event)">
|
|
4993
|
-
<option value="">{{ filter.label }}</option>
|
|
4994
|
-
@for (opt of filter.options; track opt.value) { <option [value]="opt.value">{{ opt.label }}</option> }
|
|
4995
|
-
</select>
|
|
4996
|
-
}
|
|
4997
|
-
</div>
|
|
4998
|
-
<div class="table-header-right">
|
|
4999
|
-
@for (action of config.headerActions || []; track action.id) {
|
|
5000
|
-
<button class="btn-primary btn-sm" (click)="handleAction(action, null)">
|
|
5001
|
-
@if (action.icon) { <svg viewBox="0 0 24 24" class="btn-icon"><path [attr.d]="iconRegistry.getIcon(action.icon)"></path></svg> }
|
|
5002
|
-
{{ action.label }}
|
|
5003
|
-
</button>
|
|
5004
|
-
}
|
|
5005
|
-
|
|
5006
|
-
@if (config.exportable) {
|
|
5007
|
-
<div class="export-container">
|
|
5008
|
-
<button class="btn-ghost btn-sm" (click)="exportMenuOpen.set(!exportMenuOpen())">
|
|
5009
|
-
<svg viewBox="0 0 24 24" class="btn-icon"><path [attr.d]="iconRegistry.getIcon('download')"></path></svg>
|
|
5010
|
-
Export
|
|
5011
|
-
</button>
|
|
5012
|
-
@if (exportMenuOpen()) {
|
|
5013
|
-
<div class="dropdown-menu export-menu">
|
|
5014
|
-
@for (format of config.exportFormats || ['csv', 'json']; track format) {
|
|
5015
|
-
<div class="dropdown-item" (click)="exportData(format); exportMenuOpen.set(false)">
|
|
5016
|
-
Export as {{ format | uppercase }}
|
|
5017
|
-
</div>
|
|
5018
|
-
}
|
|
5019
|
-
</div>
|
|
5020
|
-
}
|
|
5021
|
-
</div>
|
|
5022
|
-
}
|
|
5023
|
-
</div>
|
|
5024
|
-
</div>
|
|
5025
|
-
<div class="table-wrapper">
|
|
5026
|
-
<table class="data-table" [class.striped]="config.striped" [class.hoverable]="config.hoverable !== false">
|
|
5027
|
-
<thead>
|
|
5028
|
-
<tr cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropColumn($event)">
|
|
5029
|
-
@if (config.reorderable) { <th class="drag-col" style="width: 40px; text-align: center;"></th> }
|
|
5030
|
-
@if (config.selectionMode === 'checkbox') {
|
|
5031
|
-
<th class="selection-col" style="width: 40px; text-align: center;">
|
|
5032
|
-
@if (config.showSelectAll !== false) {
|
|
5033
|
-
<input type="checkbox"
|
|
5034
|
-
class="amf-checkbox"
|
|
5035
|
-
[checked]="selectedRows().size > 0 && selectedRows().size === filteredData().length"
|
|
5036
|
-
(change)="toggleAllSelection($event)" />
|
|
5037
|
-
}
|
|
5038
|
-
</th>
|
|
5039
|
-
}
|
|
5040
|
-
@if (config.expandable) {
|
|
5041
|
-
<th style="width: 36px;"></th>
|
|
5042
|
-
}
|
|
5043
|
-
@for (col of visibleColumns(); track col.key) {
|
|
5044
|
-
<th cdkDrag [cdkDragDisabled]="!config.columnReorder" [style.width]="col.width" [style.min-width]="col.minWidth" [style.text-align]="col.align || 'left'" [class.sortable]="col.sortable" (click)="col.sortable ? toggleSort(col.key) : null">
|
|
5045
|
-
{{ col.label }} @if (col.sortable && sortKey() === col.key) { <span class="sort-indicator">{{ sortDirection() === 'asc' ? '↑' : '↓' }}</span> }
|
|
5046
|
-
</th>
|
|
5047
|
-
}
|
|
5048
|
-
@if (config.actions?.length) { <th class="actions-col">Actions</th> }
|
|
5049
|
-
</tr>
|
|
5050
|
-
</thead>
|
|
5051
|
-
<tbody cdkDropList (cdkDropListDropped)="dropRow($event)">
|
|
5052
|
-
@for (row of groupedRows(); track $index) {
|
|
5053
|
-
@if (row.__isGroupHeader) {
|
|
5054
|
-
<tr class="group-header-row">
|
|
5055
|
-
<td [attr.colspan]="visibleColumns().length + (config.reorderable ? 1 : 0) + (config.selectionMode === 'checkbox' ? 1 : 0) + (config.expandable ? 1 : 0) + (config.actions?.length ? 1 : 0)">
|
|
5056
|
-
<button class="group-toggle" (click)="toggleGroup(row.__groupKey)">
|
|
5057
|
-
<span class="group-chevron" [class.open]="!collapsedGroups().has(row.__groupKey)">▶</span>
|
|
5058
|
-
{{ config.groupBy }}: <strong>{{ row.__groupKey }}</strong>
|
|
5059
|
-
<span class="group-count">({{ row.__count }} items)</span>
|
|
5060
|
-
</button>
|
|
5061
|
-
</td>
|
|
5062
|
-
</tr>
|
|
5063
|
-
} @else {
|
|
5064
|
-
<tr cdkDrag [cdkDragDisabled]="!config.reorderable" (click)="handleRowClick(row)" [class.clickable]="config.rowClick || config.selectionMode === 'single' || config.selectionMode === 'multi'" [class.selected]="selectedRows().has(row)" [class.expanded]="expandedRows().has(row)">
|
|
5065
|
-
@if (config.reorderable) {
|
|
5066
|
-
<td class="drag-cell" (click)="$event.stopPropagation()" cdkDragHandle>
|
|
5067
|
-
<svg viewBox="0 0 24 24" style="width:16px;height:16px;fill:var(--app-text-muted)"><path [attr.d]="iconRegistry.getIcon('menu')"></path></svg>
|
|
5068
|
-
</td>
|
|
5069
|
-
}
|
|
5070
|
-
@if (config.selectionMode === 'checkbox') {
|
|
5071
|
-
<td class="selection-cell" (click)="$event.stopPropagation(); toggleSelection(row)">
|
|
5072
|
-
<input type="checkbox" class="amf-checkbox" [checked]="selectedRows().has(row)" (click)="$event.stopPropagation()" (change)="$event.stopPropagation(); toggleSelection(row)" />
|
|
5073
|
-
</td>
|
|
5074
|
-
}
|
|
5075
|
-
@if (config.expandable) {
|
|
5076
|
-
<td class="expand-cell" (click)="$event.stopPropagation(); toggleRowExpand(row)">
|
|
5077
|
-
<span class="expand-chevron" [class.open]="expandedRows().has(row)">▶</span>
|
|
5078
|
-
</td>
|
|
5079
|
-
}
|
|
5080
|
-
@for (col of visibleColumns(); track col.key) {
|
|
5081
|
-
<td [style.text-align]="col.align || 'left'" (dblclick)="config.inlineEdit && col.editable !== false ? startEdit(row, col.key, $event) : null" [class.editable-cell]="config.inlineEdit && col.editable !== false">
|
|
5082
|
-
@if (isEditing(row, col.key)) {
|
|
5083
|
-
<div class="inline-edit-wrap" (click)="$event.stopPropagation()">
|
|
5084
|
-
<div class="inline-edit-row">
|
|
5085
|
-
@if (col.editType === 'select' && col.editOptions) {
|
|
5086
|
-
<select class="inline-input" [(ngModel)]="editBuffer[col.key]">
|
|
5087
|
-
@for (opt of col.editOptions; track opt.value) { <option [value]="opt.value">{{ opt.label }}</option> }
|
|
5088
|
-
</select>
|
|
5089
|
-
} @else {
|
|
5090
|
-
<input class="inline-input" [type]="col.editType || 'text'" [(ngModel)]="editBuffer[col.key]" (keydown.enter)="commitEdit(row, col.key)" (keydown.escape)="cancelEdit()" />
|
|
5091
|
-
}
|
|
5092
|
-
<div class="inline-edit-actions">
|
|
5093
|
-
<button class="ie-btn ie-save" title="Save (Enter)" (click)="commitEdit(row, col.key)">
|
|
5094
|
-
<svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
|
|
5095
|
-
</button>
|
|
5096
|
-
<button class="ie-btn ie-cancel" title="Cancel (Esc)" (click)="cancelEdit()">
|
|
5097
|
-
<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
|
5098
|
-
</button>
|
|
5099
|
-
</div>
|
|
5100
|
-
</div>
|
|
5101
|
-
@if (editError()) {
|
|
5102
|
-
<span class="inline-edit-error">{{ editError() }}</span>
|
|
5103
|
-
}
|
|
5104
|
-
</div>
|
|
5105
|
-
} @else {
|
|
5106
|
-
<amf-cell-renderer [column]="col" [row]="row" [value]="getCellValue(row, col.key)"></amf-cell-renderer>
|
|
5107
|
-
}
|
|
5108
|
-
</td>
|
|
5109
|
-
}
|
|
5110
|
-
@if (config.actions?.length) {
|
|
5111
|
-
<td class="actions-cell">
|
|
5112
|
-
<div class="action-btns">
|
|
5113
|
-
@for (action of config.actions; track action.id) {
|
|
5114
|
-
<button class="action-btn" [class]="action.variant || 'ghost'" [title]="action.label" (click)="handleAction(action, row); $event.stopPropagation()">
|
|
5115
|
-
@if (action.icon) { <svg viewBox="0 0 24 24"><path [attr.d]="iconRegistry.getIcon(action.icon)"></path></svg> } @else { {{ action.label }} }
|
|
5116
|
-
</button>
|
|
5117
|
-
}
|
|
5118
|
-
</div>
|
|
5119
|
-
</td>
|
|
5120
|
-
}
|
|
5121
|
-
</tr>
|
|
5122
|
-
@if (config.expandable && expandedRows().has(row)) {
|
|
5123
|
-
<tr class="expanded-row">
|
|
5124
|
-
<td [attr.colspan]="visibleColumns().length + (config.reorderable ? 1 : 0) + (config.selectionMode === 'checkbox' ? 1 : 0) + 1 + (config.actions?.length ? 1 : 0)" class="expanded-content">
|
|
5125
|
-
@if (config.expandSection) {
|
|
5126
|
-
<div class="expand-section">Row detail: {{ row | json }}</div>
|
|
5127
|
-
} @else {
|
|
5128
|
-
<div class="expand-section">
|
|
5129
|
-
@for (col of visibleColumns(); track col.key) {
|
|
5130
|
-
<div class="expand-field"><span class="expand-label">{{ col.label }}:</span> <span>{{ getCellValue(row, col.key) }}</span></div>
|
|
5131
|
-
}
|
|
5132
|
-
</div>
|
|
5133
|
-
}
|
|
5134
|
-
</td>
|
|
5135
|
-
</tr>
|
|
5136
|
-
}
|
|
5137
|
-
}
|
|
5138
|
-
} @empty { <tr><td [attr.colspan]="visibleColumns().length + (config.actions?.length ? 1 : 0)" class="empty-state">{{ config.emptyMessage || 'No data found.' }}</td></tr> }
|
|
5139
|
-
@if (config.aggregates?.length) {
|
|
5140
|
-
<tr class="aggregate-row">
|
|
5141
|
-
@if (config.reorderable) { <td></td> }
|
|
5142
|
-
@if (config.selectionMode === 'checkbox') { <td></td> }
|
|
5143
|
-
@if (config.expandable) { <td></td> }
|
|
5144
|
-
@for (col of visibleColumns(); track col.key) {
|
|
5145
|
-
<td class="aggregate-cell" [style.text-align]="col.align || 'right'">
|
|
5146
|
-
@if (getAggregate(col.key); as agg) { <span class="agg-value">{{ agg.label ? agg.label + ': ' : '' }}{{ agg.value }}</span> }
|
|
5147
|
-
</td>
|
|
5148
|
-
}
|
|
5149
|
-
@if (config.actions?.length) { <td></td> }
|
|
5150
|
-
</tr>
|
|
5151
|
-
}
|
|
5152
|
-
</tbody>
|
|
5153
|
-
</table>
|
|
5154
|
-
</div>
|
|
5155
|
-
@if (config.pagination?.enabled) {
|
|
5156
|
-
<div class="table-footer">
|
|
5157
|
-
<div class="footer-left">
|
|
5158
|
-
<span class="results-count">Showing {{ paginatedData().length }} of {{ filteredData().length }} @if (config.pagination?.showTotal) { (total: {{ allData().length }}) }</span>
|
|
5159
|
-
@if ((config.pagination?.pageSizeOptions || [5, 10, 25, 50]).length > 1) {
|
|
5160
|
-
<div class="page-size-wrap">
|
|
5161
|
-
<label class="page-size-label">Rows:</label>
|
|
5162
|
-
<select class="page-size-select" [ngModel]="activePageSize()" (ngModelChange)="setPageSize($event)">
|
|
5163
|
-
@for (opt of config.pagination?.pageSizeOptions || [5, 10, 25, 50]; track opt) {
|
|
5164
|
-
<option [value]="opt">{{ opt }}</option>
|
|
5165
|
-
}
|
|
5166
|
-
</select>
|
|
5167
|
-
</div>
|
|
5168
|
-
}
|
|
5169
|
-
</div>
|
|
5170
|
-
<div class="pagination">
|
|
5171
|
-
<button class="btn-page-nav" [disabled]="currentPage() <= 1" (click)="currentPage.set(currentPage() - 1)">Previous</button>
|
|
5172
|
-
@for (p of pageNumbers(); track p) { <button class="btn-page" [class.active]="p === currentPage()" (click)="currentPage.set(p)">{{ p }}</button> }
|
|
5173
|
-
<button class="btn-page-nav" [disabled]="currentPage() >= totalPages()" (click)="currentPage.set(currentPage() + 1)">Next</button>
|
|
5174
|
-
</div>
|
|
5175
|
-
</div>
|
|
5176
|
-
}
|
|
5177
|
-
</div>
|
|
4981
|
+
args: [{ selector: 'amf-table-renderer', standalone: true, imports: [CommonModule, FormsModule, DragDropModule, CellRendererComponent], template: `
|
|
4982
|
+
<div class="amf-table-card" [class]="'variant-' + (config.variant || 'default') + ' ' + (config.cssClass || '')">
|
|
4983
|
+
<div class="table-header">
|
|
4984
|
+
<div class="table-header-left">
|
|
4985
|
+
@if (config.searchable) {
|
|
4986
|
+
<div class="search-box">
|
|
4987
|
+
<svg viewBox="0 0 24 24" class="search-icon"><path [attr.d]="iconRegistry.getIcon('search')"></path></svg>
|
|
4988
|
+
<input type="text" [placeholder]="config.searchPlaceholder || 'Search...'" [ngModel]="searchQuery()" (ngModelChange)="searchQuery.set($event)" />
|
|
4989
|
+
</div>
|
|
4990
|
+
}
|
|
4991
|
+
@for (filter of config.filters || []; track filter.key) {
|
|
4992
|
+
<select class="filter-select" [ngModel]="getFilterValue(filter.key)" (ngModelChange)="setFilterValue(filter.key, $event)">
|
|
4993
|
+
<option value="">{{ filter.label }}</option>
|
|
4994
|
+
@for (opt of filter.options; track opt.value) { <option [value]="opt.value">{{ opt.label }}</option> }
|
|
4995
|
+
</select>
|
|
4996
|
+
}
|
|
4997
|
+
</div>
|
|
4998
|
+
<div class="table-header-right">
|
|
4999
|
+
@for (action of config.headerActions || []; track action.id) {
|
|
5000
|
+
<button class="btn-primary btn-sm" (click)="handleAction(action, null)">
|
|
5001
|
+
@if (action.icon) { <svg viewBox="0 0 24 24" class="btn-icon"><path [attr.d]="iconRegistry.getIcon(action.icon)"></path></svg> }
|
|
5002
|
+
{{ action.label }}
|
|
5003
|
+
</button>
|
|
5004
|
+
}
|
|
5005
|
+
|
|
5006
|
+
@if (config.exportable) {
|
|
5007
|
+
<div class="export-container">
|
|
5008
|
+
<button class="btn-ghost btn-sm" (click)="exportMenuOpen.set(!exportMenuOpen())">
|
|
5009
|
+
<svg viewBox="0 0 24 24" class="btn-icon"><path [attr.d]="iconRegistry.getIcon('download')"></path></svg>
|
|
5010
|
+
Export
|
|
5011
|
+
</button>
|
|
5012
|
+
@if (exportMenuOpen()) {
|
|
5013
|
+
<div class="dropdown-menu export-menu">
|
|
5014
|
+
@for (format of config.exportFormats || ['csv', 'json']; track format) {
|
|
5015
|
+
<div class="dropdown-item" (click)="exportData(format); exportMenuOpen.set(false)">
|
|
5016
|
+
Export as {{ format | uppercase }}
|
|
5017
|
+
</div>
|
|
5018
|
+
}
|
|
5019
|
+
</div>
|
|
5020
|
+
}
|
|
5021
|
+
</div>
|
|
5022
|
+
}
|
|
5023
|
+
</div>
|
|
5024
|
+
</div>
|
|
5025
|
+
<div class="table-wrapper">
|
|
5026
|
+
<table class="data-table" [class.striped]="config.striped" [class.hoverable]="config.hoverable !== false">
|
|
5027
|
+
<thead>
|
|
5028
|
+
<tr cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropColumn($event)">
|
|
5029
|
+
@if (config.reorderable) { <th class="drag-col" style="width: 40px; text-align: center;"></th> }
|
|
5030
|
+
@if (config.selectionMode === 'checkbox') {
|
|
5031
|
+
<th class="selection-col" style="width: 40px; text-align: center;">
|
|
5032
|
+
@if (config.showSelectAll !== false) {
|
|
5033
|
+
<input type="checkbox"
|
|
5034
|
+
class="amf-checkbox"
|
|
5035
|
+
[checked]="selectedRows().size > 0 && selectedRows().size === filteredData().length"
|
|
5036
|
+
(change)="toggleAllSelection($event)" />
|
|
5037
|
+
}
|
|
5038
|
+
</th>
|
|
5039
|
+
}
|
|
5040
|
+
@if (config.expandable) {
|
|
5041
|
+
<th style="width: 36px;"></th>
|
|
5042
|
+
}
|
|
5043
|
+
@for (col of visibleColumns(); track col.key) {
|
|
5044
|
+
<th cdkDrag [cdkDragDisabled]="!config.columnReorder" [style.width]="col.width" [style.min-width]="col.minWidth" [style.text-align]="col.align || 'left'" [class.sortable]="col.sortable" (click)="col.sortable ? toggleSort(col.key) : null">
|
|
5045
|
+
{{ col.label }} @if (col.sortable && sortKey() === col.key) { <span class="sort-indicator">{{ sortDirection() === 'asc' ? '↑' : '↓' }}</span> }
|
|
5046
|
+
</th>
|
|
5047
|
+
}
|
|
5048
|
+
@if (config.actions?.length) { <th class="actions-col">Actions</th> }
|
|
5049
|
+
</tr>
|
|
5050
|
+
</thead>
|
|
5051
|
+
<tbody cdkDropList (cdkDropListDropped)="dropRow($event)">
|
|
5052
|
+
@for (row of groupedRows(); track $index) {
|
|
5053
|
+
@if (row.__isGroupHeader) {
|
|
5054
|
+
<tr class="group-header-row">
|
|
5055
|
+
<td [attr.colspan]="visibleColumns().length + (config.reorderable ? 1 : 0) + (config.selectionMode === 'checkbox' ? 1 : 0) + (config.expandable ? 1 : 0) + (config.actions?.length ? 1 : 0)">
|
|
5056
|
+
<button class="group-toggle" (click)="toggleGroup(row.__groupKey)">
|
|
5057
|
+
<span class="group-chevron" [class.open]="!collapsedGroups().has(row.__groupKey)">▶</span>
|
|
5058
|
+
{{ config.groupBy }}: <strong>{{ row.__groupKey }}</strong>
|
|
5059
|
+
<span class="group-count">({{ row.__count }} items)</span>
|
|
5060
|
+
</button>
|
|
5061
|
+
</td>
|
|
5062
|
+
</tr>
|
|
5063
|
+
} @else {
|
|
5064
|
+
<tr cdkDrag [cdkDragDisabled]="!config.reorderable" (click)="handleRowClick(row)" [class.clickable]="config.rowClick || config.selectionMode === 'single' || config.selectionMode === 'multi'" [class.selected]="selectedRows().has(row)" [class.expanded]="expandedRows().has(row)">
|
|
5065
|
+
@if (config.reorderable) {
|
|
5066
|
+
<td class="drag-cell" (click)="$event.stopPropagation()" cdkDragHandle>
|
|
5067
|
+
<svg viewBox="0 0 24 24" style="width:16px;height:16px;fill:var(--app-text-muted)"><path [attr.d]="iconRegistry.getIcon('menu')"></path></svg>
|
|
5068
|
+
</td>
|
|
5069
|
+
}
|
|
5070
|
+
@if (config.selectionMode === 'checkbox') {
|
|
5071
|
+
<td class="selection-cell" (click)="$event.stopPropagation(); toggleSelection(row)">
|
|
5072
|
+
<input type="checkbox" class="amf-checkbox" [checked]="selectedRows().has(row)" (click)="$event.stopPropagation()" (change)="$event.stopPropagation(); toggleSelection(row)" />
|
|
5073
|
+
</td>
|
|
5074
|
+
}
|
|
5075
|
+
@if (config.expandable) {
|
|
5076
|
+
<td class="expand-cell" (click)="$event.stopPropagation(); toggleRowExpand(row)">
|
|
5077
|
+
<span class="expand-chevron" [class.open]="expandedRows().has(row)">▶</span>
|
|
5078
|
+
</td>
|
|
5079
|
+
}
|
|
5080
|
+
@for (col of visibleColumns(); track col.key) {
|
|
5081
|
+
<td [style.text-align]="col.align || 'left'" (dblclick)="config.inlineEdit && col.editable !== false ? startEdit(row, col.key, $event) : null" [class.editable-cell]="config.inlineEdit && col.editable !== false">
|
|
5082
|
+
@if (isEditing(row, col.key)) {
|
|
5083
|
+
<div class="inline-edit-wrap" (click)="$event.stopPropagation()">
|
|
5084
|
+
<div class="inline-edit-row">
|
|
5085
|
+
@if (col.editType === 'select' && col.editOptions) {
|
|
5086
|
+
<select class="inline-input" [(ngModel)]="editBuffer[col.key]">
|
|
5087
|
+
@for (opt of col.editOptions; track opt.value) { <option [value]="opt.value">{{ opt.label }}</option> }
|
|
5088
|
+
</select>
|
|
5089
|
+
} @else {
|
|
5090
|
+
<input class="inline-input" [type]="col.editType || 'text'" [(ngModel)]="editBuffer[col.key]" (keydown.enter)="commitEdit(row, col.key)" (keydown.escape)="cancelEdit()" />
|
|
5091
|
+
}
|
|
5092
|
+
<div class="inline-edit-actions">
|
|
5093
|
+
<button class="ie-btn ie-save" title="Save (Enter)" (click)="commitEdit(row, col.key)">
|
|
5094
|
+
<svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>
|
|
5095
|
+
</button>
|
|
5096
|
+
<button class="ie-btn ie-cancel" title="Cancel (Esc)" (click)="cancelEdit()">
|
|
5097
|
+
<svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
|
5098
|
+
</button>
|
|
5099
|
+
</div>
|
|
5100
|
+
</div>
|
|
5101
|
+
@if (editError()) {
|
|
5102
|
+
<span class="inline-edit-error">{{ editError() }}</span>
|
|
5103
|
+
}
|
|
5104
|
+
</div>
|
|
5105
|
+
} @else {
|
|
5106
|
+
<amf-cell-renderer [column]="col" [row]="row" [value]="getCellValue(row, col.key)"></amf-cell-renderer>
|
|
5107
|
+
}
|
|
5108
|
+
</td>
|
|
5109
|
+
}
|
|
5110
|
+
@if (config.actions?.length) {
|
|
5111
|
+
<td class="actions-cell">
|
|
5112
|
+
<div class="action-btns">
|
|
5113
|
+
@for (action of config.actions; track action.id) {
|
|
5114
|
+
<button class="action-btn" [class]="action.variant || 'ghost'" [title]="action.label" (click)="handleAction(action, row); $event.stopPropagation()">
|
|
5115
|
+
@if (action.icon) { <svg viewBox="0 0 24 24"><path [attr.d]="iconRegistry.getIcon(action.icon)"></path></svg> } @else { {{ action.label }} }
|
|
5116
|
+
</button>
|
|
5117
|
+
}
|
|
5118
|
+
</div>
|
|
5119
|
+
</td>
|
|
5120
|
+
}
|
|
5121
|
+
</tr>
|
|
5122
|
+
@if (config.expandable && expandedRows().has(row)) {
|
|
5123
|
+
<tr class="expanded-row">
|
|
5124
|
+
<td [attr.colspan]="visibleColumns().length + (config.reorderable ? 1 : 0) + (config.selectionMode === 'checkbox' ? 1 : 0) + 1 + (config.actions?.length ? 1 : 0)" class="expanded-content">
|
|
5125
|
+
@if (config.expandSection) {
|
|
5126
|
+
<div class="expand-section">Row detail: {{ row | json }}</div>
|
|
5127
|
+
} @else {
|
|
5128
|
+
<div class="expand-section">
|
|
5129
|
+
@for (col of visibleColumns(); track col.key) {
|
|
5130
|
+
<div class="expand-field"><span class="expand-label">{{ col.label }}:</span> <span>{{ getCellValue(row, col.key) }}</span></div>
|
|
5131
|
+
}
|
|
5132
|
+
</div>
|
|
5133
|
+
}
|
|
5134
|
+
</td>
|
|
5135
|
+
</tr>
|
|
5136
|
+
}
|
|
5137
|
+
}
|
|
5138
|
+
} @empty { <tr><td [attr.colspan]="visibleColumns().length + (config.actions?.length ? 1 : 0)" class="empty-state">{{ config.emptyMessage || 'No data found.' }}</td></tr> }
|
|
5139
|
+
@if (config.aggregates?.length) {
|
|
5140
|
+
<tr class="aggregate-row">
|
|
5141
|
+
@if (config.reorderable) { <td></td> }
|
|
5142
|
+
@if (config.selectionMode === 'checkbox') { <td></td> }
|
|
5143
|
+
@if (config.expandable) { <td></td> }
|
|
5144
|
+
@for (col of visibleColumns(); track col.key) {
|
|
5145
|
+
<td class="aggregate-cell" [style.text-align]="col.align || 'right'">
|
|
5146
|
+
@if (getAggregate(col.key); as agg) { <span class="agg-value">{{ agg.label ? agg.label + ': ' : '' }}{{ agg.value }}</span> }
|
|
5147
|
+
</td>
|
|
5148
|
+
}
|
|
5149
|
+
@if (config.actions?.length) { <td></td> }
|
|
5150
|
+
</tr>
|
|
5151
|
+
}
|
|
5152
|
+
</tbody>
|
|
5153
|
+
</table>
|
|
5154
|
+
</div>
|
|
5155
|
+
@if (config.pagination?.enabled) {
|
|
5156
|
+
<div class="table-footer">
|
|
5157
|
+
<div class="footer-left">
|
|
5158
|
+
<span class="results-count">Showing {{ paginatedData().length }} of {{ filteredData().length }} @if (config.pagination?.showTotal) { (total: {{ allData().length }}) }</span>
|
|
5159
|
+
@if ((config.pagination?.pageSizeOptions || [5, 10, 25, 50]).length > 1) {
|
|
5160
|
+
<div class="page-size-wrap">
|
|
5161
|
+
<label class="page-size-label">Rows:</label>
|
|
5162
|
+
<select class="page-size-select" [ngModel]="activePageSize()" (ngModelChange)="setPageSize($event)">
|
|
5163
|
+
@for (opt of config.pagination?.pageSizeOptions || [5, 10, 25, 50]; track opt) {
|
|
5164
|
+
<option [value]="opt">{{ opt }}</option>
|
|
5165
|
+
}
|
|
5166
|
+
</select>
|
|
5167
|
+
</div>
|
|
5168
|
+
}
|
|
5169
|
+
</div>
|
|
5170
|
+
<div class="pagination">
|
|
5171
|
+
<button class="btn-page-nav" [disabled]="currentPage() <= 1" (click)="currentPage.set(currentPage() - 1)">Previous</button>
|
|
5172
|
+
@for (p of pageNumbers(); track p) { <button class="btn-page" [class.active]="p === currentPage()" (click)="currentPage.set(p)">{{ p }}</button> }
|
|
5173
|
+
<button class="btn-page-nav" [disabled]="currentPage() >= totalPages()" (click)="currentPage.set(currentPage() + 1)">Next</button>
|
|
5174
|
+
</div>
|
|
5175
|
+
</div>
|
|
5176
|
+
}
|
|
5177
|
+
</div>
|
|
5178
5178
|
`, styles: [".amf-table-card{background:var(--app-surface);border:1px solid var(--app-border);border-radius:16px;overflow:hidden;box-shadow:0 1px 3px #0000000d}.table-header{padding:16px 20px;display:flex;justify-content:space-between;align-items:center;gap:16px;border-bottom:1px solid var(--app-border);flex-wrap:wrap}.table-header-left,.table-header-right{display:flex;align-items:center;gap:12px}.search-box{position:relative;min-width:240px}.search-icon{position:absolute;left:12px;top:50%;transform:translateY(-50%);width:16px;height:16px;fill:var(--app-text-muted)}.search-box input{width:100%;padding:8px 12px 8px 36px;border:1px solid var(--app-border);border-radius:8px;font-size:.8125rem;outline:none;background:var(--glass-bg);color:var(--app-text)}.search-box input:focus{border-color:var(--app-primary)}.filter-select{padding:8px 12px;border:1px solid var(--app-border);border-radius:8px;font-size:.8125rem;outline:none;background:var(--glass-bg);color:var(--app-text);color-scheme:dark}.filter-select option{background-color:#1e1e2d;color:#fff}:host-context([data-color-scheme=\"light\"]) .filter-select{color-scheme:light}:host-context([data-color-scheme=\"light\"]) .filter-select option{background-color:#fff;color:#000}.table-wrapper{width:100%;overflow-x:auto}.data-table{width:100%;border-collapse:collapse;white-space:normal;word-break:break-word}.data-table th{background:var(--app-bg);padding:10px 20px;font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--app-text-muted);border-bottom:1px solid var(--app-border);-webkit-user-select:none;user-select:none}.data-table th.sortable{cursor:pointer}.data-table th.sortable:hover{color:var(--app-primary)}.sort-indicator{margin-left:4px;font-size:.75rem}.data-table td{padding:14px 20px;border-bottom:1px solid var(--app-border);font-size:.875rem;color:var(--app-text)}.data-table.hoverable tbody tr:hover{background:var(--glass-bg)}.data-table.striped tbody tr:nth-child(2n){background:var(--glass-bg)}.variant-striped .data-table tbody tr:nth-child(2n){background:var(--glass-bg)}.variant-borderless{border:none!important;box-shadow:none!important;background:transparent!important}.variant-borderless .table-header{border-bottom:none;padding:0 0 16px}.variant-borderless .data-table th{background:transparent;border-bottom:2px solid var(--app-border)}.variant-borderless .data-table td{border-bottom:1px dashed var(--app-border)}.variant-borderless .table-footer{border-top:none;background:transparent;padding:16px 0 0}.variant-glass{background:var(--glass-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));border:1px solid var(--glass-border);box-shadow:var(--glass-shadow-sm)}.variant-glass .table-header,.variant-glass .table-footer,.variant-glass .data-table th{background:transparent;border-color:var(--glass-border)}.variant-glass .data-table td{border-bottom:1px solid var(--glass-border)}.variant-elevated{box-shadow:0 20px 40px var(--glass-shadow);transform:translateY(-2px);transition:all .3s ease}.variant-compact .table-header{padding:12px 16px}.variant-compact .data-table th{padding:8px 16px;font-size:.625rem}.variant-compact .data-table td{padding:8px 16px;font-size:.8125rem}.variant-compact .table-footer{padding:8px 16px}tr.clickable{cursor:pointer}.amf-checkbox{width:16px;height:16px;cursor:pointer;accent-color:var(--app-primary)}.data-table tbody tr.selected{background:#3b82f626!important}.actions-col{text-align:right!important;width:120px}.actions-cell{text-align:right}.action-btns{display:flex;justify-content:flex-end;gap:6px}.action-btn{width:30px;height:30px;border-radius:6px;border:1px solid var(--app-border);background:transparent;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s}.action-btn svg{width:14px;height:14px;fill:var(--app-text-muted)}.action-btn:hover{border-color:var(--app-primary)}.action-btn:hover svg{fill:var(--app-primary)}.action-btn.danger:hover{border-color:#f43f5e}.action-btn.danger:hover svg{fill:#f43f5e}.btn-primary{background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff;border:none;padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;cursor:pointer;display:flex;align-items:center;gap:6px;transition:all .2s}.btn-primary:hover{transform:translateY(-1px);box-shadow:0 4px 12px var(--app-glow)}.btn-icon{width:16px;height:16px;fill:currentColor}.btn-sm{padding:6px 12px;font-size:.75rem;border-radius:6px}.btn-ghost{background:transparent;border:1px solid var(--app-border);color:var(--app-text);padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;display:flex;align-items:center;gap:6px;cursor:pointer;transition:all .2s}.btn-ghost:hover{background:var(--glass-bg-hover);color:var(--app-primary)}.export-container{position:relative}.export-menu{position:absolute;top:calc(100% + 8px);right:0;background:var(--app-surface);border:1px solid var(--app-border);border-radius:12px;box-shadow:0 10px 40px #00000080;min-width:160px;z-index:100;overflow:hidden;animation:slideInDown .2s ease-out backwards}.export-menu .dropdown-item{padding:10px 16px;font-size:.8125rem;font-weight:500;cursor:pointer;color:var(--app-text);transition:background .2s}.export-menu .dropdown-item:hover{background:var(--glass-bg-hover);color:var(--app-primary)}.empty-state{text-align:center;padding:40px!important;color:var(--app-text-muted)}.table-footer{padding:12px 20px;display:flex;justify-content:space-between;align-items:center;background:var(--app-bg);border-top:1px solid var(--app-border)}.footer-left{display:flex;align-items:center;gap:16px}.results-count{font-size:.75rem;color:var(--app-text-muted)}.page-size-wrap{display:flex;align-items:center;gap:6px}.page-size-label{font-size:.75rem;color:var(--app-text-muted);white-space:nowrap}.page-size-select{padding:4px 8px;border:1px solid var(--app-border);border-radius:6px;font-size:.75rem;background:var(--glass-bg);color:var(--app-text);outline:none;cursor:pointer;color-scheme:dark}.page-size-select option{background-color:#1a1a2e;color:#fff}:host-context([data-color-scheme=\"light\"]) .page-size-select{color-scheme:light}:host-context([data-color-scheme=\"light\"]) .page-size-select option{background-color:#fff;color:#000}.pagination{display:flex;gap:4px}.btn-page,.btn-page-nav{padding:6px 10px;border:1px solid var(--app-border);background:transparent;border-radius:6px;font-size:.75rem;font-weight:500;color:var(--app-text);cursor:pointer}.btn-page.active{background:var(--app-primary);border-color:var(--app-primary);color:#fff}.btn-page-nav:disabled{opacity:.4;cursor:not-allowed}.editable-cell{position:relative}.editable-cell:hover{background:#3b82f614;cursor:text}.inline-edit-wrap{display:flex;flex-direction:column;gap:4px;min-width:0}.inline-edit-row{display:flex;align-items:center;gap:4px}.inline-input{flex:1;min-width:0;padding:5px 8px;border:1.5px solid var(--app-primary);border-radius:6px;background:var(--app-surface);color:var(--app-text);font-size:.875rem;outline:none}.inline-input.input-invalid{border-color:#f43f5e}.inline-edit-error{font-size:.6875rem;color:#f43f5e;font-weight:500;padding:0 2px;animation:fadeIn .15s ease-out}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.inline-edit-actions{display:flex;gap:3px;flex-shrink:0}.ie-btn{width:26px;height:26px;border-radius:5px;border:none;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:opacity .15s}.ie-btn svg{width:14px;height:14px;fill:currentColor}.ie-btn:hover{opacity:.85}.ie-save{background:#22c55e;color:#fff}.ie-cancel{background:var(--app-border);color:var(--app-text-muted)}select.inline-input{color-scheme:dark;cursor:pointer}select.inline-input option{background-color:#1a1a2e;color:#fff}:host-context([data-color-scheme=\"light\"]) select.inline-input{color-scheme:light}:host-context([data-color-scheme=\"light\"]) select.inline-input option{background-color:#fff;color:#000}.expand-cell{width:36px;text-align:center;cursor:pointer}.expand-chevron{display:inline-block;transition:transform .2s;font-size:.625rem;color:var(--app-text-muted)}.expand-chevron.open{transform:rotate(90deg)}.expanded-row td,.expanded-content{padding:0!important}.expand-section{padding:14px 24px;display:flex;flex-wrap:wrap;gap:16px;background:var(--glass-bg);animation:fadeInUp .2s ease-out}.expand-field{display:flex;gap:8px;font-size:.8125rem}.expand-label{color:var(--app-text-muted);font-weight:600}.group-header-row td{background:var(--app-bg)}.group-toggle{display:flex;align-items:center;gap:8px;background:none;border:none;color:var(--app-text);cursor:pointer;font-size:.8125rem;padding:8px 16px}.group-chevron{display:inline-block;font-size:.625rem;transition:transform .2s;color:var(--app-text-muted)}.group-chevron.open{transform:rotate(90deg)}.group-count{color:var(--app-text-muted);font-size:.75rem}.aggregate-row td{background:var(--app-bg);border-top:2px solid var(--app-border)}.aggregate-cell{padding:10px 20px!important}.agg-value{font-size:.8125rem;font-weight:700;color:var(--app-primary)}\n"] }]
|
|
5179
5179
|
}], propDecorators: { config: [{
|
|
5180
5180
|
type: Input
|
|
@@ -5195,45 +5195,45 @@ class CardSectionComponent {
|
|
|
5195
5195
|
get trustedContent() {
|
|
5196
5196
|
return this.sanitizer.bypassSecurityTrustHtml(this.config.content || '');
|
|
5197
5197
|
}
|
|
5198
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
5199
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
5200
|
-
<div class="amf-card" [class]="'variant-' + (config.variant || 'glass')">
|
|
5201
|
-
@if (config.title) { <h2 class="card-title">{{ config.title }}</h2> }
|
|
5202
|
-
@if (config.content) { <div class="card-content" [innerHTML]="trustedContent"></div> }
|
|
5203
|
-
@if (config.sections?.length) {
|
|
5204
|
-
<div class="card-sections">
|
|
5205
|
-
@for (nested of config.sections; track nested.id) {
|
|
5206
|
-
<amf-renderer [section]="nested" [context]="context" class="card-nested-section"></amf-renderer>
|
|
5207
|
-
}
|
|
5208
|
-
</div>
|
|
5209
|
-
}
|
|
5210
|
-
@if (config.actions?.length) {
|
|
5211
|
-
<div class="card-actions">
|
|
5212
|
-
@for (action of config.actions; track action.label) { <button [class]="'btn-' + (action.variant || 'secondary')" (click)="actionDispatcher.dispatch(action.action, context)">{{ action.label }}</button> }
|
|
5213
|
-
</div>
|
|
5214
|
-
}
|
|
5215
|
-
</div>
|
|
5198
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CardSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5199
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: CardSectionComponent, isStandalone: true, selector: "amf-card", inputs: { config: "config", context: "context" }, ngImport: i0, template: `
|
|
5200
|
+
<div class="amf-card" [class]="'variant-' + (config.variant || 'glass')">
|
|
5201
|
+
@if (config.title) { <h2 class="card-title">{{ config.title }}</h2> }
|
|
5202
|
+
@if (config.content) { <div class="card-content" [innerHTML]="trustedContent"></div> }
|
|
5203
|
+
@if (config.sections?.length) {
|
|
5204
|
+
<div class="card-sections">
|
|
5205
|
+
@for (nested of config.sections; track nested.id) {
|
|
5206
|
+
<amf-renderer [section]="nested" [context]="context" class="card-nested-section"></amf-renderer>
|
|
5207
|
+
}
|
|
5208
|
+
</div>
|
|
5209
|
+
}
|
|
5210
|
+
@if (config.actions?.length) {
|
|
5211
|
+
<div class="card-actions">
|
|
5212
|
+
@for (action of config.actions; track action.label) { <button [class]="'btn-' + (action.variant || 'secondary')" (click)="actionDispatcher.dispatch(action.action, context)">{{ action.label }}</button> }
|
|
5213
|
+
</div>
|
|
5214
|
+
}
|
|
5215
|
+
</div>
|
|
5216
5216
|
`, isInline: true, styles: [".amf-card{background:var(--glass-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));border:1px solid var(--glass-border);border-radius:16px;padding:24px;box-shadow:var(--glass-shadow-sm);transition:all .3s cubic-bezier(.4,0,.2,1)}.amf-card:hover{background:var(--glass-bg-hover);border-color:var(--glass-border-light);box-shadow:var(--glass-shadow);transform:translateY(-2px)}.variant-default{background:var(--app-surface);border:1px solid var(--app-border);backdrop-filter:none;-webkit-backdrop-filter:none}.variant-outlined{background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}.variant-elevated{box-shadow:0 20px 40px var(--glass-shadow);transform:translateY(-4px)}.variant-gradient{background:linear-gradient(135deg,#3b82f626,#8b5cf626);border:1px solid rgba(139,92,246,.3)}.card-title{font-size:1.25rem;margin-bottom:16px}.card-content{color:var(--app-text-muted);font-size:.9375rem;line-height:1.6}.card-sections{display:flex;flex-direction:column;gap:16px;margin-top:16px}.card-nested-section{display:block}.card-actions{margin-top:20px;display:flex;gap:12px}.btn-secondary{background:var(--glass-bg);border:1px solid var(--app-border);color:var(--app-text);padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;cursor:pointer;transition:all .2s}.btn-secondary:hover{background:var(--glass-bg-hover)}.btn-primary{background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff;border:none;padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;cursor:pointer;transition:all .2s}.btn-primary:hover{transform:translateY(-1px);box-shadow:0 4px 12px var(--app-glow)}.btn-danger{background:linear-gradient(135deg,#ef4444,#dc2626);color:#fff;border:none;padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;cursor:pointer;transition:all .2s}.btn-danger:hover{transform:translateY(-1px);box-shadow:0 4px 12px #ef444466}.btn-success{background:linear-gradient(135deg,#10b981,#059669);color:#fff;border:none;padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;cursor:pointer;transition:all .2s}.btn-success:hover{transform:translateY(-1px);box-shadow:0 4px 12px #10b98166}.btn-ghost{background:transparent;border:1px solid transparent;color:var(--app-text-muted);padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;cursor:pointer;transition:all .2s}.btn-ghost:hover{background:#ffffff0d;color:var(--app-text)}\n"], dependencies: [{ kind: "component", type: MetaRendererComponent, selector: "amf-renderer", inputs: ["section", "context"] }] });
|
|
5217
5217
|
}
|
|
5218
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
5218
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CardSectionComponent, decorators: [{
|
|
5219
5219
|
type: Component,
|
|
5220
|
-
args: [{ selector: 'amf-card', standalone: true, imports: [MetaRendererComponent], template: `
|
|
5221
|
-
<div class="amf-card" [class]="'variant-' + (config.variant || 'glass')">
|
|
5222
|
-
@if (config.title) { <h2 class="card-title">{{ config.title }}</h2> }
|
|
5223
|
-
@if (config.content) { <div class="card-content" [innerHTML]="trustedContent"></div> }
|
|
5224
|
-
@if (config.sections?.length) {
|
|
5225
|
-
<div class="card-sections">
|
|
5226
|
-
@for (nested of config.sections; track nested.id) {
|
|
5227
|
-
<amf-renderer [section]="nested" [context]="context" class="card-nested-section"></amf-renderer>
|
|
5228
|
-
}
|
|
5229
|
-
</div>
|
|
5230
|
-
}
|
|
5231
|
-
@if (config.actions?.length) {
|
|
5232
|
-
<div class="card-actions">
|
|
5233
|
-
@for (action of config.actions; track action.label) { <button [class]="'btn-' + (action.variant || 'secondary')" (click)="actionDispatcher.dispatch(action.action, context)">{{ action.label }}</button> }
|
|
5234
|
-
</div>
|
|
5235
|
-
}
|
|
5236
|
-
</div>
|
|
5220
|
+
args: [{ selector: 'amf-card', standalone: true, imports: [MetaRendererComponent], template: `
|
|
5221
|
+
<div class="amf-card" [class]="'variant-' + (config.variant || 'glass')">
|
|
5222
|
+
@if (config.title) { <h2 class="card-title">{{ config.title }}</h2> }
|
|
5223
|
+
@if (config.content) { <div class="card-content" [innerHTML]="trustedContent"></div> }
|
|
5224
|
+
@if (config.sections?.length) {
|
|
5225
|
+
<div class="card-sections">
|
|
5226
|
+
@for (nested of config.sections; track nested.id) {
|
|
5227
|
+
<amf-renderer [section]="nested" [context]="context" class="card-nested-section"></amf-renderer>
|
|
5228
|
+
}
|
|
5229
|
+
</div>
|
|
5230
|
+
}
|
|
5231
|
+
@if (config.actions?.length) {
|
|
5232
|
+
<div class="card-actions">
|
|
5233
|
+
@for (action of config.actions; track action.label) { <button [class]="'btn-' + (action.variant || 'secondary')" (click)="actionDispatcher.dispatch(action.action, context)">{{ action.label }}</button> }
|
|
5234
|
+
</div>
|
|
5235
|
+
}
|
|
5236
|
+
</div>
|
|
5237
5237
|
`, styles: [".amf-card{background:var(--glass-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));border:1px solid var(--glass-border);border-radius:16px;padding:24px;box-shadow:var(--glass-shadow-sm);transition:all .3s cubic-bezier(.4,0,.2,1)}.amf-card:hover{background:var(--glass-bg-hover);border-color:var(--glass-border-light);box-shadow:var(--glass-shadow);transform:translateY(-2px)}.variant-default{background:var(--app-surface);border:1px solid var(--app-border);backdrop-filter:none;-webkit-backdrop-filter:none}.variant-outlined{background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}.variant-elevated{box-shadow:0 20px 40px var(--glass-shadow);transform:translateY(-4px)}.variant-gradient{background:linear-gradient(135deg,#3b82f626,#8b5cf626);border:1px solid rgba(139,92,246,.3)}.card-title{font-size:1.25rem;margin-bottom:16px}.card-content{color:var(--app-text-muted);font-size:.9375rem;line-height:1.6}.card-sections{display:flex;flex-direction:column;gap:16px;margin-top:16px}.card-nested-section{display:block}.card-actions{margin-top:20px;display:flex;gap:12px}.btn-secondary{background:var(--glass-bg);border:1px solid var(--app-border);color:var(--app-text);padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;cursor:pointer;transition:all .2s}.btn-secondary:hover{background:var(--glass-bg-hover)}.btn-primary{background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff;border:none;padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;cursor:pointer;transition:all .2s}.btn-primary:hover{transform:translateY(-1px);box-shadow:0 4px 12px var(--app-glow)}.btn-danger{background:linear-gradient(135deg,#ef4444,#dc2626);color:#fff;border:none;padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;cursor:pointer;transition:all .2s}.btn-danger:hover{transform:translateY(-1px);box-shadow:0 4px 12px #ef444466}.btn-success{background:linear-gradient(135deg,#10b981,#059669);color:#fff;border:none;padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;cursor:pointer;transition:all .2s}.btn-success:hover{transform:translateY(-1px);box-shadow:0 4px 12px #10b98166}.btn-ghost{background:transparent;border:1px solid transparent;color:var(--app-text-muted);padding:8px 16px;border-radius:8px;font-weight:600;font-size:.8125rem;cursor:pointer;transition:all .2s}.btn-ghost:hover{background:#ffffff0d;color:var(--app-text)}\n"] }]
|
|
5238
5238
|
}], propDecorators: { config: [{
|
|
5239
5239
|
type: Input
|
|
@@ -5249,47 +5249,47 @@ class StatsGridSectionComponent {
|
|
|
5249
5249
|
context = {};
|
|
5250
5250
|
iconRegistry = inject(IconRegistryService);
|
|
5251
5251
|
get gridCols() { return `repeat(auto-fit, minmax(280px, 1fr))`; }
|
|
5252
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
5253
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
5254
|
-
<div class="amf-stats-grid" [style.grid-template-columns]="gridCols" [class]="'variant-' + (config.variant || 'glass')">
|
|
5255
|
-
@for (stat of config.stats; track stat.label; let i = $index) {
|
|
5256
|
-
<div class="stat-card" [style.animation-delay]="(i * 0.1) + 's'">
|
|
5257
|
-
<div class="stat-glow" [style.background]="stat.glowColor || stat.color"></div>
|
|
5258
|
-
@if (stat.icon) {
|
|
5259
|
-
<div class="stat-icon" [style.color]="stat.color" [style.background]="stat.bgColor">
|
|
5260
|
-
<svg viewBox="0 0 24 24"><path [attr.d]="iconRegistry.getIcon(stat.icon)"></path></svg>
|
|
5261
|
-
</div>
|
|
5262
|
-
}
|
|
5263
|
-
<div class="stat-data">
|
|
5264
|
-
<span class="stat-label">{{ stat.label }}</span>
|
|
5265
|
-
<span class="stat-value">{{ stat.value }}</span>
|
|
5266
|
-
@if (stat.trend) { <span class="stat-trend" [class.positive]="stat.trendPositive" [class.negative]="!stat.trendPositive">{{ stat.trend }}</span> }
|
|
5267
|
-
</div>
|
|
5268
|
-
</div>
|
|
5269
|
-
}
|
|
5270
|
-
</div>
|
|
5252
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: StatsGridSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5253
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: StatsGridSectionComponent, isStandalone: true, selector: "amf-stats-grid", inputs: { config: "config", context: "context" }, ngImport: i0, template: `
|
|
5254
|
+
<div class="amf-stats-grid" [style.grid-template-columns]="gridCols" [class]="'variant-' + (config.variant || 'glass')">
|
|
5255
|
+
@for (stat of config.stats; track stat.label; let i = $index) {
|
|
5256
|
+
<div class="stat-card" [style.animation-delay]="(i * 0.1) + 's'">
|
|
5257
|
+
<div class="stat-glow" [style.background]="stat.glowColor || stat.color"></div>
|
|
5258
|
+
@if (stat.icon) {
|
|
5259
|
+
<div class="stat-icon" [style.color]="stat.color" [style.background]="stat.bgColor">
|
|
5260
|
+
<svg viewBox="0 0 24 24"><path [attr.d]="iconRegistry.getIcon(stat.icon)"></path></svg>
|
|
5261
|
+
</div>
|
|
5262
|
+
}
|
|
5263
|
+
<div class="stat-data">
|
|
5264
|
+
<span class="stat-label">{{ stat.label }}</span>
|
|
5265
|
+
<span class="stat-value">{{ stat.value }}</span>
|
|
5266
|
+
@if (stat.trend) { <span class="stat-trend" [class.positive]="stat.trendPositive" [class.negative]="!stat.trendPositive">{{ stat.trend }}</span> }
|
|
5267
|
+
</div>
|
|
5268
|
+
</div>
|
|
5269
|
+
}
|
|
5270
|
+
</div>
|
|
5271
5271
|
`, isInline: true, styles: [".amf-stats-grid{display:grid;gap:20px}.stat-card{background:var(--glass-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));border:1px solid var(--glass-border);border-radius:16px;padding:24px;display:flex;align-items:center;gap:20px;position:relative;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1);animation:fadeInUp .5s ease-out backwards}.stat-card:hover{background:var(--glass-bg-hover);border-color:var(--glass-border-light);transform:translateY(-4px);box-shadow:var(--glass-shadow)}.variant-default .stat-card{background:var(--app-surface);border:1px solid var(--app-border);backdrop-filter:none;-webkit-backdrop-filter:none}.variant-compact .stat-card{padding:14px 16px;gap:14px;min-height:80px}.variant-compact .stat-icon{width:38px;height:38px;border-radius:10px}.variant-compact .stat-icon svg{width:18px;height:18px}.variant-compact .stat-value{font-size:1.25rem;font-weight:800}.variant-compact .stat-glow{width:60px;height:60px;top:-10px;right:-10px}.variant-outlined .stat-card{background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none}.variant-elevated .stat-card{box-shadow:0 20px 40px var(--glass-shadow);transform:translateY(-2px);border-color:var(--glass-border-light)}.stat-glow{position:absolute;width:100px;height:100px;border-radius:50%;filter:blur(40px);opacity:.15;top:-20px;right:-20px;pointer-events:none;transition:opacity .3s}.stat-card:hover .stat-glow{opacity:.3}.stat-icon{width:52px;height:52px;border-radius:14px;display:flex;align-items:center;justify-content:center;flex-shrink:0}.stat-icon svg{width:26px;height:26px;fill:currentColor}.stat-data{display:flex;flex-direction:column}.stat-label{font-size:.8125rem;color:var(--app-text-muted);font-weight:500}.stat-value{font-size:1.5rem;font-weight:700;color:var(--app-text);margin:2px 0}.stat-trend{font-size:.75rem;font-weight:600}.stat-trend.positive{color:#34d399}.stat-trend.negative{color:#fb7185}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}\n"] });
|
|
5272
5272
|
}
|
|
5273
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
5273
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: StatsGridSectionComponent, decorators: [{
|
|
5274
5274
|
type: Component,
|
|
5275
|
-
args: [{ selector: 'amf-stats-grid', standalone: true, imports: [], template: `
|
|
5276
|
-
<div class="amf-stats-grid" [style.grid-template-columns]="gridCols" [class]="'variant-' + (config.variant || 'glass')">
|
|
5277
|
-
@for (stat of config.stats; track stat.label; let i = $index) {
|
|
5278
|
-
<div class="stat-card" [style.animation-delay]="(i * 0.1) + 's'">
|
|
5279
|
-
<div class="stat-glow" [style.background]="stat.glowColor || stat.color"></div>
|
|
5280
|
-
@if (stat.icon) {
|
|
5281
|
-
<div class="stat-icon" [style.color]="stat.color" [style.background]="stat.bgColor">
|
|
5282
|
-
<svg viewBox="0 0 24 24"><path [attr.d]="iconRegistry.getIcon(stat.icon)"></path></svg>
|
|
5283
|
-
</div>
|
|
5284
|
-
}
|
|
5285
|
-
<div class="stat-data">
|
|
5286
|
-
<span class="stat-label">{{ stat.label }}</span>
|
|
5287
|
-
<span class="stat-value">{{ stat.value }}</span>
|
|
5288
|
-
@if (stat.trend) { <span class="stat-trend" [class.positive]="stat.trendPositive" [class.negative]="!stat.trendPositive">{{ stat.trend }}</span> }
|
|
5289
|
-
</div>
|
|
5290
|
-
</div>
|
|
5291
|
-
}
|
|
5292
|
-
</div>
|
|
5275
|
+
args: [{ selector: 'amf-stats-grid', standalone: true, imports: [], template: `
|
|
5276
|
+
<div class="amf-stats-grid" [style.grid-template-columns]="gridCols" [class]="'variant-' + (config.variant || 'glass')">
|
|
5277
|
+
@for (stat of config.stats; track stat.label; let i = $index) {
|
|
5278
|
+
<div class="stat-card" [style.animation-delay]="(i * 0.1) + 's'">
|
|
5279
|
+
<div class="stat-glow" [style.background]="stat.glowColor || stat.color"></div>
|
|
5280
|
+
@if (stat.icon) {
|
|
5281
|
+
<div class="stat-icon" [style.color]="stat.color" [style.background]="stat.bgColor">
|
|
5282
|
+
<svg viewBox="0 0 24 24"><path [attr.d]="iconRegistry.getIcon(stat.icon)"></path></svg>
|
|
5283
|
+
</div>
|
|
5284
|
+
}
|
|
5285
|
+
<div class="stat-data">
|
|
5286
|
+
<span class="stat-label">{{ stat.label }}</span>
|
|
5287
|
+
<span class="stat-value">{{ stat.value }}</span>
|
|
5288
|
+
@if (stat.trend) { <span class="stat-trend" [class.positive]="stat.trendPositive" [class.negative]="!stat.trendPositive">{{ stat.trend }}</span> }
|
|
5289
|
+
</div>
|
|
5290
|
+
</div>
|
|
5291
|
+
}
|
|
5292
|
+
</div>
|
|
5293
5293
|
`, styles: [".amf-stats-grid{display:grid;gap:20px}.stat-card{background:var(--glass-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));border:1px solid var(--glass-border);border-radius:16px;padding:24px;display:flex;align-items:center;gap:20px;position:relative;overflow:hidden;transition:all .3s cubic-bezier(.4,0,.2,1);animation:fadeInUp .5s ease-out backwards}.stat-card:hover{background:var(--glass-bg-hover);border-color:var(--glass-border-light);transform:translateY(-4px);box-shadow:var(--glass-shadow)}.variant-default .stat-card{background:var(--app-surface);border:1px solid var(--app-border);backdrop-filter:none;-webkit-backdrop-filter:none}.variant-compact .stat-card{padding:14px 16px;gap:14px;min-height:80px}.variant-compact .stat-icon{width:38px;height:38px;border-radius:10px}.variant-compact .stat-icon svg{width:18px;height:18px}.variant-compact .stat-value{font-size:1.25rem;font-weight:800}.variant-compact .stat-glow{width:60px;height:60px;top:-10px;right:-10px}.variant-outlined .stat-card{background:transparent;backdrop-filter:none;-webkit-backdrop-filter:none}.variant-elevated .stat-card{box-shadow:0 20px 40px var(--glass-shadow);transform:translateY(-2px);border-color:var(--glass-border-light)}.stat-glow{position:absolute;width:100px;height:100px;border-radius:50%;filter:blur(40px);opacity:.15;top:-20px;right:-20px;pointer-events:none;transition:opacity .3s}.stat-card:hover .stat-glow{opacity:.3}.stat-icon{width:52px;height:52px;border-radius:14px;display:flex;align-items:center;justify-content:center;flex-shrink:0}.stat-icon svg{width:26px;height:26px;fill:currentColor}.stat-data{display:flex;flex-direction:column}.stat-label{font-size:.8125rem;color:var(--app-text-muted);font-weight:500}.stat-value{font-size:1.5rem;font-weight:700;color:var(--app-text);margin:2px 0}.stat-trend{font-size:.75rem;font-weight:600}.stat-trend.positive{color:#34d399}.stat-trend.negative{color:#fb7185}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
5294
5294
|
}], propDecorators: { config: [{
|
|
5295
5295
|
type: Input
|
|
@@ -5313,41 +5313,41 @@ class PageHeaderSectionComponent {
|
|
|
5313
5313
|
}
|
|
5314
5314
|
return this.config.title;
|
|
5315
5315
|
}
|
|
5316
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
5317
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
5318
|
-
<header class="amf-page-header">
|
|
5319
|
-
<div class="header-content">
|
|
5320
|
-
<h1>{{ resolvedTitle }}</h1>
|
|
5321
|
-
@if (config.subtitle) { <p>{{ config.subtitle }}</p> }
|
|
5322
|
-
</div>
|
|
5323
|
-
<div class="header-actions">
|
|
5324
|
-
@for (action of config.actions || []; track action.label) {
|
|
5325
|
-
<button [class]="'btn-' + (action.variant || 'primary')" (click)="actionDispatcher.dispatch(action.action, context)">
|
|
5326
|
-
@if (action.icon) { <svg viewBox="0 0 24 24" class="btn-icon"><path [attr.d]="iconRegistry.getIcon(action.icon)"></path></svg> }
|
|
5327
|
-
{{ action.label }}
|
|
5328
|
-
</button>
|
|
5329
|
-
}
|
|
5330
|
-
</div>
|
|
5331
|
-
</header>
|
|
5316
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: PageHeaderSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5317
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: PageHeaderSectionComponent, isStandalone: true, selector: "amf-page-header", inputs: { config: "config", context: "context" }, ngImport: i0, template: `
|
|
5318
|
+
<header class="amf-page-header">
|
|
5319
|
+
<div class="header-content">
|
|
5320
|
+
<h1>{{ resolvedTitle }}</h1>
|
|
5321
|
+
@if (config.subtitle) { <p>{{ config.subtitle }}</p> }
|
|
5322
|
+
</div>
|
|
5323
|
+
<div class="header-actions">
|
|
5324
|
+
@for (action of config.actions || []; track action.label) {
|
|
5325
|
+
<button [class]="'btn-' + (action.variant || 'primary')" (click)="actionDispatcher.dispatch(action.action, context)">
|
|
5326
|
+
@if (action.icon) { <svg viewBox="0 0 24 24" class="btn-icon"><path [attr.d]="iconRegistry.getIcon(action.icon)"></path></svg> }
|
|
5327
|
+
{{ action.label }}
|
|
5328
|
+
</button>
|
|
5329
|
+
}
|
|
5330
|
+
</div>
|
|
5331
|
+
</header>
|
|
5332
5332
|
`, isInline: true, styles: [".amf-page-header{display:flex;justify-content:space-between;align-items:center;animation:fadeInUp .4s ease-out}.header-content h1{font-size:1.875rem;margin-bottom:4px}.header-content p{color:var(--app-text-muted);font-size:.9375rem}.header-actions{display:flex;gap:12px}.btn-primary{background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff;border:none;padding:10px 20px;border-radius:10px;font-weight:600;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .3s}.btn-primary:hover{transform:translateY(-2px);box-shadow:0 8px 24px -4px var(--app-glow)}.btn-secondary{background:var(--glass-bg);border:1px solid var(--app-border);color:var(--app-text);padding:10px 20px;border-radius:10px;font-weight:600;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .2s}.btn-secondary:hover{background:var(--glass-bg-hover)}.btn-ghost{background:transparent;border:none;color:var(--app-text-muted);padding:10px 20px;border-radius:10px;font-weight:600;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .2s}.btn-ghost:hover{color:var(--app-primary);background:var(--glass-bg)}.btn-icon{width:18px;height:18px;fill:currentColor}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}\n"] });
|
|
5333
5333
|
}
|
|
5334
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
5334
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: PageHeaderSectionComponent, decorators: [{
|
|
5335
5335
|
type: Component,
|
|
5336
|
-
args: [{ selector: 'amf-page-header', standalone: true, imports: [], template: `
|
|
5337
|
-
<header class="amf-page-header">
|
|
5338
|
-
<div class="header-content">
|
|
5339
|
-
<h1>{{ resolvedTitle }}</h1>
|
|
5340
|
-
@if (config.subtitle) { <p>{{ config.subtitle }}</p> }
|
|
5341
|
-
</div>
|
|
5342
|
-
<div class="header-actions">
|
|
5343
|
-
@for (action of config.actions || []; track action.label) {
|
|
5344
|
-
<button [class]="'btn-' + (action.variant || 'primary')" (click)="actionDispatcher.dispatch(action.action, context)">
|
|
5345
|
-
@if (action.icon) { <svg viewBox="0 0 24 24" class="btn-icon"><path [attr.d]="iconRegistry.getIcon(action.icon)"></path></svg> }
|
|
5346
|
-
{{ action.label }}
|
|
5347
|
-
</button>
|
|
5348
|
-
}
|
|
5349
|
-
</div>
|
|
5350
|
-
</header>
|
|
5336
|
+
args: [{ selector: 'amf-page-header', standalone: true, imports: [], template: `
|
|
5337
|
+
<header class="amf-page-header">
|
|
5338
|
+
<div class="header-content">
|
|
5339
|
+
<h1>{{ resolvedTitle }}</h1>
|
|
5340
|
+
@if (config.subtitle) { <p>{{ config.subtitle }}</p> }
|
|
5341
|
+
</div>
|
|
5342
|
+
<div class="header-actions">
|
|
5343
|
+
@for (action of config.actions || []; track action.label) {
|
|
5344
|
+
<button [class]="'btn-' + (action.variant || 'primary')" (click)="actionDispatcher.dispatch(action.action, context)">
|
|
5345
|
+
@if (action.icon) { <svg viewBox="0 0 24 24" class="btn-icon"><path [attr.d]="iconRegistry.getIcon(action.icon)"></path></svg> }
|
|
5346
|
+
{{ action.label }}
|
|
5347
|
+
</button>
|
|
5348
|
+
}
|
|
5349
|
+
</div>
|
|
5350
|
+
</header>
|
|
5351
5351
|
`, styles: [".amf-page-header{display:flex;justify-content:space-between;align-items:center;animation:fadeInUp .4s ease-out}.header-content h1{font-size:1.875rem;margin-bottom:4px}.header-content p{color:var(--app-text-muted);font-size:.9375rem}.header-actions{display:flex;gap:12px}.btn-primary{background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff;border:none;padding:10px 20px;border-radius:10px;font-weight:600;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .3s}.btn-primary:hover{transform:translateY(-2px);box-shadow:0 8px 24px -4px var(--app-glow)}.btn-secondary{background:var(--glass-bg);border:1px solid var(--app-border);color:var(--app-text);padding:10px 20px;border-radius:10px;font-weight:600;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .2s}.btn-secondary:hover{background:var(--glass-bg-hover)}.btn-ghost{background:transparent;border:none;color:var(--app-text-muted);padding:10px 20px;border-radius:10px;font-weight:600;cursor:pointer;display:flex;align-items:center;gap:8px;transition:all .2s}.btn-ghost:hover{color:var(--app-primary);background:var(--glass-bg)}.btn-icon{width:18px;height:18px;fill:currentColor}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
5352
5352
|
}], propDecorators: { config: [{
|
|
5353
5353
|
type: Input
|
|
@@ -5361,10 +5361,10 @@ class NavigationService {
|
|
|
5361
5361
|
setMenuItems(groups) {
|
|
5362
5362
|
this.menuItems.set(groups);
|
|
5363
5363
|
}
|
|
5364
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
5365
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
5364
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: NavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5365
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: NavigationService, providedIn: 'root' });
|
|
5366
5366
|
}
|
|
5367
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
5367
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: NavigationService, decorators: [{
|
|
5368
5368
|
type: Injectable,
|
|
5369
5369
|
args: [{ providedIn: 'root' }]
|
|
5370
5370
|
}] });
|
|
@@ -5531,10 +5531,10 @@ class AppConfigService {
|
|
|
5531
5531
|
html.setAttribute('data-color-scheme', 'light');
|
|
5532
5532
|
}
|
|
5533
5533
|
}
|
|
5534
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
5535
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
5534
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AppConfigService, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5535
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AppConfigService, providedIn: 'root' });
|
|
5536
5536
|
}
|
|
5537
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
5537
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: AppConfigService, decorators: [{
|
|
5538
5538
|
type: Injectable,
|
|
5539
5539
|
args: [{ providedIn: 'root' }]
|
|
5540
5540
|
}], ctorParameters: () => [{ type: i1.Router }] });
|
|
@@ -5770,10 +5770,10 @@ class ThemeService {
|
|
|
5770
5770
|
const next = themes[(idx + 1) % themes.length];
|
|
5771
5771
|
this.setTheme(next.name);
|
|
5772
5772
|
}
|
|
5773
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
5774
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.
|
|
5773
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
5774
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ThemeService, providedIn: 'root' });
|
|
5775
5775
|
}
|
|
5776
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
5776
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ThemeService, decorators: [{
|
|
5777
5777
|
type: Injectable,
|
|
5778
5778
|
args: [{ providedIn: 'root' }]
|
|
5779
5779
|
}], ctorParameters: () => [] });
|
|
@@ -5793,141 +5793,141 @@ class SidebarComponent {
|
|
|
5793
5793
|
}
|
|
5794
5794
|
}
|
|
5795
5795
|
}
|
|
5796
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
5797
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
5798
|
-
<div class="sidebar-container" [class.collapsed]="config.sidebarCollapsed()">
|
|
5799
|
-
<div class="sidebar-header">
|
|
5800
|
-
<div class="logo">
|
|
5801
|
-
<div class="logo-glow">
|
|
5802
|
-
<svg viewBox="0 0 24 24" class="logo-icon">
|
|
5803
|
-
<path [attr.d]="iconRegistry.getIcon('dashboard')"></path>
|
|
5804
|
-
</svg>
|
|
5805
|
-
</div>
|
|
5806
|
-
<span class="logo-text">{{ config.appName() }}</span>
|
|
5807
|
-
</div>
|
|
5808
|
-
</div>
|
|
5809
|
-
|
|
5810
|
-
<nav class="sidebar-nav">
|
|
5811
|
-
@for (group of navigation.menuItems(); track group.label) {
|
|
5812
|
-
<div class="nav-group">
|
|
5813
|
-
<h3 class="group-title">{{ group.label }}</h3>
|
|
5814
|
-
<ul>
|
|
5815
|
-
<ng-container *ngTemplateOutlet="menuList; context: { $implicit: group.items }"></ng-container>
|
|
5816
|
-
</ul>
|
|
5817
|
-
</div>
|
|
5818
|
-
}
|
|
5819
|
-
</nav>
|
|
5820
|
-
|
|
5821
|
-
<ng-template #menuList let-listItems>
|
|
5822
|
-
@for (node of listItems; track node.label) {
|
|
5823
|
-
<li class="nav-item-wrapper">
|
|
5824
|
-
<div
|
|
5825
|
-
class="nav-item"
|
|
5826
|
-
[routerLink]="node.route ? node.route : null"
|
|
5827
|
-
routerLinkActive="active"
|
|
5828
|
-
[class.has-children]="node.children?.length"
|
|
5829
|
-
(click)="toggleExpand(node)"
|
|
5830
|
-
>
|
|
5831
|
-
<div class="nav-link-content">
|
|
5832
|
-
@if (node.icon) {
|
|
5833
|
-
<svg viewBox="0 0 24 24" class="nav-icon">
|
|
5834
|
-
<path [attr.d]="iconRegistry.getIcon(node.icon)"></path>
|
|
5835
|
-
</svg>
|
|
5836
|
-
}
|
|
5837
|
-
<span class="nav-label">{{ node.label }}</span>
|
|
5838
|
-
</div>
|
|
5839
|
-
|
|
5840
|
-
@if (node.badge) {
|
|
5841
|
-
<span class="badge" [style.background]="'linear-gradient(135deg, ' + node.badgeColor + ', ' + node.badgeColor + '88)'">
|
|
5842
|
-
{{ node.badge }}
|
|
5843
|
-
</span>
|
|
5844
|
-
}
|
|
5845
|
-
|
|
5846
|
-
@if (node.children?.length) {
|
|
5847
|
-
<svg viewBox="0 0 24 24" class="chevron" [class.rotated]="expandedItems.has(node)">
|
|
5848
|
-
<path [attr.d]="iconRegistry.getIcon('chevron-right')"></path>
|
|
5849
|
-
</svg>
|
|
5850
|
-
}
|
|
5851
|
-
</div>
|
|
5852
|
-
|
|
5853
|
-
@if (node.children?.length && expandedItems.has(node)) {
|
|
5854
|
-
<ul class="sub-menu">
|
|
5855
|
-
<ng-container *ngTemplateOutlet="menuList; context: { $implicit: node.children }"></ng-container>
|
|
5856
|
-
</ul>
|
|
5857
|
-
}
|
|
5858
|
-
</li>
|
|
5859
|
-
}
|
|
5860
|
-
</ng-template>
|
|
5861
|
-
</div>
|
|
5796
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5797
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: SidebarComponent, isStandalone: true, selector: "app-sidebar", ngImport: i0, template: `
|
|
5798
|
+
<div class="sidebar-container" [class.collapsed]="config.sidebarCollapsed()">
|
|
5799
|
+
<div class="sidebar-header">
|
|
5800
|
+
<div class="logo">
|
|
5801
|
+
<div class="logo-glow">
|
|
5802
|
+
<svg viewBox="0 0 24 24" class="logo-icon">
|
|
5803
|
+
<path [attr.d]="iconRegistry.getIcon('dashboard')"></path>
|
|
5804
|
+
</svg>
|
|
5805
|
+
</div>
|
|
5806
|
+
<span class="logo-text">{{ config.appName() }}</span>
|
|
5807
|
+
</div>
|
|
5808
|
+
</div>
|
|
5809
|
+
|
|
5810
|
+
<nav class="sidebar-nav">
|
|
5811
|
+
@for (group of navigation.menuItems(); track group.label) {
|
|
5812
|
+
<div class="nav-group">
|
|
5813
|
+
<h3 class="group-title">{{ group.label }}</h3>
|
|
5814
|
+
<ul>
|
|
5815
|
+
<ng-container *ngTemplateOutlet="menuList; context: { $implicit: group.items }"></ng-container>
|
|
5816
|
+
</ul>
|
|
5817
|
+
</div>
|
|
5818
|
+
}
|
|
5819
|
+
</nav>
|
|
5820
|
+
|
|
5821
|
+
<ng-template #menuList let-listItems>
|
|
5822
|
+
@for (node of listItems; track node.label) {
|
|
5823
|
+
<li class="nav-item-wrapper">
|
|
5824
|
+
<div
|
|
5825
|
+
class="nav-item"
|
|
5826
|
+
[routerLink]="node.route ? node.route : null"
|
|
5827
|
+
routerLinkActive="active"
|
|
5828
|
+
[class.has-children]="node.children?.length"
|
|
5829
|
+
(click)="toggleExpand(node)"
|
|
5830
|
+
>
|
|
5831
|
+
<div class="nav-link-content">
|
|
5832
|
+
@if (node.icon) {
|
|
5833
|
+
<svg viewBox="0 0 24 24" class="nav-icon">
|
|
5834
|
+
<path [attr.d]="iconRegistry.getIcon(node.icon)"></path>
|
|
5835
|
+
</svg>
|
|
5836
|
+
}
|
|
5837
|
+
<span class="nav-label">{{ node.label }}</span>
|
|
5838
|
+
</div>
|
|
5839
|
+
|
|
5840
|
+
@if (node.badge) {
|
|
5841
|
+
<span class="badge" [style.background]="'linear-gradient(135deg, ' + node.badgeColor + ', ' + node.badgeColor + '88)'">
|
|
5842
|
+
{{ node.badge }}
|
|
5843
|
+
</span>
|
|
5844
|
+
}
|
|
5845
|
+
|
|
5846
|
+
@if (node.children?.length) {
|
|
5847
|
+
<svg viewBox="0 0 24 24" class="chevron" [class.rotated]="expandedItems.has(node)">
|
|
5848
|
+
<path [attr.d]="iconRegistry.getIcon('chevron-right')"></path>
|
|
5849
|
+
</svg>
|
|
5850
|
+
}
|
|
5851
|
+
</div>
|
|
5852
|
+
|
|
5853
|
+
@if (node.children?.length && expandedItems.has(node)) {
|
|
5854
|
+
<ul class="sub-menu">
|
|
5855
|
+
<ng-container *ngTemplateOutlet="menuList; context: { $implicit: node.children }"></ng-container>
|
|
5856
|
+
</ul>
|
|
5857
|
+
}
|
|
5858
|
+
</li>
|
|
5859
|
+
}
|
|
5860
|
+
</ng-template>
|
|
5861
|
+
</div>
|
|
5862
5862
|
`, isInline: true, styles: [":host{display:block;height:100%}.sidebar-container{width:var(--sidebar-width, 260px);height:100%;background:var(--app-sidebar-bg);backdrop-filter:blur(var(--glass-blur-heavy));-webkit-backdrop-filter:blur(var(--glass-blur-heavy));border-right:1px solid var(--glass-border);display:flex;flex-direction:column;transition:width var(--transition-smooth);overflow:hidden;position:relative}.sidebar-container:after{content:\"\";position:absolute;top:0;right:0;width:1px;height:100%;background:linear-gradient(to bottom,transparent,var(--app-primary-light),transparent);pointer-events:none}.sidebar-container.collapsed{width:80px}.sidebar-header{height:68px;display:flex;align-items:center;padding:0 20px;border-bottom:1px solid var(--glass-border)}.logo{display:flex;align-items:center;gap:12px;font-weight:700;font-size:1.25rem;color:var(--app-text);white-space:nowrap}.logo-glow{width:38px;height:38px;border-radius:10px;background:linear-gradient(135deg,var(--app-primary),var(--app-accent));display:flex;align-items:center;justify-content:center;box-shadow:0 0 20px var(--app-glow);animation:pulseGlow 4s ease-in-out infinite;flex-shrink:0}.logo-icon{width:20px;height:20px;fill:#fff}.sidebar-container.collapsed .logo-text{display:none}.sidebar-nav{flex:1;overflow-y:auto;padding:16px 0}.nav-group{margin-top:28px}.nav-group:first-child{margin-top:0}.group-title{font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--app-text-muted);padding:0 24px 8px;opacity:.6}.sidebar-container.collapsed .group-title{display:none}ul{list-style:none;padding:0;margin:0}.nav-item-wrapper{margin-bottom:2px;padding:0 10px}.nav-item{display:flex;align-items:center;justify-content:space-between;height:44px;padding:0 14px;border-radius:10px;color:var(--app-sidebar-text);cursor:pointer;transition:all var(--transition-smooth);text-decoration:none;position:relative}.nav-item:hover{background:var(--glass-bg-hover);color:var(--app-text)}.nav-item.active{background:linear-gradient(135deg,var(--app-primary-light),var(--app-accent-light));color:var(--app-primary);box-shadow:0 0 20px var(--app-glow)}.nav-item.active:before{content:\"\";position:absolute;left:0;top:50%;transform:translateY(-50%);width:3px;height:20px;border-radius:0 3px 3px 0;background:linear-gradient(to bottom,var(--app-primary),var(--app-accent))}.nav-item.active .nav-icon{filter:drop-shadow(0 0 6px var(--app-glow))}.nav-link-content{display:flex;align-items:center;gap:12px}.nav-icon{width:20px;height:20px;fill:currentColor;flex-shrink:0;transition:all var(--transition-fast)}.sidebar-container.collapsed .nav-label,.sidebar-container.collapsed .chevron,.sidebar-container.collapsed .badge{display:none}.chevron{width:16px;height:16px;fill:currentColor;transition:transform var(--transition-smooth);opacity:.5}.chevron.rotated{transform:rotate(90deg)}.badge{font-size:10px;padding:2px 8px;border-radius:10px;color:#fff;font-weight:600;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.sub-menu{padding-left:24px;margin-top:4px;animation:fadeInUp .2s ease-out}.sidebar-container.collapsed .sub-menu{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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"] }] });
|
|
5863
5863
|
}
|
|
5864
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
5864
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: SidebarComponent, decorators: [{
|
|
5865
5865
|
type: Component,
|
|
5866
|
-
args: [{ selector: 'app-sidebar', standalone: true, imports: [CommonModule, RouterLink, RouterLinkActive], template: `
|
|
5867
|
-
<div class="sidebar-container" [class.collapsed]="config.sidebarCollapsed()">
|
|
5868
|
-
<div class="sidebar-header">
|
|
5869
|
-
<div class="logo">
|
|
5870
|
-
<div class="logo-glow">
|
|
5871
|
-
<svg viewBox="0 0 24 24" class="logo-icon">
|
|
5872
|
-
<path [attr.d]="iconRegistry.getIcon('dashboard')"></path>
|
|
5873
|
-
</svg>
|
|
5874
|
-
</div>
|
|
5875
|
-
<span class="logo-text">{{ config.appName() }}</span>
|
|
5876
|
-
</div>
|
|
5877
|
-
</div>
|
|
5878
|
-
|
|
5879
|
-
<nav class="sidebar-nav">
|
|
5880
|
-
@for (group of navigation.menuItems(); track group.label) {
|
|
5881
|
-
<div class="nav-group">
|
|
5882
|
-
<h3 class="group-title">{{ group.label }}</h3>
|
|
5883
|
-
<ul>
|
|
5884
|
-
<ng-container *ngTemplateOutlet="menuList; context: { $implicit: group.items }"></ng-container>
|
|
5885
|
-
</ul>
|
|
5886
|
-
</div>
|
|
5887
|
-
}
|
|
5888
|
-
</nav>
|
|
5889
|
-
|
|
5890
|
-
<ng-template #menuList let-listItems>
|
|
5891
|
-
@for (node of listItems; track node.label) {
|
|
5892
|
-
<li class="nav-item-wrapper">
|
|
5893
|
-
<div
|
|
5894
|
-
class="nav-item"
|
|
5895
|
-
[routerLink]="node.route ? node.route : null"
|
|
5896
|
-
routerLinkActive="active"
|
|
5897
|
-
[class.has-children]="node.children?.length"
|
|
5898
|
-
(click)="toggleExpand(node)"
|
|
5899
|
-
>
|
|
5900
|
-
<div class="nav-link-content">
|
|
5901
|
-
@if (node.icon) {
|
|
5902
|
-
<svg viewBox="0 0 24 24" class="nav-icon">
|
|
5903
|
-
<path [attr.d]="iconRegistry.getIcon(node.icon)"></path>
|
|
5904
|
-
</svg>
|
|
5905
|
-
}
|
|
5906
|
-
<span class="nav-label">{{ node.label }}</span>
|
|
5907
|
-
</div>
|
|
5908
|
-
|
|
5909
|
-
@if (node.badge) {
|
|
5910
|
-
<span class="badge" [style.background]="'linear-gradient(135deg, ' + node.badgeColor + ', ' + node.badgeColor + '88)'">
|
|
5911
|
-
{{ node.badge }}
|
|
5912
|
-
</span>
|
|
5913
|
-
}
|
|
5914
|
-
|
|
5915
|
-
@if (node.children?.length) {
|
|
5916
|
-
<svg viewBox="0 0 24 24" class="chevron" [class.rotated]="expandedItems.has(node)">
|
|
5917
|
-
<path [attr.d]="iconRegistry.getIcon('chevron-right')"></path>
|
|
5918
|
-
</svg>
|
|
5919
|
-
}
|
|
5920
|
-
</div>
|
|
5921
|
-
|
|
5922
|
-
@if (node.children?.length && expandedItems.has(node)) {
|
|
5923
|
-
<ul class="sub-menu">
|
|
5924
|
-
<ng-container *ngTemplateOutlet="menuList; context: { $implicit: node.children }"></ng-container>
|
|
5925
|
-
</ul>
|
|
5926
|
-
}
|
|
5927
|
-
</li>
|
|
5928
|
-
}
|
|
5929
|
-
</ng-template>
|
|
5930
|
-
</div>
|
|
5866
|
+
args: [{ selector: 'app-sidebar', standalone: true, imports: [CommonModule, RouterLink, RouterLinkActive], template: `
|
|
5867
|
+
<div class="sidebar-container" [class.collapsed]="config.sidebarCollapsed()">
|
|
5868
|
+
<div class="sidebar-header">
|
|
5869
|
+
<div class="logo">
|
|
5870
|
+
<div class="logo-glow">
|
|
5871
|
+
<svg viewBox="0 0 24 24" class="logo-icon">
|
|
5872
|
+
<path [attr.d]="iconRegistry.getIcon('dashboard')"></path>
|
|
5873
|
+
</svg>
|
|
5874
|
+
</div>
|
|
5875
|
+
<span class="logo-text">{{ config.appName() }}</span>
|
|
5876
|
+
</div>
|
|
5877
|
+
</div>
|
|
5878
|
+
|
|
5879
|
+
<nav class="sidebar-nav">
|
|
5880
|
+
@for (group of navigation.menuItems(); track group.label) {
|
|
5881
|
+
<div class="nav-group">
|
|
5882
|
+
<h3 class="group-title">{{ group.label }}</h3>
|
|
5883
|
+
<ul>
|
|
5884
|
+
<ng-container *ngTemplateOutlet="menuList; context: { $implicit: group.items }"></ng-container>
|
|
5885
|
+
</ul>
|
|
5886
|
+
</div>
|
|
5887
|
+
}
|
|
5888
|
+
</nav>
|
|
5889
|
+
|
|
5890
|
+
<ng-template #menuList let-listItems>
|
|
5891
|
+
@for (node of listItems; track node.label) {
|
|
5892
|
+
<li class="nav-item-wrapper">
|
|
5893
|
+
<div
|
|
5894
|
+
class="nav-item"
|
|
5895
|
+
[routerLink]="node.route ? node.route : null"
|
|
5896
|
+
routerLinkActive="active"
|
|
5897
|
+
[class.has-children]="node.children?.length"
|
|
5898
|
+
(click)="toggleExpand(node)"
|
|
5899
|
+
>
|
|
5900
|
+
<div class="nav-link-content">
|
|
5901
|
+
@if (node.icon) {
|
|
5902
|
+
<svg viewBox="0 0 24 24" class="nav-icon">
|
|
5903
|
+
<path [attr.d]="iconRegistry.getIcon(node.icon)"></path>
|
|
5904
|
+
</svg>
|
|
5905
|
+
}
|
|
5906
|
+
<span class="nav-label">{{ node.label }}</span>
|
|
5907
|
+
</div>
|
|
5908
|
+
|
|
5909
|
+
@if (node.badge) {
|
|
5910
|
+
<span class="badge" [style.background]="'linear-gradient(135deg, ' + node.badgeColor + ', ' + node.badgeColor + '88)'">
|
|
5911
|
+
{{ node.badge }}
|
|
5912
|
+
</span>
|
|
5913
|
+
}
|
|
5914
|
+
|
|
5915
|
+
@if (node.children?.length) {
|
|
5916
|
+
<svg viewBox="0 0 24 24" class="chevron" [class.rotated]="expandedItems.has(node)">
|
|
5917
|
+
<path [attr.d]="iconRegistry.getIcon('chevron-right')"></path>
|
|
5918
|
+
</svg>
|
|
5919
|
+
}
|
|
5920
|
+
</div>
|
|
5921
|
+
|
|
5922
|
+
@if (node.children?.length && expandedItems.has(node)) {
|
|
5923
|
+
<ul class="sub-menu">
|
|
5924
|
+
<ng-container *ngTemplateOutlet="menuList; context: { $implicit: node.children }"></ng-container>
|
|
5925
|
+
</ul>
|
|
5926
|
+
}
|
|
5927
|
+
</li>
|
|
5928
|
+
}
|
|
5929
|
+
</ng-template>
|
|
5930
|
+
</div>
|
|
5931
5931
|
`, styles: [":host{display:block;height:100%}.sidebar-container{width:var(--sidebar-width, 260px);height:100%;background:var(--app-sidebar-bg);backdrop-filter:blur(var(--glass-blur-heavy));-webkit-backdrop-filter:blur(var(--glass-blur-heavy));border-right:1px solid var(--glass-border);display:flex;flex-direction:column;transition:width var(--transition-smooth);overflow:hidden;position:relative}.sidebar-container:after{content:\"\";position:absolute;top:0;right:0;width:1px;height:100%;background:linear-gradient(to bottom,transparent,var(--app-primary-light),transparent);pointer-events:none}.sidebar-container.collapsed{width:80px}.sidebar-header{height:68px;display:flex;align-items:center;padding:0 20px;border-bottom:1px solid var(--glass-border)}.logo{display:flex;align-items:center;gap:12px;font-weight:700;font-size:1.25rem;color:var(--app-text);white-space:nowrap}.logo-glow{width:38px;height:38px;border-radius:10px;background:linear-gradient(135deg,var(--app-primary),var(--app-accent));display:flex;align-items:center;justify-content:center;box-shadow:0 0 20px var(--app-glow);animation:pulseGlow 4s ease-in-out infinite;flex-shrink:0}.logo-icon{width:20px;height:20px;fill:#fff}.sidebar-container.collapsed .logo-text{display:none}.sidebar-nav{flex:1;overflow-y:auto;padding:16px 0}.nav-group{margin-top:28px}.nav-group:first-child{margin-top:0}.group-title{font-size:.6875rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:var(--app-text-muted);padding:0 24px 8px;opacity:.6}.sidebar-container.collapsed .group-title{display:none}ul{list-style:none;padding:0;margin:0}.nav-item-wrapper{margin-bottom:2px;padding:0 10px}.nav-item{display:flex;align-items:center;justify-content:space-between;height:44px;padding:0 14px;border-radius:10px;color:var(--app-sidebar-text);cursor:pointer;transition:all var(--transition-smooth);text-decoration:none;position:relative}.nav-item:hover{background:var(--glass-bg-hover);color:var(--app-text)}.nav-item.active{background:linear-gradient(135deg,var(--app-primary-light),var(--app-accent-light));color:var(--app-primary);box-shadow:0 0 20px var(--app-glow)}.nav-item.active:before{content:\"\";position:absolute;left:0;top:50%;transform:translateY(-50%);width:3px;height:20px;border-radius:0 3px 3px 0;background:linear-gradient(to bottom,var(--app-primary),var(--app-accent))}.nav-item.active .nav-icon{filter:drop-shadow(0 0 6px var(--app-glow))}.nav-link-content{display:flex;align-items:center;gap:12px}.nav-icon{width:20px;height:20px;fill:currentColor;flex-shrink:0;transition:all var(--transition-fast)}.sidebar-container.collapsed .nav-label,.sidebar-container.collapsed .chevron,.sidebar-container.collapsed .badge{display:none}.chevron{width:16px;height:16px;fill:currentColor;transition:transform var(--transition-smooth);opacity:.5}.chevron.rotated{transform:rotate(90deg)}.badge{font-size:10px;padding:2px 8px;border-radius:10px;color:#fff;font-weight:600;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}.sub-menu{padding-left:24px;margin-top:4px;animation:fadeInUp .2s ease-out}.sidebar-container.collapsed .sub-menu{display:none}\n"] }]
|
|
5932
5932
|
}] });
|
|
5933
5933
|
|
|
@@ -5946,437 +5946,437 @@ class NavbarComponent {
|
|
|
5946
5946
|
};
|
|
5947
5947
|
return colors[name] || '#06b6d4';
|
|
5948
5948
|
}
|
|
5949
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
5950
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
5951
|
-
<header class="navbar-container">
|
|
5952
|
-
<div class="left-section">
|
|
5953
|
-
<button class="icon-btn" (click)="config.toggleSidebar()" title="Toggle Sidebar">
|
|
5954
|
-
<svg viewBox="0 0 24 24">
|
|
5955
|
-
<path [attr.d]="iconRegistry.getIcon('menu')"></path>
|
|
5956
|
-
</svg>
|
|
5957
|
-
</button>
|
|
5958
|
-
|
|
5959
|
-
<div class="search-box">
|
|
5960
|
-
<svg viewBox="0 0 24 24" class="search-icon">
|
|
5961
|
-
<path [attr.d]="iconRegistry.getIcon('search')"></path>
|
|
5962
|
-
</svg>
|
|
5963
|
-
<input type="text" placeholder="Search anything...">
|
|
5964
|
-
</div>
|
|
5965
|
-
</div>
|
|
5966
|
-
|
|
5967
|
-
<div class="right-section">
|
|
5968
|
-
<!-- Theme Switcher -->
|
|
5969
|
-
<button class="icon-btn theme-btn" (click)="themeToggleOpen.set(!themeToggleOpen())" title="Change Theme">
|
|
5970
|
-
<svg viewBox="0 0 24 24">
|
|
5971
|
-
<path [attr.d]="iconRegistry.getIcon('palette')"></path>
|
|
5972
|
-
</svg>
|
|
5973
|
-
|
|
5974
|
-
@if (themeToggleOpen()) {
|
|
5975
|
-
<div class="dropdown theme-dropdown">
|
|
5976
|
-
@for (theme of themeService.availableThemes; track theme.name) {
|
|
5977
|
-
<div
|
|
5978
|
-
class="dropdown-item"
|
|
5979
|
-
[class.active]="themeService.currentTheme() === theme.name"
|
|
5980
|
-
(click)="themeService.setTheme(theme.name); themeToggleOpen.set(false)"
|
|
5981
|
-
>
|
|
5982
|
-
<span class="theme-dot" [style.background]="getThemeColor(theme.name)"></span>
|
|
5983
|
-
{{ theme.label }}
|
|
5984
|
-
</div>
|
|
5985
|
-
}
|
|
5986
|
-
</div>
|
|
5987
|
-
}
|
|
5988
|
-
</button>
|
|
5989
|
-
|
|
5990
|
-
<!-- User Profile -->
|
|
5991
|
-
<div class="user-profile" (click)="userMenuOpen.set(!userMenuOpen())">
|
|
5992
|
-
<div class="user-info">
|
|
5993
|
-
<span class="user-name">{{ auth.user()?.name }}</span>
|
|
5994
|
-
<span class="user-role">{{ auth.user()?.role }}</span>
|
|
5995
|
-
</div>
|
|
5996
|
-
<div class="avatar">
|
|
5997
|
-
@if (auth.user()?.avatar) {
|
|
5998
|
-
<img [src]="auth.user()?.avatar" [alt]="auth.user()?.name">
|
|
5999
|
-
} @else {
|
|
6000
|
-
<svg viewBox="0 0 24 24">
|
|
6001
|
-
<path [attr.d]="iconRegistry.getIcon('person')"></path>
|
|
6002
|
-
</svg>
|
|
6003
|
-
}
|
|
6004
|
-
</div>
|
|
6005
|
-
|
|
6006
|
-
@if (userMenuOpen()) {
|
|
6007
|
-
<div class="dropdown user-dropdown">
|
|
6008
|
-
<div class="dropdown-header">
|
|
6009
|
-
<strong>{{ auth.user()?.name }}</strong>
|
|
6010
|
-
<span>{{ auth.user()?.email }}</span>
|
|
6011
|
-
</div>
|
|
6012
|
-
<div class="divider"></div>
|
|
6013
|
-
<div class="dropdown-item">Your Profile</div>
|
|
6014
|
-
<div class="dropdown-item">Settings</div>
|
|
6015
|
-
<div class="divider"></div>
|
|
6016
|
-
<div class="dropdown-item logout" (click)="auth.logout()">
|
|
6017
|
-
<svg viewBox="0 0 24 24" class="logout-icon">
|
|
6018
|
-
<path [attr.d]="iconRegistry.getIcon('logout')"></path>
|
|
6019
|
-
</svg>
|
|
6020
|
-
Logout
|
|
6021
|
-
</div>
|
|
6022
|
-
</div>
|
|
6023
|
-
}
|
|
6024
|
-
</div>
|
|
6025
|
-
</div>
|
|
6026
|
-
</header>
|
|
5949
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: NavbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5950
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: NavbarComponent, isStandalone: true, selector: "app-navbar", ngImport: i0, template: `
|
|
5951
|
+
<header class="navbar-container">
|
|
5952
|
+
<div class="left-section">
|
|
5953
|
+
<button class="icon-btn" (click)="config.toggleSidebar()" title="Toggle Sidebar">
|
|
5954
|
+
<svg viewBox="0 0 24 24">
|
|
5955
|
+
<path [attr.d]="iconRegistry.getIcon('menu')"></path>
|
|
5956
|
+
</svg>
|
|
5957
|
+
</button>
|
|
5958
|
+
|
|
5959
|
+
<div class="search-box">
|
|
5960
|
+
<svg viewBox="0 0 24 24" class="search-icon">
|
|
5961
|
+
<path [attr.d]="iconRegistry.getIcon('search')"></path>
|
|
5962
|
+
</svg>
|
|
5963
|
+
<input type="text" placeholder="Search anything...">
|
|
5964
|
+
</div>
|
|
5965
|
+
</div>
|
|
5966
|
+
|
|
5967
|
+
<div class="right-section">
|
|
5968
|
+
<!-- Theme Switcher -->
|
|
5969
|
+
<button class="icon-btn theme-btn" (click)="themeToggleOpen.set(!themeToggleOpen())" title="Change Theme">
|
|
5970
|
+
<svg viewBox="0 0 24 24">
|
|
5971
|
+
<path [attr.d]="iconRegistry.getIcon('palette')"></path>
|
|
5972
|
+
</svg>
|
|
5973
|
+
|
|
5974
|
+
@if (themeToggleOpen()) {
|
|
5975
|
+
<div class="dropdown theme-dropdown">
|
|
5976
|
+
@for (theme of themeService.availableThemes; track theme.name) {
|
|
5977
|
+
<div
|
|
5978
|
+
class="dropdown-item"
|
|
5979
|
+
[class.active]="themeService.currentTheme() === theme.name"
|
|
5980
|
+
(click)="themeService.setTheme(theme.name); themeToggleOpen.set(false)"
|
|
5981
|
+
>
|
|
5982
|
+
<span class="theme-dot" [style.background]="getThemeColor(theme.name)"></span>
|
|
5983
|
+
{{ theme.label }}
|
|
5984
|
+
</div>
|
|
5985
|
+
}
|
|
5986
|
+
</div>
|
|
5987
|
+
}
|
|
5988
|
+
</button>
|
|
5989
|
+
|
|
5990
|
+
<!-- User Profile -->
|
|
5991
|
+
<div class="user-profile" (click)="userMenuOpen.set(!userMenuOpen())">
|
|
5992
|
+
<div class="user-info">
|
|
5993
|
+
<span class="user-name">{{ auth.user()?.name }}</span>
|
|
5994
|
+
<span class="user-role">{{ auth.user()?.role }}</span>
|
|
5995
|
+
</div>
|
|
5996
|
+
<div class="avatar">
|
|
5997
|
+
@if (auth.user()?.avatar) {
|
|
5998
|
+
<img [src]="auth.user()?.avatar" [alt]="auth.user()?.name">
|
|
5999
|
+
} @else {
|
|
6000
|
+
<svg viewBox="0 0 24 24">
|
|
6001
|
+
<path [attr.d]="iconRegistry.getIcon('person')"></path>
|
|
6002
|
+
</svg>
|
|
6003
|
+
}
|
|
6004
|
+
</div>
|
|
6005
|
+
|
|
6006
|
+
@if (userMenuOpen()) {
|
|
6007
|
+
<div class="dropdown user-dropdown">
|
|
6008
|
+
<div class="dropdown-header">
|
|
6009
|
+
<strong>{{ auth.user()?.name }}</strong>
|
|
6010
|
+
<span>{{ auth.user()?.email }}</span>
|
|
6011
|
+
</div>
|
|
6012
|
+
<div class="divider"></div>
|
|
6013
|
+
<div class="dropdown-item">Your Profile</div>
|
|
6014
|
+
<div class="dropdown-item">Settings</div>
|
|
6015
|
+
<div class="divider"></div>
|
|
6016
|
+
<div class="dropdown-item logout" (click)="auth.logout()">
|
|
6017
|
+
<svg viewBox="0 0 24 24" class="logout-icon">
|
|
6018
|
+
<path [attr.d]="iconRegistry.getIcon('logout')"></path>
|
|
6019
|
+
</svg>
|
|
6020
|
+
Logout
|
|
6021
|
+
</div>
|
|
6022
|
+
</div>
|
|
6023
|
+
}
|
|
6024
|
+
</div>
|
|
6025
|
+
</div>
|
|
6026
|
+
</header>
|
|
6027
6027
|
`, isInline: true, styles: [":host{display:block;width:100%}.navbar-container{height:68px;padding:0 24px;background:var(--app-navbar-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));border-bottom:1px solid var(--glass-border);display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100}.left-section,.right-section{display:flex;align-items:center;gap:16px}.icon-btn{width:40px;height:40px;border-radius:10px;border:1px solid transparent;background:transparent;color:var(--app-text-muted);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--transition-smooth);position:relative}.icon-btn:hover{background:var(--glass-bg-hover);border-color:var(--glass-border);color:var(--app-primary);box-shadow:0 0 16px var(--app-glow)}.icon-btn svg{width:22px;height:22px;fill:currentColor}.search-box{display:flex;align-items:center;background:var(--glass-bg);border:1px solid var(--glass-border);border-radius:10px;padding:0 14px;width:300px;height:40px;transition:all var(--transition-smooth)}.search-box:focus-within{border-color:var(--app-primary);background:var(--glass-bg-hover);box-shadow:0 0 20px var(--app-glow)}.search-icon{width:18px;height:18px;fill:var(--app-text-muted);flex-shrink:0;transition:fill var(--transition-fast)}.search-box:focus-within .search-icon{fill:var(--app-primary)}.search-box input{border:none;background:transparent;padding:8px;outline:none;flex:1;font-size:.875rem;color:var(--app-text)}.search-box input::placeholder{color:var(--app-text-muted)}.user-profile{display:flex;align-items:center;gap:12px;cursor:pointer;padding:4px 12px;border-radius:12px;border:1px solid transparent;transition:all var(--transition-smooth);position:relative}.user-profile:hover{background:var(--glass-bg-hover);border-color:var(--glass-border)}.user-info{display:flex;flex-direction:column;align-items:flex-end}.user-name{font-size:.875rem;font-weight:600;color:var(--app-text)}.user-role{font-size:.6875rem;color:var(--app-text-muted);text-transform:uppercase;letter-spacing:.05em}.avatar{width:38px;height:38px;border-radius:12px;background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff;display:flex;align-items:center;justify-content:center;overflow:hidden;transition:box-shadow var(--transition-smooth)}.user-profile:hover .avatar{box-shadow:0 0 20px var(--app-glow)}.avatar img{width:100%;height:100%;object-fit:cover}.avatar svg{width:22px;height:22px;fill:currentColor}.dropdown{position:absolute;top:calc(100% + 8px);right:0;background:var(--app-bg-secondary);backdrop-filter:blur(var(--glass-blur-heavy));-webkit-backdrop-filter:blur(var(--glass-blur-heavy));border:1px solid var(--glass-border-light);border-radius:14px;box-shadow:var(--glass-shadow),0 0 30px #0006;min-width:220px;overflow:hidden;animation:slideInDown .25s ease-out}.dropdown-header{padding:14px 16px;display:flex;flex-direction:column}.dropdown-header strong{color:var(--app-text);font-size:.9375rem}.dropdown-header span{font-size:.75rem;color:var(--app-text-muted);margin-top:2px}.dropdown-item{padding:10px 16px;font-size:.875rem;cursor:pointer;transition:all var(--transition-fast);color:var(--app-text-muted);display:flex;align-items:center;gap:10px}.dropdown-item:hover{background:var(--glass-bg-hover);color:var(--app-primary)}.dropdown-item.active{background:var(--app-primary-light);color:var(--app-primary);font-weight:600}.theme-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}.divider{height:1px;background:var(--glass-border);margin:4px 0}.logout{color:#f43f5e!important}.logout:hover{background:#f43f5e1a!important;color:#fb7185!important}.logout-icon{width:18px;height:18px;fill:currentColor}\n"] });
|
|
6028
6028
|
}
|
|
6029
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6029
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: NavbarComponent, decorators: [{
|
|
6030
6030
|
type: Component,
|
|
6031
|
-
args: [{ selector: 'app-navbar', standalone: true, imports: [], template: `
|
|
6032
|
-
<header class="navbar-container">
|
|
6033
|
-
<div class="left-section">
|
|
6034
|
-
<button class="icon-btn" (click)="config.toggleSidebar()" title="Toggle Sidebar">
|
|
6035
|
-
<svg viewBox="0 0 24 24">
|
|
6036
|
-
<path [attr.d]="iconRegistry.getIcon('menu')"></path>
|
|
6037
|
-
</svg>
|
|
6038
|
-
</button>
|
|
6039
|
-
|
|
6040
|
-
<div class="search-box">
|
|
6041
|
-
<svg viewBox="0 0 24 24" class="search-icon">
|
|
6042
|
-
<path [attr.d]="iconRegistry.getIcon('search')"></path>
|
|
6043
|
-
</svg>
|
|
6044
|
-
<input type="text" placeholder="Search anything...">
|
|
6045
|
-
</div>
|
|
6046
|
-
</div>
|
|
6047
|
-
|
|
6048
|
-
<div class="right-section">
|
|
6049
|
-
<!-- Theme Switcher -->
|
|
6050
|
-
<button class="icon-btn theme-btn" (click)="themeToggleOpen.set(!themeToggleOpen())" title="Change Theme">
|
|
6051
|
-
<svg viewBox="0 0 24 24">
|
|
6052
|
-
<path [attr.d]="iconRegistry.getIcon('palette')"></path>
|
|
6053
|
-
</svg>
|
|
6054
|
-
|
|
6055
|
-
@if (themeToggleOpen()) {
|
|
6056
|
-
<div class="dropdown theme-dropdown">
|
|
6057
|
-
@for (theme of themeService.availableThemes; track theme.name) {
|
|
6058
|
-
<div
|
|
6059
|
-
class="dropdown-item"
|
|
6060
|
-
[class.active]="themeService.currentTheme() === theme.name"
|
|
6061
|
-
(click)="themeService.setTheme(theme.name); themeToggleOpen.set(false)"
|
|
6062
|
-
>
|
|
6063
|
-
<span class="theme-dot" [style.background]="getThemeColor(theme.name)"></span>
|
|
6064
|
-
{{ theme.label }}
|
|
6065
|
-
</div>
|
|
6066
|
-
}
|
|
6067
|
-
</div>
|
|
6068
|
-
}
|
|
6069
|
-
</button>
|
|
6070
|
-
|
|
6071
|
-
<!-- User Profile -->
|
|
6072
|
-
<div class="user-profile" (click)="userMenuOpen.set(!userMenuOpen())">
|
|
6073
|
-
<div class="user-info">
|
|
6074
|
-
<span class="user-name">{{ auth.user()?.name }}</span>
|
|
6075
|
-
<span class="user-role">{{ auth.user()?.role }}</span>
|
|
6076
|
-
</div>
|
|
6077
|
-
<div class="avatar">
|
|
6078
|
-
@if (auth.user()?.avatar) {
|
|
6079
|
-
<img [src]="auth.user()?.avatar" [alt]="auth.user()?.name">
|
|
6080
|
-
} @else {
|
|
6081
|
-
<svg viewBox="0 0 24 24">
|
|
6082
|
-
<path [attr.d]="iconRegistry.getIcon('person')"></path>
|
|
6083
|
-
</svg>
|
|
6084
|
-
}
|
|
6085
|
-
</div>
|
|
6086
|
-
|
|
6087
|
-
@if (userMenuOpen()) {
|
|
6088
|
-
<div class="dropdown user-dropdown">
|
|
6089
|
-
<div class="dropdown-header">
|
|
6090
|
-
<strong>{{ auth.user()?.name }}</strong>
|
|
6091
|
-
<span>{{ auth.user()?.email }}</span>
|
|
6092
|
-
</div>
|
|
6093
|
-
<div class="divider"></div>
|
|
6094
|
-
<div class="dropdown-item">Your Profile</div>
|
|
6095
|
-
<div class="dropdown-item">Settings</div>
|
|
6096
|
-
<div class="divider"></div>
|
|
6097
|
-
<div class="dropdown-item logout" (click)="auth.logout()">
|
|
6098
|
-
<svg viewBox="0 0 24 24" class="logout-icon">
|
|
6099
|
-
<path [attr.d]="iconRegistry.getIcon('logout')"></path>
|
|
6100
|
-
</svg>
|
|
6101
|
-
Logout
|
|
6102
|
-
</div>
|
|
6103
|
-
</div>
|
|
6104
|
-
}
|
|
6105
|
-
</div>
|
|
6106
|
-
</div>
|
|
6107
|
-
</header>
|
|
6031
|
+
args: [{ selector: 'app-navbar', standalone: true, imports: [], template: `
|
|
6032
|
+
<header class="navbar-container">
|
|
6033
|
+
<div class="left-section">
|
|
6034
|
+
<button class="icon-btn" (click)="config.toggleSidebar()" title="Toggle Sidebar">
|
|
6035
|
+
<svg viewBox="0 0 24 24">
|
|
6036
|
+
<path [attr.d]="iconRegistry.getIcon('menu')"></path>
|
|
6037
|
+
</svg>
|
|
6038
|
+
</button>
|
|
6039
|
+
|
|
6040
|
+
<div class="search-box">
|
|
6041
|
+
<svg viewBox="0 0 24 24" class="search-icon">
|
|
6042
|
+
<path [attr.d]="iconRegistry.getIcon('search')"></path>
|
|
6043
|
+
</svg>
|
|
6044
|
+
<input type="text" placeholder="Search anything...">
|
|
6045
|
+
</div>
|
|
6046
|
+
</div>
|
|
6047
|
+
|
|
6048
|
+
<div class="right-section">
|
|
6049
|
+
<!-- Theme Switcher -->
|
|
6050
|
+
<button class="icon-btn theme-btn" (click)="themeToggleOpen.set(!themeToggleOpen())" title="Change Theme">
|
|
6051
|
+
<svg viewBox="0 0 24 24">
|
|
6052
|
+
<path [attr.d]="iconRegistry.getIcon('palette')"></path>
|
|
6053
|
+
</svg>
|
|
6054
|
+
|
|
6055
|
+
@if (themeToggleOpen()) {
|
|
6056
|
+
<div class="dropdown theme-dropdown">
|
|
6057
|
+
@for (theme of themeService.availableThemes; track theme.name) {
|
|
6058
|
+
<div
|
|
6059
|
+
class="dropdown-item"
|
|
6060
|
+
[class.active]="themeService.currentTheme() === theme.name"
|
|
6061
|
+
(click)="themeService.setTheme(theme.name); themeToggleOpen.set(false)"
|
|
6062
|
+
>
|
|
6063
|
+
<span class="theme-dot" [style.background]="getThemeColor(theme.name)"></span>
|
|
6064
|
+
{{ theme.label }}
|
|
6065
|
+
</div>
|
|
6066
|
+
}
|
|
6067
|
+
</div>
|
|
6068
|
+
}
|
|
6069
|
+
</button>
|
|
6070
|
+
|
|
6071
|
+
<!-- User Profile -->
|
|
6072
|
+
<div class="user-profile" (click)="userMenuOpen.set(!userMenuOpen())">
|
|
6073
|
+
<div class="user-info">
|
|
6074
|
+
<span class="user-name">{{ auth.user()?.name }}</span>
|
|
6075
|
+
<span class="user-role">{{ auth.user()?.role }}</span>
|
|
6076
|
+
</div>
|
|
6077
|
+
<div class="avatar">
|
|
6078
|
+
@if (auth.user()?.avatar) {
|
|
6079
|
+
<img [src]="auth.user()?.avatar" [alt]="auth.user()?.name">
|
|
6080
|
+
} @else {
|
|
6081
|
+
<svg viewBox="0 0 24 24">
|
|
6082
|
+
<path [attr.d]="iconRegistry.getIcon('person')"></path>
|
|
6083
|
+
</svg>
|
|
6084
|
+
}
|
|
6085
|
+
</div>
|
|
6086
|
+
|
|
6087
|
+
@if (userMenuOpen()) {
|
|
6088
|
+
<div class="dropdown user-dropdown">
|
|
6089
|
+
<div class="dropdown-header">
|
|
6090
|
+
<strong>{{ auth.user()?.name }}</strong>
|
|
6091
|
+
<span>{{ auth.user()?.email }}</span>
|
|
6092
|
+
</div>
|
|
6093
|
+
<div class="divider"></div>
|
|
6094
|
+
<div class="dropdown-item">Your Profile</div>
|
|
6095
|
+
<div class="dropdown-item">Settings</div>
|
|
6096
|
+
<div class="divider"></div>
|
|
6097
|
+
<div class="dropdown-item logout" (click)="auth.logout()">
|
|
6098
|
+
<svg viewBox="0 0 24 24" class="logout-icon">
|
|
6099
|
+
<path [attr.d]="iconRegistry.getIcon('logout')"></path>
|
|
6100
|
+
</svg>
|
|
6101
|
+
Logout
|
|
6102
|
+
</div>
|
|
6103
|
+
</div>
|
|
6104
|
+
}
|
|
6105
|
+
</div>
|
|
6106
|
+
</div>
|
|
6107
|
+
</header>
|
|
6108
6108
|
`, styles: [":host{display:block;width:100%}.navbar-container{height:68px;padding:0 24px;background:var(--app-navbar-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));border-bottom:1px solid var(--glass-border);display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100}.left-section,.right-section{display:flex;align-items:center;gap:16px}.icon-btn{width:40px;height:40px;border-radius:10px;border:1px solid transparent;background:transparent;color:var(--app-text-muted);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all var(--transition-smooth);position:relative}.icon-btn:hover{background:var(--glass-bg-hover);border-color:var(--glass-border);color:var(--app-primary);box-shadow:0 0 16px var(--app-glow)}.icon-btn svg{width:22px;height:22px;fill:currentColor}.search-box{display:flex;align-items:center;background:var(--glass-bg);border:1px solid var(--glass-border);border-radius:10px;padding:0 14px;width:300px;height:40px;transition:all var(--transition-smooth)}.search-box:focus-within{border-color:var(--app-primary);background:var(--glass-bg-hover);box-shadow:0 0 20px var(--app-glow)}.search-icon{width:18px;height:18px;fill:var(--app-text-muted);flex-shrink:0;transition:fill var(--transition-fast)}.search-box:focus-within .search-icon{fill:var(--app-primary)}.search-box input{border:none;background:transparent;padding:8px;outline:none;flex:1;font-size:.875rem;color:var(--app-text)}.search-box input::placeholder{color:var(--app-text-muted)}.user-profile{display:flex;align-items:center;gap:12px;cursor:pointer;padding:4px 12px;border-radius:12px;border:1px solid transparent;transition:all var(--transition-smooth);position:relative}.user-profile:hover{background:var(--glass-bg-hover);border-color:var(--glass-border)}.user-info{display:flex;flex-direction:column;align-items:flex-end}.user-name{font-size:.875rem;font-weight:600;color:var(--app-text)}.user-role{font-size:.6875rem;color:var(--app-text-muted);text-transform:uppercase;letter-spacing:.05em}.avatar{width:38px;height:38px;border-radius:12px;background:linear-gradient(135deg,var(--app-primary),var(--app-accent));color:#fff;display:flex;align-items:center;justify-content:center;overflow:hidden;transition:box-shadow var(--transition-smooth)}.user-profile:hover .avatar{box-shadow:0 0 20px var(--app-glow)}.avatar img{width:100%;height:100%;object-fit:cover}.avatar svg{width:22px;height:22px;fill:currentColor}.dropdown{position:absolute;top:calc(100% + 8px);right:0;background:var(--app-bg-secondary);backdrop-filter:blur(var(--glass-blur-heavy));-webkit-backdrop-filter:blur(var(--glass-blur-heavy));border:1px solid var(--glass-border-light);border-radius:14px;box-shadow:var(--glass-shadow),0 0 30px #0006;min-width:220px;overflow:hidden;animation:slideInDown .25s ease-out}.dropdown-header{padding:14px 16px;display:flex;flex-direction:column}.dropdown-header strong{color:var(--app-text);font-size:.9375rem}.dropdown-header span{font-size:.75rem;color:var(--app-text-muted);margin-top:2px}.dropdown-item{padding:10px 16px;font-size:.875rem;cursor:pointer;transition:all var(--transition-fast);color:var(--app-text-muted);display:flex;align-items:center;gap:10px}.dropdown-item:hover{background:var(--glass-bg-hover);color:var(--app-primary)}.dropdown-item.active{background:var(--app-primary-light);color:var(--app-primary);font-weight:600}.theme-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}.divider{height:1px;background:var(--glass-border);margin:4px 0}.logout{color:#f43f5e!important}.logout:hover{background:#f43f5e1a!important;color:#fb7185!important}.logout-icon{width:18px;height:18px;fill:currentColor}\n"] }]
|
|
6109
6109
|
}] });
|
|
6110
6110
|
|
|
6111
6111
|
class FooterComponent {
|
|
6112
6112
|
config = inject(AppConfigService);
|
|
6113
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6114
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
6115
|
-
<footer class="footer-container">
|
|
6116
|
-
<div class="footer-content">
|
|
6117
|
-
<p class="copyright">{{ config.copyrightText() }}</p>
|
|
6118
|
-
<div class="links">
|
|
6119
|
-
<a href="#">Terms</a>
|
|
6120
|
-
<a href="#">Privacy</a>
|
|
6121
|
-
<a href="#">Support</a>
|
|
6122
|
-
</div>
|
|
6123
|
-
</div>
|
|
6124
|
-
</footer>
|
|
6113
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: FooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6114
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.15", type: FooterComponent, isStandalone: true, selector: "app-footer", ngImport: i0, template: `
|
|
6115
|
+
<footer class="footer-container">
|
|
6116
|
+
<div class="footer-content">
|
|
6117
|
+
<p class="copyright">{{ config.copyrightText() }}</p>
|
|
6118
|
+
<div class="links">
|
|
6119
|
+
<a href="#">Terms</a>
|
|
6120
|
+
<a href="#">Privacy</a>
|
|
6121
|
+
<a href="#">Support</a>
|
|
6122
|
+
</div>
|
|
6123
|
+
</div>
|
|
6124
|
+
</footer>
|
|
6125
6125
|
`, isInline: true, styles: [".footer-container{height:52px;padding:0 28px;background:var(--app-navbar-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));border-top:1px solid var(--glass-border);display:flex;align-items:center;margin-top:auto;position:relative}.footer-container:before{content:\"\";position:absolute;top:0;left:10%;right:10%;height:1px;background:linear-gradient(to right,transparent,var(--app-primary-light),transparent)}.footer-content{width:100%;display:flex;justify-content:space-between;align-items:center}.copyright{font-size:.8125rem;color:var(--app-text-muted);opacity:.6}.links{display:flex;gap:20px}.links a{font-size:.8125rem;color:var(--app-text-muted);text-decoration:none;transition:all var(--transition-fast);opacity:.6}.links a:hover{color:var(--app-primary);opacity:1}\n"] });
|
|
6126
6126
|
}
|
|
6127
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6127
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: FooterComponent, decorators: [{
|
|
6128
6128
|
type: Component,
|
|
6129
|
-
args: [{ selector: 'app-footer', standalone: true, imports: [], template: `
|
|
6130
|
-
<footer class="footer-container">
|
|
6131
|
-
<div class="footer-content">
|
|
6132
|
-
<p class="copyright">{{ config.copyrightText() }}</p>
|
|
6133
|
-
<div class="links">
|
|
6134
|
-
<a href="#">Terms</a>
|
|
6135
|
-
<a href="#">Privacy</a>
|
|
6136
|
-
<a href="#">Support</a>
|
|
6137
|
-
</div>
|
|
6138
|
-
</div>
|
|
6139
|
-
</footer>
|
|
6129
|
+
args: [{ selector: 'app-footer', standalone: true, imports: [], template: `
|
|
6130
|
+
<footer class="footer-container">
|
|
6131
|
+
<div class="footer-content">
|
|
6132
|
+
<p class="copyright">{{ config.copyrightText() }}</p>
|
|
6133
|
+
<div class="links">
|
|
6134
|
+
<a href="#">Terms</a>
|
|
6135
|
+
<a href="#">Privacy</a>
|
|
6136
|
+
<a href="#">Support</a>
|
|
6137
|
+
</div>
|
|
6138
|
+
</div>
|
|
6139
|
+
</footer>
|
|
6140
6140
|
`, styles: [".footer-container{height:52px;padding:0 28px;background:var(--app-navbar-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));border-top:1px solid var(--glass-border);display:flex;align-items:center;margin-top:auto;position:relative}.footer-container:before{content:\"\";position:absolute;top:0;left:10%;right:10%;height:1px;background:linear-gradient(to right,transparent,var(--app-primary-light),transparent)}.footer-content{width:100%;display:flex;justify-content:space-between;align-items:center}.copyright{font-size:.8125rem;color:var(--app-text-muted);opacity:.6}.links{display:flex;gap:20px}.links a{font-size:.8125rem;color:var(--app-text-muted);text-decoration:none;transition:all var(--transition-fast);opacity:.6}.links a:hover{color:var(--app-primary);opacity:1}\n"] }]
|
|
6141
6141
|
}] });
|
|
6142
6142
|
|
|
6143
6143
|
class VerticalLayoutComponent {
|
|
6144
6144
|
config = inject(AppConfigService);
|
|
6145
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6146
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
6147
|
-
<div class="layout-wrapper" [class.collapsed]="config.sidebarCollapsed()">
|
|
6148
|
-
<!-- Animated Gradient Mesh Background -->
|
|
6149
|
-
<div class="gradient-mesh" aria-hidden="true">
|
|
6150
|
-
<div class="blob blob-1"></div>
|
|
6151
|
-
<div class="blob blob-2"></div>
|
|
6152
|
-
<div class="blob blob-3"></div>
|
|
6153
|
-
</div>
|
|
6154
|
-
|
|
6155
|
-
<!-- Sidebar -->
|
|
6156
|
-
<app-sidebar class="layout-sidebar"></app-sidebar>
|
|
6157
|
-
|
|
6158
|
-
<!-- Main Content Area -->
|
|
6159
|
-
<div class="layout-main">
|
|
6160
|
-
<app-navbar></app-navbar>
|
|
6161
|
-
|
|
6162
|
-
<main class="content-body">
|
|
6163
|
-
<router-outlet></router-outlet>
|
|
6164
|
-
</main>
|
|
6165
|
-
|
|
6166
|
-
<app-footer></app-footer>
|
|
6167
|
-
</div>
|
|
6168
|
-
</div>
|
|
6145
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: VerticalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6146
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.15", type: VerticalLayoutComponent, isStandalone: true, selector: "app-vertical-layout", ngImport: i0, template: `
|
|
6147
|
+
<div class="layout-wrapper" [class.collapsed]="config.sidebarCollapsed()">
|
|
6148
|
+
<!-- Animated Gradient Mesh Background -->
|
|
6149
|
+
<div class="gradient-mesh" aria-hidden="true">
|
|
6150
|
+
<div class="blob blob-1"></div>
|
|
6151
|
+
<div class="blob blob-2"></div>
|
|
6152
|
+
<div class="blob blob-3"></div>
|
|
6153
|
+
</div>
|
|
6154
|
+
|
|
6155
|
+
<!-- Sidebar -->
|
|
6156
|
+
<app-sidebar class="layout-sidebar"></app-sidebar>
|
|
6157
|
+
|
|
6158
|
+
<!-- Main Content Area -->
|
|
6159
|
+
<div class="layout-main">
|
|
6160
|
+
<app-navbar></app-navbar>
|
|
6161
|
+
|
|
6162
|
+
<main class="content-body">
|
|
6163
|
+
<router-outlet></router-outlet>
|
|
6164
|
+
</main>
|
|
6165
|
+
|
|
6166
|
+
<app-footer></app-footer>
|
|
6167
|
+
</div>
|
|
6168
|
+
</div>
|
|
6169
6169
|
`, isInline: true, styles: [":host{display:block;height:100vh;width:100%}.layout-wrapper{display:flex;height:100vh;overflow:hidden;background:var(--app-bg);position:relative}.gradient-mesh{position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none}.blob{position:absolute;border-radius:50%;filter:blur(80px);opacity:.35;will-change:transform}.blob-1{width:500px;height:500px;background:var(--app-gradient-1);top:-10%;right:-5%;animation:blobMove1 20s ease-in-out infinite}.blob-2{width:400px;height:400px;background:var(--app-gradient-2);bottom:-10%;left:10%;animation:blobMove2 25s ease-in-out infinite}.blob-3{width:350px;height:350px;background:var(--app-gradient-3);top:40%;left:40%;animation:blobMove3 22s ease-in-out infinite}.layout-sidebar{flex-shrink:0;z-index:100;position:relative}.layout-main{flex:1;display:flex;flex-direction:column;overflow-y:auto;position:relative;z-index:1;transition:margin-left var(--transition-smooth)}.content-body{padding:28px;flex:1;max-width:1600px;width:100%;margin:0 auto;animation:fadeInUp .4s ease-out}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: SidebarComponent, selector: "app-sidebar" }, { kind: "component", type: NavbarComponent, selector: "app-navbar" }, { kind: "component", type: FooterComponent, selector: "app-footer" }] });
|
|
6170
6170
|
}
|
|
6171
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6171
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: VerticalLayoutComponent, decorators: [{
|
|
6172
6172
|
type: Component,
|
|
6173
|
-
args: [{ selector: 'app-vertical-layout', standalone: true, imports: [RouterOutlet, SidebarComponent, NavbarComponent, FooterComponent], template: `
|
|
6174
|
-
<div class="layout-wrapper" [class.collapsed]="config.sidebarCollapsed()">
|
|
6175
|
-
<!-- Animated Gradient Mesh Background -->
|
|
6176
|
-
<div class="gradient-mesh" aria-hidden="true">
|
|
6177
|
-
<div class="blob blob-1"></div>
|
|
6178
|
-
<div class="blob blob-2"></div>
|
|
6179
|
-
<div class="blob blob-3"></div>
|
|
6180
|
-
</div>
|
|
6181
|
-
|
|
6182
|
-
<!-- Sidebar -->
|
|
6183
|
-
<app-sidebar class="layout-sidebar"></app-sidebar>
|
|
6184
|
-
|
|
6185
|
-
<!-- Main Content Area -->
|
|
6186
|
-
<div class="layout-main">
|
|
6187
|
-
<app-navbar></app-navbar>
|
|
6188
|
-
|
|
6189
|
-
<main class="content-body">
|
|
6190
|
-
<router-outlet></router-outlet>
|
|
6191
|
-
</main>
|
|
6192
|
-
|
|
6193
|
-
<app-footer></app-footer>
|
|
6194
|
-
</div>
|
|
6195
|
-
</div>
|
|
6173
|
+
args: [{ selector: 'app-vertical-layout', standalone: true, imports: [RouterOutlet, SidebarComponent, NavbarComponent, FooterComponent], template: `
|
|
6174
|
+
<div class="layout-wrapper" [class.collapsed]="config.sidebarCollapsed()">
|
|
6175
|
+
<!-- Animated Gradient Mesh Background -->
|
|
6176
|
+
<div class="gradient-mesh" aria-hidden="true">
|
|
6177
|
+
<div class="blob blob-1"></div>
|
|
6178
|
+
<div class="blob blob-2"></div>
|
|
6179
|
+
<div class="blob blob-3"></div>
|
|
6180
|
+
</div>
|
|
6181
|
+
|
|
6182
|
+
<!-- Sidebar -->
|
|
6183
|
+
<app-sidebar class="layout-sidebar"></app-sidebar>
|
|
6184
|
+
|
|
6185
|
+
<!-- Main Content Area -->
|
|
6186
|
+
<div class="layout-main">
|
|
6187
|
+
<app-navbar></app-navbar>
|
|
6188
|
+
|
|
6189
|
+
<main class="content-body">
|
|
6190
|
+
<router-outlet></router-outlet>
|
|
6191
|
+
</main>
|
|
6192
|
+
|
|
6193
|
+
<app-footer></app-footer>
|
|
6194
|
+
</div>
|
|
6195
|
+
</div>
|
|
6196
6196
|
`, styles: [":host{display:block;height:100vh;width:100%}.layout-wrapper{display:flex;height:100vh;overflow:hidden;background:var(--app-bg);position:relative}.gradient-mesh{position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none}.blob{position:absolute;border-radius:50%;filter:blur(80px);opacity:.35;will-change:transform}.blob-1{width:500px;height:500px;background:var(--app-gradient-1);top:-10%;right:-5%;animation:blobMove1 20s ease-in-out infinite}.blob-2{width:400px;height:400px;background:var(--app-gradient-2);bottom:-10%;left:10%;animation:blobMove2 25s ease-in-out infinite}.blob-3{width:350px;height:350px;background:var(--app-gradient-3);top:40%;left:40%;animation:blobMove3 22s ease-in-out infinite}.layout-sidebar{flex-shrink:0;z-index:100;position:relative}.layout-main{flex:1;display:flex;flex-direction:column;overflow-y:auto;position:relative;z-index:1;transition:margin-left var(--transition-smooth)}.content-body{padding:28px;flex:1;max-width:1600px;width:100%;margin:0 auto;animation:fadeInUp .4s ease-out}\n"] }]
|
|
6197
6197
|
}] });
|
|
6198
6198
|
|
|
6199
6199
|
class HorizontalLayoutComponent {
|
|
6200
6200
|
navigation = inject(NavigationService);
|
|
6201
6201
|
iconRegistry = inject(IconRegistryService);
|
|
6202
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6203
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
6204
|
-
<div class="layout-wrapper">
|
|
6205
|
-
<app-navbar>
|
|
6206
|
-
<!-- Horizontal Menu Injection (Conceptual - in a full app we'd use a dedicated component or slot) -->
|
|
6207
|
-
</app-navbar>
|
|
6208
|
-
|
|
6209
|
-
<nav class="horizontal-nav">
|
|
6210
|
-
<div class="nav-container">
|
|
6211
|
-
<ul>
|
|
6212
|
-
@for (group of navigation.menuItems(); track group.label) {
|
|
6213
|
-
@for (item of group.items; track item.label) {
|
|
6214
|
-
<li class="nav-item">
|
|
6215
|
-
<a [routerLink]="item.route" routerLinkActive="active" class="nav-link">
|
|
6216
|
-
@if (item.icon) {
|
|
6217
|
-
<svg viewBox="0 0 24 24" class="nav-icon">
|
|
6218
|
-
<path [attr.d]="iconRegistry.getIcon(item.icon)"></path>
|
|
6219
|
-
</svg>
|
|
6220
|
-
}
|
|
6221
|
-
{{ item.label }}
|
|
6222
|
-
</a>
|
|
6223
|
-
</li>
|
|
6224
|
-
}
|
|
6225
|
-
}
|
|
6226
|
-
</ul>
|
|
6227
|
-
</div>
|
|
6228
|
-
</nav>
|
|
6229
|
-
|
|
6230
|
-
<main class="content-body">
|
|
6231
|
-
<router-outlet></router-outlet>
|
|
6232
|
-
</main>
|
|
6233
|
-
|
|
6234
|
-
<app-footer></app-footer>
|
|
6235
|
-
</div>
|
|
6202
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: HorizontalLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6203
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: HorizontalLayoutComponent, isStandalone: true, selector: "app-horizontal-layout", ngImport: i0, template: `
|
|
6204
|
+
<div class="layout-wrapper">
|
|
6205
|
+
<app-navbar>
|
|
6206
|
+
<!-- Horizontal Menu Injection (Conceptual - in a full app we'd use a dedicated component or slot) -->
|
|
6207
|
+
</app-navbar>
|
|
6208
|
+
|
|
6209
|
+
<nav class="horizontal-nav">
|
|
6210
|
+
<div class="nav-container">
|
|
6211
|
+
<ul>
|
|
6212
|
+
@for (group of navigation.menuItems(); track group.label) {
|
|
6213
|
+
@for (item of group.items; track item.label) {
|
|
6214
|
+
<li class="nav-item">
|
|
6215
|
+
<a [routerLink]="item.route" routerLinkActive="active" class="nav-link">
|
|
6216
|
+
@if (item.icon) {
|
|
6217
|
+
<svg viewBox="0 0 24 24" class="nav-icon">
|
|
6218
|
+
<path [attr.d]="iconRegistry.getIcon(item.icon)"></path>
|
|
6219
|
+
</svg>
|
|
6220
|
+
}
|
|
6221
|
+
{{ item.label }}
|
|
6222
|
+
</a>
|
|
6223
|
+
</li>
|
|
6224
|
+
}
|
|
6225
|
+
}
|
|
6226
|
+
</ul>
|
|
6227
|
+
</div>
|
|
6228
|
+
</nav>
|
|
6229
|
+
|
|
6230
|
+
<main class="content-body">
|
|
6231
|
+
<router-outlet></router-outlet>
|
|
6232
|
+
</main>
|
|
6233
|
+
|
|
6234
|
+
<app-footer></app-footer>
|
|
6235
|
+
</div>
|
|
6236
6236
|
`, isInline: true, styles: [".layout-wrapper{display:flex;flex-direction:column;min-height:100vh;background:var(--app-bg, #f9fafb)}.horizontal-nav{background:var(--app-navbar-bg, #ffffff);border-bottom:1px solid var(--app-border, #e5e7eb);height:48px}.nav-container{max-width:1600px;margin:0 auto;height:100%;padding:0 24px}ul{display:flex;list-style:none;padding:0;margin:0;height:100%;gap:32px}.nav-item{height:100%}.nav-link{display:flex;align-items:center;gap:8px;height:100%;color:var(--app-text, #374151);text-decoration:none;font-size:.875rem;font-weight:500;border-bottom:2px solid transparent;transition:all .2s}.nav-link:hover{color:var(--app-primary, #3b82f6)}.nav-link.active{color:var(--app-primary, #3b82f6);border-bottom-color:var(--app-primary, #3b82f6)}.nav-icon{width:18px;height:18px;fill:currentColor}.content-body{padding:24px;flex:1;max-width:1600px;width:100%;margin:0 auto}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: NavbarComponent, selector: "app-navbar" }, { kind: "component", type: FooterComponent, selector: "app-footer" }, { 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"] }] });
|
|
6237
6237
|
}
|
|
6238
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6238
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: HorizontalLayoutComponent, decorators: [{
|
|
6239
6239
|
type: Component,
|
|
6240
|
-
args: [{ selector: 'app-horizontal-layout', standalone: true, imports: [RouterOutlet, NavbarComponent, FooterComponent, RouterLink, RouterLinkActive], template: `
|
|
6241
|
-
<div class="layout-wrapper">
|
|
6242
|
-
<app-navbar>
|
|
6243
|
-
<!-- Horizontal Menu Injection (Conceptual - in a full app we'd use a dedicated component or slot) -->
|
|
6244
|
-
</app-navbar>
|
|
6245
|
-
|
|
6246
|
-
<nav class="horizontal-nav">
|
|
6247
|
-
<div class="nav-container">
|
|
6248
|
-
<ul>
|
|
6249
|
-
@for (group of navigation.menuItems(); track group.label) {
|
|
6250
|
-
@for (item of group.items; track item.label) {
|
|
6251
|
-
<li class="nav-item">
|
|
6252
|
-
<a [routerLink]="item.route" routerLinkActive="active" class="nav-link">
|
|
6253
|
-
@if (item.icon) {
|
|
6254
|
-
<svg viewBox="0 0 24 24" class="nav-icon">
|
|
6255
|
-
<path [attr.d]="iconRegistry.getIcon(item.icon)"></path>
|
|
6256
|
-
</svg>
|
|
6257
|
-
}
|
|
6258
|
-
{{ item.label }}
|
|
6259
|
-
</a>
|
|
6260
|
-
</li>
|
|
6261
|
-
}
|
|
6262
|
-
}
|
|
6263
|
-
</ul>
|
|
6264
|
-
</div>
|
|
6265
|
-
</nav>
|
|
6266
|
-
|
|
6267
|
-
<main class="content-body">
|
|
6268
|
-
<router-outlet></router-outlet>
|
|
6269
|
-
</main>
|
|
6270
|
-
|
|
6271
|
-
<app-footer></app-footer>
|
|
6272
|
-
</div>
|
|
6240
|
+
args: [{ selector: 'app-horizontal-layout', standalone: true, imports: [RouterOutlet, NavbarComponent, FooterComponent, RouterLink, RouterLinkActive], template: `
|
|
6241
|
+
<div class="layout-wrapper">
|
|
6242
|
+
<app-navbar>
|
|
6243
|
+
<!-- Horizontal Menu Injection (Conceptual - in a full app we'd use a dedicated component or slot) -->
|
|
6244
|
+
</app-navbar>
|
|
6245
|
+
|
|
6246
|
+
<nav class="horizontal-nav">
|
|
6247
|
+
<div class="nav-container">
|
|
6248
|
+
<ul>
|
|
6249
|
+
@for (group of navigation.menuItems(); track group.label) {
|
|
6250
|
+
@for (item of group.items; track item.label) {
|
|
6251
|
+
<li class="nav-item">
|
|
6252
|
+
<a [routerLink]="item.route" routerLinkActive="active" class="nav-link">
|
|
6253
|
+
@if (item.icon) {
|
|
6254
|
+
<svg viewBox="0 0 24 24" class="nav-icon">
|
|
6255
|
+
<path [attr.d]="iconRegistry.getIcon(item.icon)"></path>
|
|
6256
|
+
</svg>
|
|
6257
|
+
}
|
|
6258
|
+
{{ item.label }}
|
|
6259
|
+
</a>
|
|
6260
|
+
</li>
|
|
6261
|
+
}
|
|
6262
|
+
}
|
|
6263
|
+
</ul>
|
|
6264
|
+
</div>
|
|
6265
|
+
</nav>
|
|
6266
|
+
|
|
6267
|
+
<main class="content-body">
|
|
6268
|
+
<router-outlet></router-outlet>
|
|
6269
|
+
</main>
|
|
6270
|
+
|
|
6271
|
+
<app-footer></app-footer>
|
|
6272
|
+
</div>
|
|
6273
6273
|
`, styles: [".layout-wrapper{display:flex;flex-direction:column;min-height:100vh;background:var(--app-bg, #f9fafb)}.horizontal-nav{background:var(--app-navbar-bg, #ffffff);border-bottom:1px solid var(--app-border, #e5e7eb);height:48px}.nav-container{max-width:1600px;margin:0 auto;height:100%;padding:0 24px}ul{display:flex;list-style:none;padding:0;margin:0;height:100%;gap:32px}.nav-item{height:100%}.nav-link{display:flex;align-items:center;gap:8px;height:100%;color:var(--app-text, #374151);text-decoration:none;font-size:.875rem;font-weight:500;border-bottom:2px solid transparent;transition:all .2s}.nav-link:hover{color:var(--app-primary, #3b82f6)}.nav-link.active{color:var(--app-primary, #3b82f6);border-bottom-color:var(--app-primary, #3b82f6)}.nav-icon{width:18px;height:18px;fill:currentColor}.content-body{padding:24px;flex:1;max-width:1600px;width:100%;margin:0 auto}\n"] }]
|
|
6274
6274
|
}] });
|
|
6275
6275
|
|
|
6276
6276
|
class EmptyLayoutComponent {
|
|
6277
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6278
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
6279
|
-
<div class="empty-layout-container">
|
|
6280
|
-
<router-outlet></router-outlet>
|
|
6281
|
-
</div>
|
|
6277
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: EmptyLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6278
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.15", type: EmptyLayoutComponent, isStandalone: true, selector: "app-empty-layout", ngImport: i0, template: `
|
|
6279
|
+
<div class="empty-layout-container">
|
|
6280
|
+
<router-outlet></router-outlet>
|
|
6281
|
+
</div>
|
|
6282
6282
|
`, isInline: true, styles: [":host{display:flex;flex-direction:column;height:100%}.empty-layout-container{height:100%;display:flex;flex-direction:column;background:var(--app-bg, #f9fafb);color:var(--app-text, #111827)}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
|
|
6283
6283
|
}
|
|
6284
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6284
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: EmptyLayoutComponent, decorators: [{
|
|
6285
6285
|
type: Component,
|
|
6286
|
-
args: [{ selector: 'app-empty-layout', standalone: true, imports: [RouterOutlet], template: `
|
|
6287
|
-
<div class="empty-layout-container">
|
|
6288
|
-
<router-outlet></router-outlet>
|
|
6289
|
-
</div>
|
|
6286
|
+
args: [{ selector: 'app-empty-layout', standalone: true, imports: [RouterOutlet], template: `
|
|
6287
|
+
<div class="empty-layout-container">
|
|
6288
|
+
<router-outlet></router-outlet>
|
|
6289
|
+
</div>
|
|
6290
6290
|
`, styles: [":host{display:flex;flex-direction:column;height:100%}.empty-layout-container{height:100%;display:flex;flex-direction:column;background:var(--app-bg, #f9fafb);color:var(--app-text, #111827)}\n"] }]
|
|
6291
6291
|
}] });
|
|
6292
6292
|
|
|
6293
6293
|
class CenteredLayoutComponent {
|
|
6294
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6295
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
6296
|
-
<div class="centered-container">
|
|
6297
|
-
<div class="centered-content glass-panel">
|
|
6298
|
-
<router-outlet></router-outlet>
|
|
6299
|
-
</div>
|
|
6300
|
-
</div>
|
|
6294
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CenteredLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6295
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.15", type: CenteredLayoutComponent, isStandalone: true, selector: "app-centered-layout", ngImport: i0, template: `
|
|
6296
|
+
<div class="centered-container">
|
|
6297
|
+
<div class="centered-content glass-panel">
|
|
6298
|
+
<router-outlet></router-outlet>
|
|
6299
|
+
</div>
|
|
6300
|
+
</div>
|
|
6301
6301
|
`, isInline: true, styles: [".centered-container{display:flex;align-items:center;justify-content:center;min-height:100vh;background:var(--app-bg, #f9fafb);padding:2rem}.centered-content{width:100%;max-width:600px;padding:2rem;border-radius:1rem}.glass-panel{background:var(--glass-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));border:1px solid var(--glass-border);box-shadow:var(--glass-shadow)}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
|
|
6302
6302
|
}
|
|
6303
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6303
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CenteredLayoutComponent, decorators: [{
|
|
6304
6304
|
type: Component,
|
|
6305
|
-
args: [{ selector: 'app-centered-layout', standalone: true, imports: [RouterOutlet], template: `
|
|
6306
|
-
<div class="centered-container">
|
|
6307
|
-
<div class="centered-content glass-panel">
|
|
6308
|
-
<router-outlet></router-outlet>
|
|
6309
|
-
</div>
|
|
6310
|
-
</div>
|
|
6305
|
+
args: [{ selector: 'app-centered-layout', standalone: true, imports: [RouterOutlet], template: `
|
|
6306
|
+
<div class="centered-container">
|
|
6307
|
+
<div class="centered-content glass-panel">
|
|
6308
|
+
<router-outlet></router-outlet>
|
|
6309
|
+
</div>
|
|
6310
|
+
</div>
|
|
6311
6311
|
`, styles: [".centered-container{display:flex;align-items:center;justify-content:center;min-height:100vh;background:var(--app-bg, #f9fafb);padding:2rem}.centered-content{width:100%;max-width:600px;padding:2rem;border-radius:1rem}.glass-panel{background:var(--glass-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur));border:1px solid var(--glass-border);box-shadow:var(--glass-shadow)}\n"] }]
|
|
6312
6312
|
}] });
|
|
6313
6313
|
|
|
6314
6314
|
class TwoColumnLayoutComponent {
|
|
6315
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6316
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
6317
|
-
<div class="two-column-container">
|
|
6318
|
-
<aside class="left-panel glass-panel">
|
|
6319
|
-
<!-- Master list or secondary navigation ideally goes here -->
|
|
6320
|
-
<div class="placeholder-nav">Navigation / List</div>
|
|
6321
|
-
</aside>
|
|
6322
|
-
<main class="right-panel">
|
|
6323
|
-
<router-outlet></router-outlet>
|
|
6324
|
-
</main>
|
|
6325
|
-
</div>
|
|
6315
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: TwoColumnLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6316
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.15", type: TwoColumnLayoutComponent, isStandalone: true, selector: "app-two-column-layout", ngImport: i0, template: `
|
|
6317
|
+
<div class="two-column-container">
|
|
6318
|
+
<aside class="left-panel glass-panel">
|
|
6319
|
+
<!-- Master list or secondary navigation ideally goes here -->
|
|
6320
|
+
<div class="placeholder-nav">Navigation / List</div>
|
|
6321
|
+
</aside>
|
|
6322
|
+
<main class="right-panel">
|
|
6323
|
+
<router-outlet></router-outlet>
|
|
6324
|
+
</main>
|
|
6325
|
+
</div>
|
|
6326
6326
|
`, isInline: true, styles: [".two-column-container{display:flex;min-height:100vh;background:var(--app-bg)}.left-panel{width:300px;flex-shrink:0;border-right:1px solid var(--glass-border);padding:1rem;display:flex;flex-direction:column}.right-panel{flex:1;padding:2rem;overflow-y:auto}.glass-panel{background:var(--glass-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur))}.placeholder-nav{color:var(--app-text-muted);font-size:.875rem;text-align:center;margin-top:2rem}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
|
|
6327
6327
|
}
|
|
6328
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6328
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: TwoColumnLayoutComponent, decorators: [{
|
|
6329
6329
|
type: Component,
|
|
6330
|
-
args: [{ selector: 'app-two-column-layout', standalone: true, imports: [RouterOutlet], template: `
|
|
6331
|
-
<div class="two-column-container">
|
|
6332
|
-
<aside class="left-panel glass-panel">
|
|
6333
|
-
<!-- Master list or secondary navigation ideally goes here -->
|
|
6334
|
-
<div class="placeholder-nav">Navigation / List</div>
|
|
6335
|
-
</aside>
|
|
6336
|
-
<main class="right-panel">
|
|
6337
|
-
<router-outlet></router-outlet>
|
|
6338
|
-
</main>
|
|
6339
|
-
</div>
|
|
6330
|
+
args: [{ selector: 'app-two-column-layout', standalone: true, imports: [RouterOutlet], template: `
|
|
6331
|
+
<div class="two-column-container">
|
|
6332
|
+
<aside class="left-panel glass-panel">
|
|
6333
|
+
<!-- Master list or secondary navigation ideally goes here -->
|
|
6334
|
+
<div class="placeholder-nav">Navigation / List</div>
|
|
6335
|
+
</aside>
|
|
6336
|
+
<main class="right-panel">
|
|
6337
|
+
<router-outlet></router-outlet>
|
|
6338
|
+
</main>
|
|
6339
|
+
</div>
|
|
6340
6340
|
`, styles: [".two-column-container{display:flex;min-height:100vh;background:var(--app-bg)}.left-panel{width:300px;flex-shrink:0;border-right:1px solid var(--glass-border);padding:1rem;display:flex;flex-direction:column}.right-panel{flex:1;padding:2rem;overflow-y:auto}.glass-panel{background:var(--glass-bg);backdrop-filter:blur(var(--glass-blur));-webkit-backdrop-filter:blur(var(--glass-blur))}.placeholder-nav{color:var(--app-text-muted);font-size:.875rem;text-align:center;margin-top:2rem}\n"] }]
|
|
6341
6341
|
}] });
|
|
6342
6342
|
|
|
6343
6343
|
class DashboardGridLayoutComponent {
|
|
6344
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6345
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
6346
|
-
<div class="dashboard-grid-container">
|
|
6347
|
-
<router-outlet></router-outlet>
|
|
6348
|
-
</div>
|
|
6344
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: DashboardGridLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6345
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.15", type: DashboardGridLayoutComponent, isStandalone: true, selector: "app-dashboard-grid-layout", ngImport: i0, template: `
|
|
6346
|
+
<div class="dashboard-grid-container">
|
|
6347
|
+
<router-outlet></router-outlet>
|
|
6348
|
+
</div>
|
|
6349
6349
|
`, isInline: true, styles: [".dashboard-grid-container{display:grid;grid-template-columns:repeat(12,1fr);gap:1.5rem;padding:2rem;min-height:100vh;background:var(--app-bg)}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
|
|
6350
6350
|
}
|
|
6351
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6351
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: DashboardGridLayoutComponent, decorators: [{
|
|
6352
6352
|
type: Component,
|
|
6353
|
-
args: [{ selector: 'app-dashboard-grid-layout', standalone: true, imports: [RouterOutlet], template: `
|
|
6354
|
-
<div class="dashboard-grid-container">
|
|
6355
|
-
<router-outlet></router-outlet>
|
|
6356
|
-
</div>
|
|
6353
|
+
args: [{ selector: 'app-dashboard-grid-layout', standalone: true, imports: [RouterOutlet], template: `
|
|
6354
|
+
<div class="dashboard-grid-container">
|
|
6355
|
+
<router-outlet></router-outlet>
|
|
6356
|
+
</div>
|
|
6357
6357
|
`, styles: [".dashboard-grid-container{display:grid;grid-template-columns:repeat(12,1fr);gap:1.5rem;padding:2rem;min-height:100vh;background:var(--app-bg)}\n"] }]
|
|
6358
6358
|
}] });
|
|
6359
6359
|
|
|
6360
6360
|
class CompactLayoutComponent {
|
|
6361
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6362
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.
|
|
6363
|
-
<div class="compact-container">
|
|
6364
|
-
<!-- Minimal or no header -->
|
|
6365
|
-
<main class="compact-content">
|
|
6366
|
-
<router-outlet></router-outlet>
|
|
6367
|
-
</main>
|
|
6368
|
-
</div>
|
|
6361
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CompactLayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6362
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.15", type: CompactLayoutComponent, isStandalone: true, selector: "app-compact-layout", ngImport: i0, template: `
|
|
6363
|
+
<div class="compact-container">
|
|
6364
|
+
<!-- Minimal or no header -->
|
|
6365
|
+
<main class="compact-content">
|
|
6366
|
+
<router-outlet></router-outlet>
|
|
6367
|
+
</main>
|
|
6368
|
+
</div>
|
|
6369
6369
|
`, isInline: true, styles: [".compact-container{display:flex;flex-direction:column;min-height:100vh;background:var(--app-bg)}.compact-content{flex:1;padding:1rem;max-width:100%;overflow-x:hidden}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
|
|
6370
6370
|
}
|
|
6371
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6371
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: CompactLayoutComponent, decorators: [{
|
|
6372
6372
|
type: Component,
|
|
6373
|
-
args: [{ selector: 'app-compact-layout', standalone: true, imports: [RouterOutlet], template: `
|
|
6374
|
-
<div class="compact-container">
|
|
6375
|
-
<!-- Minimal or no header -->
|
|
6376
|
-
<main class="compact-content">
|
|
6377
|
-
<router-outlet></router-outlet>
|
|
6378
|
-
</main>
|
|
6379
|
-
</div>
|
|
6373
|
+
args: [{ selector: 'app-compact-layout', standalone: true, imports: [RouterOutlet], template: `
|
|
6374
|
+
<div class="compact-container">
|
|
6375
|
+
<!-- Minimal or no header -->
|
|
6376
|
+
<main class="compact-content">
|
|
6377
|
+
<router-outlet></router-outlet>
|
|
6378
|
+
</main>
|
|
6379
|
+
</div>
|
|
6380
6380
|
`, styles: [".compact-container{display:flex;flex-direction:column;min-height:100vh;background:var(--app-bg)}.compact-content{flex:1;padding:1rem;max-width:100%;overflow-x:hidden}\n"] }]
|
|
6381
6381
|
}] });
|
|
6382
6382
|
|
|
@@ -6391,51 +6391,51 @@ class NotificationContainerComponent {
|
|
|
6391
6391
|
default: return this.iconRegistry.getIcon('info');
|
|
6392
6392
|
}
|
|
6393
6393
|
}
|
|
6394
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6395
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
6396
|
-
<div class="notification-wrapper">
|
|
6397
|
-
@for (n of service.notifications(); track n.id) {
|
|
6398
|
-
<div class="toast" [class]="n.type" (click)="service.remove(n.id)">
|
|
6399
|
-
<div class="toast-icon">
|
|
6400
|
-
<svg viewBox="0 0 24 24">
|
|
6401
|
-
<path [attr.d]="getIcon(n.type)"></path>
|
|
6402
|
-
</svg>
|
|
6403
|
-
</div>
|
|
6404
|
-
<div class="toast-content">
|
|
6405
|
-
{{ n.message }}
|
|
6406
|
-
</div>
|
|
6407
|
-
<button class="toast-close">
|
|
6408
|
-
<svg viewBox="0 0 24 24">
|
|
6409
|
-
<path [attr.d]="iconRegistry.getIcon('close')"></path>
|
|
6410
|
-
</svg>
|
|
6411
|
-
</button>
|
|
6412
|
-
</div>
|
|
6413
|
-
}
|
|
6414
|
-
</div>
|
|
6394
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: NotificationContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6395
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: NotificationContainerComponent, isStandalone: true, selector: "app-notification-container", ngImport: i0, template: `
|
|
6396
|
+
<div class="notification-wrapper">
|
|
6397
|
+
@for (n of service.notifications(); track n.id) {
|
|
6398
|
+
<div class="toast" [class]="n.type" (click)="service.remove(n.id)">
|
|
6399
|
+
<div class="toast-icon">
|
|
6400
|
+
<svg viewBox="0 0 24 24">
|
|
6401
|
+
<path [attr.d]="getIcon(n.type)"></path>
|
|
6402
|
+
</svg>
|
|
6403
|
+
</div>
|
|
6404
|
+
<div class="toast-content">
|
|
6405
|
+
{{ n.message }}
|
|
6406
|
+
</div>
|
|
6407
|
+
<button class="toast-close">
|
|
6408
|
+
<svg viewBox="0 0 24 24">
|
|
6409
|
+
<path [attr.d]="iconRegistry.getIcon('close')"></path>
|
|
6410
|
+
</svg>
|
|
6411
|
+
</button>
|
|
6412
|
+
</div>
|
|
6413
|
+
}
|
|
6414
|
+
</div>
|
|
6415
6415
|
`, isInline: true, styles: [".notification-wrapper{position:fixed;top:24px;right:24px;z-index:9999;display:flex;flex-direction:column;gap:12px;pointer-events:none}.toast{pointer-events:auto;min-width:300px;max-width:450px;background:var(--app-surface, #ffffff);border-radius:12px;padding:16px;display:flex;align-items:center;gap:12px;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d;border-left:4px solid #e5e7eb;cursor:pointer;animation:slideIn .3s cubic-bezier(.4,0,.2,1);transition:all .2s}.toast:hover{transform:translateY(-2px);box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a}.toast.success{border-left-color:#10b981}.toast.error{border-left-color:#ef4444}.toast.warning{border-left-color:#f59e0b}.toast.info{border-left-color:#3b82f6}.toast-icon{width:24px;height:24px;flex-shrink:0}.toast.success .toast-icon{fill:#10b981}.toast.error .toast-icon{fill:#ef4444}.toast.warning .toast-icon{fill:#f59e0b}.toast.info .toast-icon{fill:#3b82f6}.toast-content{flex:1;font-size:.875rem;font-weight:500;color:var(--app-text, #1f2937);line-height:1.4}.toast-close{background:none;border:none;padding:4px;cursor:pointer;color:var(--app-text-muted, #6b7280);opacity:.5;transition:opacity .2s}.toast-close:hover{opacity:1}.toast-close svg{width:16px;height:16px;fill:currentColor}@keyframes slideIn{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}\n"] });
|
|
6416
6416
|
}
|
|
6417
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6417
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: NotificationContainerComponent, decorators: [{
|
|
6418
6418
|
type: Component,
|
|
6419
|
-
args: [{ selector: 'app-notification-container', standalone: true, imports: [], template: `
|
|
6420
|
-
<div class="notification-wrapper">
|
|
6421
|
-
@for (n of service.notifications(); track n.id) {
|
|
6422
|
-
<div class="toast" [class]="n.type" (click)="service.remove(n.id)">
|
|
6423
|
-
<div class="toast-icon">
|
|
6424
|
-
<svg viewBox="0 0 24 24">
|
|
6425
|
-
<path [attr.d]="getIcon(n.type)"></path>
|
|
6426
|
-
</svg>
|
|
6427
|
-
</div>
|
|
6428
|
-
<div class="toast-content">
|
|
6429
|
-
{{ n.message }}
|
|
6430
|
-
</div>
|
|
6431
|
-
<button class="toast-close">
|
|
6432
|
-
<svg viewBox="0 0 24 24">
|
|
6433
|
-
<path [attr.d]="iconRegistry.getIcon('close')"></path>
|
|
6434
|
-
</svg>
|
|
6435
|
-
</button>
|
|
6436
|
-
</div>
|
|
6437
|
-
}
|
|
6438
|
-
</div>
|
|
6419
|
+
args: [{ selector: 'app-notification-container', standalone: true, imports: [], template: `
|
|
6420
|
+
<div class="notification-wrapper">
|
|
6421
|
+
@for (n of service.notifications(); track n.id) {
|
|
6422
|
+
<div class="toast" [class]="n.type" (click)="service.remove(n.id)">
|
|
6423
|
+
<div class="toast-icon">
|
|
6424
|
+
<svg viewBox="0 0 24 24">
|
|
6425
|
+
<path [attr.d]="getIcon(n.type)"></path>
|
|
6426
|
+
</svg>
|
|
6427
|
+
</div>
|
|
6428
|
+
<div class="toast-content">
|
|
6429
|
+
{{ n.message }}
|
|
6430
|
+
</div>
|
|
6431
|
+
<button class="toast-close">
|
|
6432
|
+
<svg viewBox="0 0 24 24">
|
|
6433
|
+
<path [attr.d]="iconRegistry.getIcon('close')"></path>
|
|
6434
|
+
</svg>
|
|
6435
|
+
</button>
|
|
6436
|
+
</div>
|
|
6437
|
+
}
|
|
6438
|
+
</div>
|
|
6439
6439
|
`, styles: [".notification-wrapper{position:fixed;top:24px;right:24px;z-index:9999;display:flex;flex-direction:column;gap:12px;pointer-events:none}.toast{pointer-events:auto;min-width:300px;max-width:450px;background:var(--app-surface, #ffffff);border-radius:12px;padding:16px;display:flex;align-items:center;gap:12px;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d;border-left:4px solid #e5e7eb;cursor:pointer;animation:slideIn .3s cubic-bezier(.4,0,.2,1);transition:all .2s}.toast:hover{transform:translateY(-2px);box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a}.toast.success{border-left-color:#10b981}.toast.error{border-left-color:#ef4444}.toast.warning{border-left-color:#f59e0b}.toast.info{border-left-color:#3b82f6}.toast-icon{width:24px;height:24px;flex-shrink:0}.toast.success .toast-icon{fill:#10b981}.toast.error .toast-icon{fill:#ef4444}.toast.warning .toast-icon{fill:#f59e0b}.toast.info .toast-icon{fill:#3b82f6}.toast-content{flex:1;font-size:.875rem;font-weight:500;color:var(--app-text, #1f2937);line-height:1.4}.toast-close{background:none;border:none;padding:4px;cursor:pointer;color:var(--app-text-muted, #6b7280);opacity:.5;transition:opacity .2s}.toast-close:hover{opacity:1}.toast-close svg{width:16px;height:16px;fill:currentColor}@keyframes slideIn{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}\n"] }]
|
|
6440
6440
|
}] });
|
|
6441
6441
|
|
|
@@ -6446,41 +6446,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
6446
6446
|
class LayoutComponent {
|
|
6447
6447
|
config = inject(AppConfigService);
|
|
6448
6448
|
LayoutType = LayoutType;
|
|
6449
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
6450
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
6451
|
-
<app-notification-container></app-notification-container>
|
|
6452
|
-
<amf-modal-host></amf-modal-host>
|
|
6453
|
-
<amf-dialog-host></amf-dialog-host>
|
|
6454
|
-
<amf-drawer-host></amf-drawer-host>
|
|
6455
|
-
@switch (config.currentLayout()) {
|
|
6456
|
-
@case (LayoutType.VERTICAL) {
|
|
6457
|
-
<app-vertical-layout></app-vertical-layout>
|
|
6458
|
-
}
|
|
6459
|
-
@case (LayoutType.HORIZONTAL) {
|
|
6460
|
-
<app-horizontal-layout></app-horizontal-layout>
|
|
6461
|
-
}
|
|
6462
|
-
@case (LayoutType.EMPTY) {
|
|
6463
|
-
<app-empty-layout></app-empty-layout>
|
|
6464
|
-
}
|
|
6465
|
-
@case (LayoutType.CENTERED) {
|
|
6466
|
-
<app-centered-layout></app-centered-layout>
|
|
6467
|
-
}
|
|
6468
|
-
@case (LayoutType.TWO_COLUMN) {
|
|
6469
|
-
<app-two-column-layout></app-two-column-layout>
|
|
6470
|
-
}
|
|
6471
|
-
@case (LayoutType.DASHBOARD_GRID) {
|
|
6472
|
-
<app-dashboard-grid-layout></app-dashboard-grid-layout>
|
|
6473
|
-
}
|
|
6474
|
-
@case (LayoutType.COMPACT) {
|
|
6475
|
-
<app-compact-layout></app-compact-layout>
|
|
6476
|
-
}
|
|
6477
|
-
@default {
|
|
6478
|
-
<app-vertical-layout></app-vertical-layout>
|
|
6479
|
-
}
|
|
6480
|
-
}
|
|
6449
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: LayoutComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6450
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: LayoutComponent, isStandalone: true, selector: "app-layout", ngImport: i0, template: `
|
|
6451
|
+
<app-notification-container></app-notification-container>
|
|
6452
|
+
<amf-modal-host></amf-modal-host>
|
|
6453
|
+
<amf-dialog-host></amf-dialog-host>
|
|
6454
|
+
<amf-drawer-host></amf-drawer-host>
|
|
6455
|
+
@switch (config.currentLayout()) {
|
|
6456
|
+
@case (LayoutType.VERTICAL) {
|
|
6457
|
+
<app-vertical-layout></app-vertical-layout>
|
|
6458
|
+
}
|
|
6459
|
+
@case (LayoutType.HORIZONTAL) {
|
|
6460
|
+
<app-horizontal-layout></app-horizontal-layout>
|
|
6461
|
+
}
|
|
6462
|
+
@case (LayoutType.EMPTY) {
|
|
6463
|
+
<app-empty-layout></app-empty-layout>
|
|
6464
|
+
}
|
|
6465
|
+
@case (LayoutType.CENTERED) {
|
|
6466
|
+
<app-centered-layout></app-centered-layout>
|
|
6467
|
+
}
|
|
6468
|
+
@case (LayoutType.TWO_COLUMN) {
|
|
6469
|
+
<app-two-column-layout></app-two-column-layout>
|
|
6470
|
+
}
|
|
6471
|
+
@case (LayoutType.DASHBOARD_GRID) {
|
|
6472
|
+
<app-dashboard-grid-layout></app-dashboard-grid-layout>
|
|
6473
|
+
}
|
|
6474
|
+
@case (LayoutType.COMPACT) {
|
|
6475
|
+
<app-compact-layout></app-compact-layout>
|
|
6476
|
+
}
|
|
6477
|
+
@default {
|
|
6478
|
+
<app-vertical-layout></app-vertical-layout>
|
|
6479
|
+
}
|
|
6480
|
+
}
|
|
6481
6481
|
`, isInline: true, styles: [":host{display:flex;flex-direction:column;height:100%;width:100%}\n"], dependencies: [{ kind: "component", type: VerticalLayoutComponent, selector: "app-vertical-layout" }, { kind: "component", type: HorizontalLayoutComponent, selector: "app-horizontal-layout" }, { kind: "component", type: EmptyLayoutComponent, selector: "app-empty-layout" }, { kind: "component", type: CenteredLayoutComponent, selector: "app-centered-layout" }, { kind: "component", type: TwoColumnLayoutComponent, selector: "app-two-column-layout" }, { kind: "component", type: DashboardGridLayoutComponent, selector: "app-dashboard-grid-layout" }, { kind: "component", type: CompactLayoutComponent, selector: "app-compact-layout" }, { kind: "component", type: NotificationContainerComponent, selector: "app-notification-container" }, { kind: "component", type: MetaModalHostComponent, selector: "amf-modal-host" }, { kind: "component", type: AmfDialogHostComponent, selector: "amf-dialog-host" }, { kind: "component", type: AmfDrawerHostComponent, selector: "amf-drawer-host" }] });
|
|
6482
6482
|
}
|
|
6483
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
6483
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: LayoutComponent, decorators: [{
|
|
6484
6484
|
type: Component,
|
|
6485
6485
|
args: [{ selector: 'app-layout', standalone: true, imports: [
|
|
6486
6486
|
VerticalLayoutComponent,
|
|
@@ -6494,37 +6494,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
6494
6494
|
MetaModalHostComponent,
|
|
6495
6495
|
AmfDialogHostComponent,
|
|
6496
6496
|
AmfDrawerHostComponent
|
|
6497
|
-
], template: `
|
|
6498
|
-
<app-notification-container></app-notification-container>
|
|
6499
|
-
<amf-modal-host></amf-modal-host>
|
|
6500
|
-
<amf-dialog-host></amf-dialog-host>
|
|
6501
|
-
<amf-drawer-host></amf-drawer-host>
|
|
6502
|
-
@switch (config.currentLayout()) {
|
|
6503
|
-
@case (LayoutType.VERTICAL) {
|
|
6504
|
-
<app-vertical-layout></app-vertical-layout>
|
|
6505
|
-
}
|
|
6506
|
-
@case (LayoutType.HORIZONTAL) {
|
|
6507
|
-
<app-horizontal-layout></app-horizontal-layout>
|
|
6508
|
-
}
|
|
6509
|
-
@case (LayoutType.EMPTY) {
|
|
6510
|
-
<app-empty-layout></app-empty-layout>
|
|
6511
|
-
}
|
|
6512
|
-
@case (LayoutType.CENTERED) {
|
|
6513
|
-
<app-centered-layout></app-centered-layout>
|
|
6514
|
-
}
|
|
6515
|
-
@case (LayoutType.TWO_COLUMN) {
|
|
6516
|
-
<app-two-column-layout></app-two-column-layout>
|
|
6517
|
-
}
|
|
6518
|
-
@case (LayoutType.DASHBOARD_GRID) {
|
|
6519
|
-
<app-dashboard-grid-layout></app-dashboard-grid-layout>
|
|
6520
|
-
}
|
|
6521
|
-
@case (LayoutType.COMPACT) {
|
|
6522
|
-
<app-compact-layout></app-compact-layout>
|
|
6523
|
-
}
|
|
6524
|
-
@default {
|
|
6525
|
-
<app-vertical-layout></app-vertical-layout>
|
|
6526
|
-
}
|
|
6527
|
-
}
|
|
6497
|
+
], template: `
|
|
6498
|
+
<app-notification-container></app-notification-container>
|
|
6499
|
+
<amf-modal-host></amf-modal-host>
|
|
6500
|
+
<amf-dialog-host></amf-dialog-host>
|
|
6501
|
+
<amf-drawer-host></amf-drawer-host>
|
|
6502
|
+
@switch (config.currentLayout()) {
|
|
6503
|
+
@case (LayoutType.VERTICAL) {
|
|
6504
|
+
<app-vertical-layout></app-vertical-layout>
|
|
6505
|
+
}
|
|
6506
|
+
@case (LayoutType.HORIZONTAL) {
|
|
6507
|
+
<app-horizontal-layout></app-horizontal-layout>
|
|
6508
|
+
}
|
|
6509
|
+
@case (LayoutType.EMPTY) {
|
|
6510
|
+
<app-empty-layout></app-empty-layout>
|
|
6511
|
+
}
|
|
6512
|
+
@case (LayoutType.CENTERED) {
|
|
6513
|
+
<app-centered-layout></app-centered-layout>
|
|
6514
|
+
}
|
|
6515
|
+
@case (LayoutType.TWO_COLUMN) {
|
|
6516
|
+
<app-two-column-layout></app-two-column-layout>
|
|
6517
|
+
}
|
|
6518
|
+
@case (LayoutType.DASHBOARD_GRID) {
|
|
6519
|
+
<app-dashboard-grid-layout></app-dashboard-grid-layout>
|
|
6520
|
+
}
|
|
6521
|
+
@case (LayoutType.COMPACT) {
|
|
6522
|
+
<app-compact-layout></app-compact-layout>
|
|
6523
|
+
}
|
|
6524
|
+
@default {
|
|
6525
|
+
<app-vertical-layout></app-vertical-layout>
|
|
6526
|
+
}
|
|
6527
|
+
}
|
|
6528
6528
|
`, styles: [":host{display:flex;flex-direction:column;height:100%;width:100%}\n"] }]
|
|
6529
6529
|
}] });
|
|
6530
6530
|
|