@momentumcms/admin 0.5.0 → 0.5.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.
Files changed (24) hide show
  1. package/fesm2022/{momentumcms-admin-array-field.component-CLV4Ny9t.mjs → momentumcms-admin-array-field.component-DH6vaHO-.mjs} +5 -5
  2. package/fesm2022/{momentumcms-admin-array-field.component-CLV4Ny9t.mjs.map → momentumcms-admin-array-field.component-DH6vaHO-.mjs.map} +1 -1
  3. package/fesm2022/{momentumcms-admin-blocks-field.component-hHiTfUf9.mjs → momentumcms-admin-blocks-field.component-BxJRfiV3.mjs} +5 -5
  4. package/fesm2022/{momentumcms-admin-blocks-field.component-hHiTfUf9.mjs.map → momentumcms-admin-blocks-field.component-BxJRfiV3.mjs.map} +1 -1
  5. package/fesm2022/{momentumcms-admin-collapsible-field.component-BeskwGvi.mjs → momentumcms-admin-collapsible-field.component-CsjYCkGw.mjs} +5 -5
  6. package/fesm2022/{momentumcms-admin-collapsible-field.component-BeskwGvi.mjs.map → momentumcms-admin-collapsible-field.component-CsjYCkGw.mjs.map} +1 -1
  7. package/fesm2022/{momentumcms-admin-global-edit.page-D_ebIITz.mjs → momentumcms-admin-global-edit.page-CmLAM17O.mjs} +5 -5
  8. package/fesm2022/{momentumcms-admin-global-edit.page-D_ebIITz.mjs.map → momentumcms-admin-global-edit.page-CmLAM17O.mjs.map} +1 -1
  9. package/fesm2022/{momentumcms-admin-group-field.component-ffsgbC6o.mjs → momentumcms-admin-group-field.component-CMKcqfjy.mjs} +5 -5
  10. package/fesm2022/{momentumcms-admin-group-field.component-ffsgbC6o.mjs.map → momentumcms-admin-group-field.component-CMKcqfjy.mjs.map} +1 -1
  11. package/fesm2022/{momentumcms-admin-momentumcms-admin-De5FLr2L.mjs → momentumcms-admin-momentumcms-admin-BTZEdMNj.mjs} +1034 -198
  12. package/fesm2022/momentumcms-admin-momentumcms-admin-BTZEdMNj.mjs.map +1 -0
  13. package/fesm2022/{momentumcms-admin-relationship-field.component-DO0kyAkE.mjs → momentumcms-admin-relationship-field.component-DNZUCENa.mjs} +11 -6
  14. package/fesm2022/{momentumcms-admin-relationship-field.component-DO0kyAkE.mjs.map → momentumcms-admin-relationship-field.component-DNZUCENa.mjs.map} +1 -1
  15. package/fesm2022/{momentumcms-admin-rich-text-field.component-BvpufJs3.mjs → momentumcms-admin-rich-text-field.component-BVAQkX3O.mjs} +5 -5
  16. package/fesm2022/{momentumcms-admin-rich-text-field.component-BvpufJs3.mjs.map → momentumcms-admin-rich-text-field.component-BVAQkX3O.mjs.map} +1 -1
  17. package/fesm2022/{momentumcms-admin-row-field.component-C8ZsdA2w.mjs → momentumcms-admin-row-field.component-0F6cnUK_.mjs} +5 -5
  18. package/fesm2022/{momentumcms-admin-row-field.component-C8ZsdA2w.mjs.map → momentumcms-admin-row-field.component-0F6cnUK_.mjs.map} +1 -1
  19. package/fesm2022/{momentumcms-admin-tabs-field.component-Uatoyjg8.mjs → momentumcms-admin-tabs-field.component-qYlbl8Ud.mjs} +5 -5
  20. package/fesm2022/{momentumcms-admin-tabs-field.component-Uatoyjg8.mjs.map → momentumcms-admin-tabs-field.component-qYlbl8Ud.mjs.map} +1 -1
  21. package/fesm2022/momentumcms-admin.mjs +1 -1
  22. package/package.json +1 -1
  23. package/types/momentumcms-admin.d.ts +134 -64
  24. package/fesm2022/momentumcms-admin-momentumcms-admin-De5FLr2L.mjs.map +0 -1
@@ -339,10 +339,10 @@ class MomentumAuthService {
339
339
  'message' in error.error &&
340
340
  typeof error.error.message === 'string');
341
341
  }
342
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MomentumAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
343
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MomentumAuthService, providedIn: 'root' });
342
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MomentumAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
343
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MomentumAuthService, providedIn: 'root' });
344
344
  }
345
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MomentumAuthService, decorators: [{
345
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MomentumAuthService, decorators: [{
346
346
  type: Injectable,
347
347
  args: [{ providedIn: 'root' }]
348
348
  }] });
@@ -669,10 +669,10 @@ class CollectionAccessService {
669
669
  getPermissions(slug) {
670
670
  return this._permissions().find((p) => p.slug === slug);
671
671
  }
672
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionAccessService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
673
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionAccessService, providedIn: 'root' });
672
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionAccessService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
673
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionAccessService, providedIn: 'root' });
674
674
  }
675
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionAccessService, decorators: [{
675
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionAccessService, decorators: [{
676
676
  type: Injectable,
677
677
  args: [{ providedIn: 'root' }]
678
678
  }] });
@@ -937,10 +937,10 @@ class FeedbackService {
937
937
  icon: config.variant === 'destructive' ? 'danger' : 'question',
938
938
  });
939
939
  }
940
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FeedbackService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
941
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FeedbackService, providedIn: 'root' });
940
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FeedbackService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
941
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FeedbackService, providedIn: 'root' });
942
942
  }
943
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FeedbackService, decorators: [{
943
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FeedbackService, decorators: [{
944
944
  type: Injectable,
945
945
  args: [{ providedIn: 'root' }]
946
946
  }] });
@@ -1134,7 +1134,7 @@ function momentumAdminRoutes(configOrOptions) {
1134
1134
  // Global edit
1135
1135
  {
1136
1136
  path: 'globals/:slug',
1137
- loadComponent: () => import('./momentumcms-admin-global-edit.page-D_ebIITz.mjs').then((m) => m.GlobalEditPage),
1137
+ loadComponent: () => import('./momentumcms-admin-global-edit.page-CmLAM17O.mjs').then((m) => m.GlobalEditPage),
1138
1138
  canDeactivate: [unsavedChangesGuard],
1139
1139
  },
1140
1140
  // Plugin-registered routes
@@ -1412,10 +1412,10 @@ class MomentumApiService {
1412
1412
  .delete(`${this.baseUrl}/${collection}/${id}`)
1413
1413
  .pipe(map((response) => response.deleted ?? false));
1414
1414
  }
1415
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MomentumApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1416
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MomentumApiService, providedIn: 'root' });
1415
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MomentumApiService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1416
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MomentumApiService, providedIn: 'root' });
1417
1417
  }
1418
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MomentumApiService, decorators: [{
1418
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MomentumApiService, decorators: [{
1419
1419
  type: Injectable,
1420
1420
  args: [{ providedIn: 'root' }]
1421
1421
  }] });
@@ -1656,10 +1656,10 @@ class UploadService {
1656
1656
  uploads.set(file, progress);
1657
1657
  this.activeUploadsSignal.set(uploads);
1658
1658
  }
1659
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UploadService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1660
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UploadService, providedIn: 'root' });
1659
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: UploadService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1660
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: UploadService, providedIn: 'root' });
1661
1661
  }
1662
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UploadService, decorators: [{
1662
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: UploadService, decorators: [{
1663
1663
  type: Injectable,
1664
1664
  args: [{ providedIn: 'root' }]
1665
1665
  }] });
@@ -2520,10 +2520,10 @@ class EntitySheetService {
2520
2520
  return callbackParam;
2521
2521
  return null;
2522
2522
  }
2523
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EntitySheetService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2524
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EntitySheetService, providedIn: 'root' });
2523
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EntitySheetService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2524
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EntitySheetService, providedIn: 'root' });
2525
2525
  }
2526
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EntitySheetService, decorators: [{
2526
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EntitySheetService, decorators: [{
2527
2527
  type: Injectable,
2528
2528
  args: [{ providedIn: 'root' }]
2529
2529
  }] });
@@ -2712,10 +2712,10 @@ class VersionService {
2712
2712
  }
2713
2713
  return params;
2714
2714
  }
2715
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: VersionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2716
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: VersionService, providedIn: 'root' });
2715
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: VersionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2716
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: VersionService, providedIn: 'root' });
2717
2717
  }
2718
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: VersionService, decorators: [{
2718
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: VersionService, decorators: [{
2719
2719
  type: Injectable,
2720
2720
  args: [{ providedIn: 'root' }]
2721
2721
  }] });
@@ -2882,10 +2882,10 @@ class McmsThemeService {
2882
2882
  mediaQuery.removeEventListener('change', handleChange);
2883
2883
  });
2884
2884
  }
2885
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: McmsThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2886
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: McmsThemeService, providedIn: 'root' });
2885
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: McmsThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2886
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: McmsThemeService, providedIn: 'root' });
2887
2887
  }
2888
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: McmsThemeService, decorators: [{
2888
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: McmsThemeService, decorators: [{
2889
2889
  type: Injectable,
2890
2890
  args: [{ providedIn: 'root' }]
2891
2891
  }], ctorParameters: () => [] });
@@ -3552,10 +3552,10 @@ class FieldRendererRegistry {
3552
3552
  has(type) {
3553
3553
  return this.renderers.has(type);
3554
3554
  }
3555
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FieldRendererRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3556
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FieldRendererRegistry, providedIn: 'root' });
3555
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FieldRendererRegistry, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
3556
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FieldRendererRegistry, providedIn: 'root' });
3557
3557
  }
3558
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FieldRendererRegistry, decorators: [{
3558
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FieldRendererRegistry, decorators: [{
3559
3559
  type: Injectable,
3560
3560
  args: [{ providedIn: 'root' }]
3561
3561
  }] });
@@ -3585,12 +3585,18 @@ class FieldRenderer {
3585
3585
  resolvedComponent = signal(null, ...(ngDevMode ? [{ debugName: "resolvedComponent" }] : []));
3586
3586
  /** Error from lazy loading failure */
3587
3587
  loadError = signal(null, ...(ngDevMode ? [{ debugName: "loadError" }] : []));
3588
- /** Registry key: 'blocks-visual' when blocks field has visual editor, otherwise field.type */
3588
+ /** Registry key: maps field type + editor config to renderer registry keys */
3589
3589
  registryKey = computed(() => {
3590
3590
  const f = this.field();
3591
3591
  if (f.type === 'blocks' && f.admin?.editor === 'visual') {
3592
3592
  return 'blocks-visual';
3593
3593
  }
3594
+ if (f.type === 'json' && f.admin?.editor === 'email-builder') {
3595
+ return 'json-email-builder';
3596
+ }
3597
+ if (f.type === 'json' && f.admin?.editor === 'form-builder') {
3598
+ return 'json-form-builder';
3599
+ }
3594
3600
  return f.type;
3595
3601
  }, ...(ngDevMode ? [{ debugName: "registryKey" }] : []));
3596
3602
  /** Inputs to pass to the dynamically loaded component via NgComponentOutlet */
@@ -3615,8 +3621,8 @@ class FieldRenderer {
3615
3621
  }
3616
3622
  });
3617
3623
  }
3618
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
3619
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: FieldRenderer, isStandalone: true, selector: "mcms-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, formTree: { classPropertyName: "formTree", publicName: "formTree", isSignal: true, isRequired: false, transformFunction: null }, formModel: { classPropertyName: "formModel", publicName: "formModel", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "block" }, ngImport: i0, template: `
3624
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
3625
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: FieldRenderer, isStandalone: true, selector: "mcms-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, formTree: { classPropertyName: "formTree", publicName: "formTree", isSignal: true, isRequired: false, transformFunction: null }, formModel: { classPropertyName: "formModel", publicName: "formModel", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "block" }, ngImport: i0, template: `
3620
3626
  @if (resolvedComponent()) {
3621
3627
  <ng-container *ngComponentOutlet="resolvedComponent(); inputs: rendererInputs()" />
3622
3628
  } @else if (loadError()) {
@@ -3635,7 +3641,7 @@ class FieldRenderer {
3635
3641
  }
3636
3642
  `, isInline: true, dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3637
3643
  }
3638
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: FieldRenderer, decorators: [{
3644
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FieldRenderer, decorators: [{
3639
3645
  type: Component,
3640
3646
  args: [{
3641
3647
  selector: 'mcms-field-renderer',
@@ -3697,8 +3703,8 @@ class VersionDiffDialogComponent {
3697
3703
  return String(value);
3698
3704
  return JSON.stringify(value, null, 2);
3699
3705
  }
3700
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: VersionDiffDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3701
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: VersionDiffDialogComponent, isStandalone: true, selector: "mcms-version-diff-dialog", ngImport: i0, template: `
3706
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: VersionDiffDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3707
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: VersionDiffDialogComponent, isStandalone: true, selector: "mcms-version-diff-dialog", ngImport: i0, template: `
3702
3708
  <mcms-dialog>
3703
3709
  <mcms-dialog-header>
3704
3710
  <mcms-dialog-title>Compare Versions</mcms-dialog-title>
@@ -3772,7 +3778,7 @@ class VersionDiffDialogComponent {
3772
3778
  </mcms-dialog>
3773
3779
  `, isInline: true, dependencies: [{ kind: "component", type: Dialog, selector: "mcms-dialog", inputs: ["class"] }, { kind: "component", type: DialogHeader, selector: "mcms-dialog-header" }, { kind: "component", type: DialogTitle, selector: "mcms-dialog-title", inputs: ["id"] }, { kind: "component", type: DialogContent, selector: "mcms-dialog-content" }, { kind: "component", type: DialogFooter, selector: "mcms-dialog-footer" }, { kind: "directive", type: DialogClose, selector: "[mcmsDialogClose]", inputs: ["mcmsDialogClose"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Badge, selector: "mcms-badge", inputs: ["variant", "class", "role", "ariaLabel"] }, { kind: "component", type: Skeleton, selector: "mcms-skeleton", inputs: ["class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3774
3780
  }
3775
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: VersionDiffDialogComponent, decorators: [{
3781
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: VersionDiffDialogComponent, decorators: [{
3776
3782
  type: Component,
3777
3783
  args: [{
3778
3784
  selector: 'mcms-version-diff-dialog',
@@ -4012,8 +4018,8 @@ class VersionHistoryWidget {
4012
4018
  getStatusVariant(status) {
4013
4019
  return status === 'published' ? 'default' : 'secondary';
4014
4020
  }
4015
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: VersionHistoryWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
4016
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: VersionHistoryWidget, isStandalone: true, selector: "mcms-version-history", inputs: { collection: { classPropertyName: "collection", publicName: "collection", isSignal: true, isRequired: true, transformFunction: null }, documentId: { classPropertyName: "documentId", publicName: "documentId", isSignal: true, isRequired: true, transformFunction: null }, documentLabel: { classPropertyName: "documentLabel", publicName: "documentLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { restored: "restored" }, host: { classAttribute: "block" }, ngImport: i0, template: `
4021
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: VersionHistoryWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
4022
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: VersionHistoryWidget, isStandalone: true, selector: "mcms-version-history", inputs: { collection: { classPropertyName: "collection", publicName: "collection", isSignal: true, isRequired: true, transformFunction: null }, documentId: { classPropertyName: "documentId", publicName: "documentId", isSignal: true, isRequired: true, transformFunction: null }, documentLabel: { classPropertyName: "documentLabel", publicName: "documentLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { restored: "restored" }, host: { classAttribute: "block" }, ngImport: i0, template: `
4017
4023
  <mcms-card>
4018
4024
  <mcms-card-header>
4019
4025
  <div class="flex items-center justify-between">
@@ -4113,7 +4119,7 @@ class VersionHistoryWidget {
4113
4119
  </mcms-card>
4114
4120
  `, isInline: true, dependencies: [{ kind: "component", type: Badge, selector: "mcms-badge", inputs: ["variant", "class", "role", "ariaLabel"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Skeleton, selector: "mcms-skeleton", inputs: ["class"] }, { kind: "component", type: Card, selector: "mcms-card" }, { kind: "component", type: CardHeader, selector: "mcms-card-header" }, { kind: "component", type: CardContent, selector: "mcms-card-content" }, { kind: "component", type: Separator, selector: "mcms-separator", inputs: ["orientation", "decorative", "class"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4115
4121
  }
4116
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: VersionHistoryWidget, decorators: [{
4122
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: VersionHistoryWidget, decorators: [{
4117
4123
  type: Component,
4118
4124
  args: [{
4119
4125
  selector: 'mcms-version-history',
@@ -4316,8 +4322,8 @@ class MediaPreviewComponent {
4316
4322
  }
4317
4323
  return heroDocument;
4318
4324
  }, ...(ngDevMode ? [{ debugName: "iconName" }] : []));
4319
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MediaPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4320
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: MediaPreviewComponent, isStandalone: true, selector: "mcms-media-preview", inputs: { media: { classPropertyName: "media", publicName: "media", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
4325
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MediaPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4326
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: MediaPreviewComponent, isStandalone: true, selector: "mcms-media-preview", inputs: { media: { classPropertyName: "media", publicName: "media", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
4321
4327
  @if (isImage()) {
4322
4328
  <img
4323
4329
  [src]="imageUrl()"
@@ -4331,7 +4337,7 @@ class MediaPreviewComponent {
4331
4337
  }
4332
4338
  `, isInline: true, dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4333
4339
  }
4334
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MediaPreviewComponent, decorators: [{
4340
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MediaPreviewComponent, decorators: [{
4335
4341
  type: Component,
4336
4342
  args: [{
4337
4343
  selector: 'mcms-media-preview',
@@ -4369,7 +4375,6 @@ function getStringProp$1(obj, key) {
4369
4375
  return undefined;
4370
4376
  if (!(key in obj))
4371
4377
  return undefined;
4372
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
4373
4378
  const value = obj[key]; // eslint-disable-line @typescript-eslint/consistent-type-assertions
4374
4379
  return typeof value === 'string' ? value : undefined;
4375
4380
  }
@@ -4576,8 +4581,8 @@ class CollectionUploadZoneComponent {
4576
4581
  removeFile() {
4577
4582
  this.fileRemoved.emit();
4578
4583
  }
4579
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionUploadZoneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4580
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: CollectionUploadZoneComponent, isStandalone: true, selector: "mcms-collection-upload-zone", inputs: { uploadConfig: { classPropertyName: "uploadConfig", publicName: "uploadConfig", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, pendingFile: { classPropertyName: "pendingFile", publicName: "pendingFile", isSignal: true, isRequired: false, transformFunction: null }, isUploading: { classPropertyName: "isUploading", publicName: "isUploading", isSignal: true, isRequired: false, transformFunction: null }, uploadProgress: { classPropertyName: "uploadProgress", publicName: "uploadProgress", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, existingMedia: { classPropertyName: "existingMedia", publicName: "existingMedia", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileSelected: "fileSelected", fileRemoved: "fileRemoved" }, host: { classAttribute: "block mb-6" }, viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
4584
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionUploadZoneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4585
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: CollectionUploadZoneComponent, isStandalone: true, selector: "mcms-collection-upload-zone", inputs: { uploadConfig: { classPropertyName: "uploadConfig", publicName: "uploadConfig", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, pendingFile: { classPropertyName: "pendingFile", publicName: "pendingFile", isSignal: true, isRequired: false, transformFunction: null }, isUploading: { classPropertyName: "isUploading", publicName: "isUploading", isSignal: true, isRequired: false, transformFunction: null }, uploadProgress: { classPropertyName: "uploadProgress", publicName: "uploadProgress", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, existingMedia: { classPropertyName: "existingMedia", publicName: "existingMedia", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fileSelected: "fileSelected", fileRemoved: "fileRemoved" }, host: { classAttribute: "block mb-6" }, viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
4581
4586
  @if (pendingFile()) {
4582
4587
  <!-- File selected preview -->
4583
4588
  <div class="rounded-lg border border-mcms-border bg-mcms-card p-4">
@@ -4700,7 +4705,7 @@ class CollectionUploadZoneComponent {
4700
4705
  }
4701
4706
  `, isInline: true, dependencies: [{ kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Progress, selector: "mcms-progress", inputs: ["value", "max", "ariaLabel", "class"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: MediaPreviewComponent, selector: "mcms-media-preview", inputs: ["media", "size", "class", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4702
4707
  }
4703
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionUploadZoneComponent, decorators: [{
4708
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionUploadZoneComponent, decorators: [{
4704
4709
  type: Component,
4705
4710
  args: [{
4706
4711
  selector: 'mcms-collection-upload-zone',
@@ -4832,6 +4837,427 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
4832
4837
  }]
4833
4838
  }], ctorParameters: () => [], propDecorators: { fileInputRef: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }], uploadConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadConfig", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], pendingFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "pendingFile", required: false }] }], isUploading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isUploading", required: false }] }], uploadProgress: [{ type: i0.Input, args: [{ isSignal: true, alias: "uploadProgress", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], existingMedia: [{ type: i0.Input, args: [{ isSignal: true, alias: "existingMedia", required: false }] }], fileSelected: [{ type: i0.Output, args: ["fileSelected"] }], fileRemoved: [{ type: i0.Output, args: ["fileRemoved"] }] } });
4834
4839
 
4840
+ /**
4841
+ * Normalize a click position within a container to a 0-1 focal point.
4842
+ */
4843
+ function normalizeFocalPoint(click, container) {
4844
+ if (container.width <= 0 || container.height <= 0) {
4845
+ return { x: 0.5, y: 0.5 };
4846
+ }
4847
+ return clampFocalPoint({
4848
+ x: click.x / container.width,
4849
+ y: click.y / container.height,
4850
+ });
4851
+ }
4852
+ /**
4853
+ * Clamp a focal point to the valid 0-1 range on both axes.
4854
+ */
4855
+ function clampFocalPoint(point) {
4856
+ return {
4857
+ x: Math.max(0, Math.min(1, point.x)),
4858
+ y: Math.max(0, Math.min(1, point.y)),
4859
+ };
4860
+ }
4861
+ /**
4862
+ * Convert a normalized focal point to a CSS `object-position` string.
4863
+ *
4864
+ * @example focalPointToCssPosition({ x: 0.25, y: 0.75 }) → '25% 75%'
4865
+ */
4866
+ function focalPointToCssPosition(point) {
4867
+ const fp = point ?? { x: 0.5, y: 0.5 };
4868
+ return `${Math.round(fp.x * 100)}% ${Math.round(fp.y * 100)}%`;
4869
+ }
4870
+
4871
+ /**
4872
+ * Calculate the crop region for a cover-fit preview.
4873
+ * Same math as the server-side crop-calculator, but for browser-side preview.
4874
+ */
4875
+ function calculatePreviewCrop(source, target, focalPoint) {
4876
+ const fp = focalPoint ?? { x: 0.5, y: 0.5 };
4877
+ const scale = Math.max(target.width / source.width, target.height / source.height);
4878
+ const cropW = Math.round(target.width / scale);
4879
+ const cropH = Math.round(target.height / scale);
4880
+ const focalX = fp.x * source.width;
4881
+ const focalY = fp.y * source.height;
4882
+ let x = Math.round(focalX - cropW / 2);
4883
+ let y = Math.round(focalY - cropH / 2);
4884
+ x = Math.max(0, Math.min(x, source.width - cropW));
4885
+ y = Math.max(0, Math.min(y, source.height - cropH));
4886
+ return { x, y, width: cropW, height: cropH };
4887
+ }
4888
+
4889
+ /**
4890
+ * Focal Point Picker Component
4891
+ *
4892
+ * Displays an image with an interactive crosshair overlay.
4893
+ * Click anywhere on the image to set the focal point.
4894
+ * Optionally shows crop preview outlines for configured image sizes.
4895
+ *
4896
+ * @example
4897
+ * ```html
4898
+ * <mcms-focal-point-picker
4899
+ * [imageUrl]="mediaUrl"
4900
+ * [focalPoint]="{ x: 0.5, y: 0.5 }"
4901
+ * [imageSizes]="configuredSizes"
4902
+ * [naturalWidth]="800"
4903
+ * [naturalHeight]="600"
4904
+ * (focalPointChange)="onFocalPointChange($event)"
4905
+ * />
4906
+ * ```
4907
+ */
4908
+ class FocalPointPickerComponent {
4909
+ imageElRef = viewChild('imageEl', ...(ngDevMode ? [{ debugName: "imageElRef" }] : []));
4910
+ /** URL of the image to display */
4911
+ imageUrl = input.required(...(ngDevMode ? [{ debugName: "imageUrl" }] : []));
4912
+ /** Current focal point (0-1 normalized) */
4913
+ focalPoint = input({ x: 0.5, y: 0.5 }, ...(ngDevMode ? [{ debugName: "focalPoint" }] : []));
4914
+ /** Alt text for the image */
4915
+ alt = input('', ...(ngDevMode ? [{ debugName: "alt" }] : []));
4916
+ /** Natural width of the source image (for crop preview calculations) */
4917
+ naturalWidth = input(0, ...(ngDevMode ? [{ debugName: "naturalWidth" }] : []));
4918
+ /** Natural height of the source image (for crop preview calculations) */
4919
+ naturalHeight = input(0, ...(ngDevMode ? [{ debugName: "naturalHeight" }] : []));
4920
+ /** Configured image sizes for crop preview outlines */
4921
+ imageSizes = input([], ...(ngDevMode ? [{ debugName: "imageSizes" }] : []));
4922
+ /** Emitted when the focal point changes */
4923
+ focalPointChange = output();
4924
+ /** Focal point X as percentage */
4925
+ focalPointX = computed(() => Math.round(this.focalPoint().x * 100), ...(ngDevMode ? [{ debugName: "focalPointX" }] : []));
4926
+ /** Focal point Y as percentage */
4927
+ focalPointY = computed(() => Math.round(this.focalPoint().y * 100), ...(ngDevMode ? [{ debugName: "focalPointY" }] : []));
4928
+ /** CSS object-position string */
4929
+ cssPosition = computed(() => focalPointToCssPosition(this.focalPoint()), ...(ngDevMode ? [{ debugName: "cssPosition" }] : []));
4930
+ /** Human-readable position label */
4931
+ positionLabel = computed(() => {
4932
+ const fp = this.focalPoint();
4933
+ return `${Math.round(fp.x * 100)}% x ${Math.round(fp.y * 100)}%`;
4934
+ }, ...(ngDevMode ? [{ debugName: "positionLabel" }] : []));
4935
+ /** Crop preview data for each configured size */
4936
+ cropPreviews = computed(() => {
4937
+ const w = this.naturalWidth();
4938
+ const h = this.naturalHeight();
4939
+ const fp = this.focalPoint();
4940
+ const sizes = this.imageSizes();
4941
+ if (!w || !h || sizes.length === 0)
4942
+ return [];
4943
+ return sizes
4944
+ .filter((s) => s.width && s.height && s.fit === 'cover')
4945
+ .map((s) => {
4946
+ const crop = calculatePreviewCrop({ width: w, height: h }, { width: s.width ?? 0, height: s.height ?? 0 }, fp);
4947
+ return {
4948
+ name: s.name,
4949
+ leftPct: (crop.x / w) * 100,
4950
+ topPct: (crop.y / h) * 100,
4951
+ widthPct: (crop.width / w) * 100,
4952
+ heightPct: (crop.height / h) * 100,
4953
+ };
4954
+ });
4955
+ }, ...(ngDevMode ? [{ debugName: "cropPreviews" }] : []));
4956
+ /**
4957
+ * Handle click on the image overlay.
4958
+ */
4959
+ onClick(event) {
4960
+ const el = this.imageElRef();
4961
+ if (!el)
4962
+ return;
4963
+ const rect = el.nativeElement.getBoundingClientRect();
4964
+ if (rect.width <= 0 || rect.height <= 0)
4965
+ return;
4966
+ const x = event.clientX - rect.left;
4967
+ const y = event.clientY - rect.top;
4968
+ const fp = normalizeFocalPoint({ x, y }, { width: rect.width, height: rect.height });
4969
+ this.focalPointChange.emit(fp);
4970
+ }
4971
+ /**
4972
+ * Reset focal point to center.
4973
+ */
4974
+ onResetCenter() {
4975
+ this.focalPointChange.emit({ x: 0.5, y: 0.5 });
4976
+ }
4977
+ /**
4978
+ * Nudge focal point by a small amount (keyboard navigation).
4979
+ */
4980
+ onNudge(dx, dy, event) {
4981
+ event.preventDefault();
4982
+ const fp = this.focalPoint();
4983
+ const newFp = {
4984
+ x: Math.max(0, Math.min(1, fp.x + dx)),
4985
+ y: Math.max(0, Math.min(1, fp.y + dy)),
4986
+ };
4987
+ this.focalPointChange.emit(newFp);
4988
+ }
4989
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FocalPointPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4990
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: FocalPointPickerComponent, isStandalone: true, selector: "mcms-focal-point-picker", inputs: { imageUrl: { classPropertyName: "imageUrl", publicName: "imageUrl", isSignal: true, isRequired: true, transformFunction: null }, focalPoint: { classPropertyName: "focalPoint", publicName: "focalPoint", isSignal: true, isRequired: false, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, naturalWidth: { classPropertyName: "naturalWidth", publicName: "naturalWidth", isSignal: true, isRequired: false, transformFunction: null }, naturalHeight: { classPropertyName: "naturalHeight", publicName: "naturalHeight", isSignal: true, isRequired: false, transformFunction: null }, imageSizes: { classPropertyName: "imageSizes", publicName: "imageSizes", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { focalPointChange: "focalPointChange" }, host: { classAttribute: "block" }, viewQueries: [{ propertyName: "imageElRef", first: true, predicate: ["imageEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
4991
+ <div class="space-y-3">
4992
+ <div class="relative inline-block overflow-hidden rounded-lg border border-mcms-border">
4993
+ <!-- Image -->
4994
+ <img
4995
+ #imageEl
4996
+ [src]="imageUrl()"
4997
+ [alt]="alt() || 'Image with focal point selector'"
4998
+ class="block max-h-96 max-w-full"
4999
+ [style.object-position]="cssPosition()"
5000
+ />
5001
+
5002
+ <!-- Clickable overlay -->
5003
+ <div
5004
+ class="absolute inset-0 cursor-crosshair"
5005
+ role="button"
5006
+ tabindex="0"
5007
+ [attr.aria-label]="'Set focal point. Current position: ' + positionLabel()"
5008
+ (click)="onClick($event)"
5009
+ (keydown.enter)="onResetCenter()"
5010
+ (keydown.space)="onResetCenter()"
5011
+ (keydown.ArrowLeft)="onNudge(-0.05, 0, $event)"
5012
+ (keydown.ArrowRight)="onNudge(0.05, 0, $event)"
5013
+ (keydown.ArrowUp)="onNudge(0, -0.05, $event)"
5014
+ (keydown.ArrowDown)="onNudge(0, 0.05, $event)"
5015
+ >
5016
+ <!-- Crosshair lines -->
5017
+ <div
5018
+ class="pointer-events-none absolute h-px w-full bg-white/70"
5019
+ [style.top.%]="focalPointY()"
5020
+ ></div>
5021
+ <div
5022
+ class="pointer-events-none absolute w-px h-full bg-white/70"
5023
+ [style.left.%]="focalPointX()"
5024
+ ></div>
5025
+
5026
+ <!-- Focal point dot -->
5027
+ <div
5028
+ class="pointer-events-none absolute h-4 w-4 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white bg-mcms-primary shadow-md"
5029
+ [style.left.%]="focalPointX()"
5030
+ [style.top.%]="focalPointY()"
5031
+ aria-hidden="true"
5032
+ ></div>
5033
+
5034
+ <!-- Crop preview outlines -->
5035
+ @for (preview of cropPreviews(); track preview.name) {
5036
+ <div
5037
+ class="pointer-events-none absolute border border-dashed border-yellow-400/60"
5038
+ [style.left.%]="preview.leftPct"
5039
+ [style.top.%]="preview.topPct"
5040
+ [style.width.%]="preview.widthPct"
5041
+ [style.height.%]="preview.heightPct"
5042
+ [attr.aria-label]="'Crop preview for ' + preview.name"
5043
+ >
5044
+ <span class="absolute -top-5 left-0 text-xs text-yellow-400 drop-shadow-sm">
5045
+ {{ preview.name }}
5046
+ </span>
5047
+ </div>
5048
+ }
5049
+ </div>
5050
+ </div>
5051
+
5052
+ <!-- Coordinates display -->
5053
+ <p class="text-xs text-mcms-muted-foreground" aria-live="polite">
5054
+ Focal point: {{ positionLabel() }}
5055
+ <button
5056
+ class="ml-2 underline hover:text-mcms-foreground"
5057
+ type="button"
5058
+ (click)="onResetCenter()"
5059
+ aria-label="Reset focal point to center"
5060
+ >
5061
+ Reset to center
5062
+ </button>
5063
+ </p>
5064
+ </div>
5065
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
5066
+ }
5067
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: FocalPointPickerComponent, decorators: [{
5068
+ type: Component,
5069
+ args: [{
5070
+ selector: 'mcms-focal-point-picker',
5071
+ changeDetection: ChangeDetectionStrategy.OnPush,
5072
+ host: { class: 'block' },
5073
+ template: `
5074
+ <div class="space-y-3">
5075
+ <div class="relative inline-block overflow-hidden rounded-lg border border-mcms-border">
5076
+ <!-- Image -->
5077
+ <img
5078
+ #imageEl
5079
+ [src]="imageUrl()"
5080
+ [alt]="alt() || 'Image with focal point selector'"
5081
+ class="block max-h-96 max-w-full"
5082
+ [style.object-position]="cssPosition()"
5083
+ />
5084
+
5085
+ <!-- Clickable overlay -->
5086
+ <div
5087
+ class="absolute inset-0 cursor-crosshair"
5088
+ role="button"
5089
+ tabindex="0"
5090
+ [attr.aria-label]="'Set focal point. Current position: ' + positionLabel()"
5091
+ (click)="onClick($event)"
5092
+ (keydown.enter)="onResetCenter()"
5093
+ (keydown.space)="onResetCenter()"
5094
+ (keydown.ArrowLeft)="onNudge(-0.05, 0, $event)"
5095
+ (keydown.ArrowRight)="onNudge(0.05, 0, $event)"
5096
+ (keydown.ArrowUp)="onNudge(0, -0.05, $event)"
5097
+ (keydown.ArrowDown)="onNudge(0, 0.05, $event)"
5098
+ >
5099
+ <!-- Crosshair lines -->
5100
+ <div
5101
+ class="pointer-events-none absolute h-px w-full bg-white/70"
5102
+ [style.top.%]="focalPointY()"
5103
+ ></div>
5104
+ <div
5105
+ class="pointer-events-none absolute w-px h-full bg-white/70"
5106
+ [style.left.%]="focalPointX()"
5107
+ ></div>
5108
+
5109
+ <!-- Focal point dot -->
5110
+ <div
5111
+ class="pointer-events-none absolute h-4 w-4 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white bg-mcms-primary shadow-md"
5112
+ [style.left.%]="focalPointX()"
5113
+ [style.top.%]="focalPointY()"
5114
+ aria-hidden="true"
5115
+ ></div>
5116
+
5117
+ <!-- Crop preview outlines -->
5118
+ @for (preview of cropPreviews(); track preview.name) {
5119
+ <div
5120
+ class="pointer-events-none absolute border border-dashed border-yellow-400/60"
5121
+ [style.left.%]="preview.leftPct"
5122
+ [style.top.%]="preview.topPct"
5123
+ [style.width.%]="preview.widthPct"
5124
+ [style.height.%]="preview.heightPct"
5125
+ [attr.aria-label]="'Crop preview for ' + preview.name"
5126
+ >
5127
+ <span class="absolute -top-5 left-0 text-xs text-yellow-400 drop-shadow-sm">
5128
+ {{ preview.name }}
5129
+ </span>
5130
+ </div>
5131
+ }
5132
+ </div>
5133
+ </div>
5134
+
5135
+ <!-- Coordinates display -->
5136
+ <p class="text-xs text-mcms-muted-foreground" aria-live="polite">
5137
+ Focal point: {{ positionLabel() }}
5138
+ <button
5139
+ class="ml-2 underline hover:text-mcms-foreground"
5140
+ type="button"
5141
+ (click)="onResetCenter()"
5142
+ aria-label="Reset focal point to center"
5143
+ >
5144
+ Reset to center
5145
+ </button>
5146
+ </p>
5147
+ </div>
5148
+ `,
5149
+ }]
5150
+ }], propDecorators: { imageElRef: [{ type: i0.ViewChild, args: ['imageEl', { isSignal: true }] }], imageUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageUrl", required: true }] }], focalPoint: [{ type: i0.Input, args: [{ isSignal: true, alias: "focalPoint", required: false }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }], naturalWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "naturalWidth", required: false }] }], naturalHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "naturalHeight", required: false }] }], imageSizes: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageSizes", required: false }] }], focalPointChange: [{ type: i0.Output, args: ["focalPointChange"] }] } });
5151
+
5152
+ /**
5153
+ * Displays generated image size variants as a grid of thumbnail cards.
5154
+ *
5155
+ * @example
5156
+ * ```html
5157
+ * <mcms-image-variants-display [sizes]="entity.sizes" />
5158
+ * ```
5159
+ */
5160
+ class ImageVariantsDisplay {
5161
+ /** The sizes record from the media document (e.g., entity['sizes']) */
5162
+ sizes = input(null, ...(ngDevMode ? [{ debugName: "sizes" }] : []));
5163
+ /** Parsed variant entries */
5164
+ variants = computed(() => {
5165
+ const sizes = this.sizes();
5166
+ if (!sizes || typeof sizes !== 'object')
5167
+ return [];
5168
+ return Object.entries(sizes)
5169
+ .filter((entry) => {
5170
+ const v = entry[1];
5171
+ return v != null && typeof v === 'object' && 'width' in v && 'path' in v;
5172
+ })
5173
+ .map(([name, data]) => ({
5174
+ name,
5175
+ ...data,
5176
+ }));
5177
+ }, ...(ngDevMode ? [{ debugName: "variants" }] : []));
5178
+ /** Build URL for a variant image */
5179
+ variantUrl(variant) {
5180
+ if (variant.url)
5181
+ return variant.url;
5182
+ if (variant.path)
5183
+ return `/api/media/file/${variant.path}`;
5184
+ return '';
5185
+ }
5186
+ /** Format file size for display */
5187
+ formatFileSize(bytes) {
5188
+ if (!bytes)
5189
+ return '';
5190
+ if (bytes >= 1024 * 1024)
5191
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
5192
+ if (bytes >= 1024)
5193
+ return `${(bytes / 1024).toFixed(1)} KB`;
5194
+ return `${bytes} bytes`;
5195
+ }
5196
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ImageVariantsDisplay, deps: [], target: i0.ɵɵFactoryTarget.Component });
5197
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: ImageVariantsDisplay, isStandalone: true, selector: "mcms-image-variants-display", inputs: { sizes: { classPropertyName: "sizes", publicName: "sizes", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "block" }, ngImport: i0, template: `
5198
+ @if (variants().length > 0) {
5199
+ <div class="space-y-3">
5200
+ <p class="text-sm font-medium">Generated Sizes</p>
5201
+ <div class="grid gap-3 grid-cols-2 sm:grid-cols-3">
5202
+ @for (variant of variants(); track variant.name) {
5203
+ <div class="rounded-lg border border-mcms-border bg-mcms-card overflow-hidden">
5204
+ <img
5205
+ [src]="variantUrl(variant)"
5206
+ [alt]="variant.name + ' variant'"
5207
+ class="h-24 w-full object-cover bg-mcms-muted"
5208
+ />
5209
+ <div class="p-2">
5210
+ <p class="text-xs font-medium">{{ variant.name }}</p>
5211
+ <p class="text-xs text-mcms-muted-foreground">
5212
+ {{ variant.width }} &times; {{ variant.height }}
5213
+ </p>
5214
+ <p class="text-xs text-mcms-muted-foreground">
5215
+ {{ formatFileSize(variant.filesize) }}
5216
+ </p>
5217
+ </div>
5218
+ </div>
5219
+ }
5220
+ </div>
5221
+ </div>
5222
+ }
5223
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
5224
+ }
5225
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ImageVariantsDisplay, decorators: [{
5226
+ type: Component,
5227
+ args: [{
5228
+ selector: 'mcms-image-variants-display',
5229
+ changeDetection: ChangeDetectionStrategy.OnPush,
5230
+ host: { class: 'block' },
5231
+ template: `
5232
+ @if (variants().length > 0) {
5233
+ <div class="space-y-3">
5234
+ <p class="text-sm font-medium">Generated Sizes</p>
5235
+ <div class="grid gap-3 grid-cols-2 sm:grid-cols-3">
5236
+ @for (variant of variants(); track variant.name) {
5237
+ <div class="rounded-lg border border-mcms-border bg-mcms-card overflow-hidden">
5238
+ <img
5239
+ [src]="variantUrl(variant)"
5240
+ [alt]="variant.name + ' variant'"
5241
+ class="h-24 w-full object-cover bg-mcms-muted"
5242
+ />
5243
+ <div class="p-2">
5244
+ <p class="text-xs font-medium">{{ variant.name }}</p>
5245
+ <p class="text-xs text-mcms-muted-foreground">
5246
+ {{ variant.width }} &times; {{ variant.height }}
5247
+ </p>
5248
+ <p class="text-xs text-mcms-muted-foreground">
5249
+ {{ formatFileSize(variant.filesize) }}
5250
+ </p>
5251
+ </div>
5252
+ </div>
5253
+ }
5254
+ </div>
5255
+ </div>
5256
+ }
5257
+ `,
5258
+ }]
5259
+ }], propDecorators: { sizes: [{ type: i0.Input, args: [{ isSignal: true, alias: "sizes", required: false }] }] } });
5260
+
4835
5261
  /**
4836
5262
  * Entity Form Widget
4837
5263
  *
@@ -4897,8 +5323,87 @@ class EntityFormWidget {
4897
5323
  isUploadingFile = signal(false, ...(ngDevMode ? [{ debugName: "isUploadingFile" }] : []));
4898
5324
  uploadFileProgress = signal(0, ...(ngDevMode ? [{ debugName: "uploadFileProgress" }] : []));
4899
5325
  uploadFileError = signal(null, ...(ngDevMode ? [{ debugName: "uploadFileError" }] : []));
5326
+ /** Preview URL for the pending image file (focal point picker) */
5327
+ pendingFileUrl = signal(null, ...(ngDevMode ? [{ debugName: "pendingFileUrl" }] : []));
5328
+ /** Detected dimensions of the pending image */
5329
+ pendingImageDimensions = signal({
5330
+ width: 0,
5331
+ height: 0,
5332
+ }, ...(ngDevMode ? [{ debugName: "pendingImageDimensions" }] : []));
4900
5333
  /** Whether the collection is an upload collection */
4901
5334
  isUploadCol = computed(() => isUploadCollection(this.collection()), ...(ngDevMode ? [{ debugName: "isUploadCol" }] : []));
5335
+ /** Whether the current file (pending or existing) is an image */
5336
+ isImageFile = computed(() => {
5337
+ const file = this.pendingFile();
5338
+ if (file)
5339
+ return file.type.startsWith('image/');
5340
+ if (this.isUploadCol() && this.mode() !== 'create') {
5341
+ const mimeType = this.formModel()['mimeType'];
5342
+ return typeof mimeType === 'string' && mimeType.startsWith('image/');
5343
+ }
5344
+ return false;
5345
+ }, ...(ngDevMode ? [{ debugName: "isImageFile" }] : []));
5346
+ /** Image sizes from collection upload config */
5347
+ uploadImageSizes = computed(() => {
5348
+ return this.collection().upload?.imageSizes ?? [];
5349
+ }, ...(ngDevMode ? [{ debugName: "uploadImageSizes" }] : []));
5350
+ /** Image URL for the focal point picker */
5351
+ focalPointImageUrl = computed(() => {
5352
+ const fileUrl = this.pendingFileUrl();
5353
+ if (fileUrl)
5354
+ return fileUrl;
5355
+ const model = this.formModel();
5356
+ if (typeof model['url'] === 'string' && model['url'])
5357
+ return model['url'];
5358
+ if (typeof model['path'] === 'string' && model['path'])
5359
+ return `/api/media/file/${model['path']}`;
5360
+ return '';
5361
+ }, ...(ngDevMode ? [{ debugName: "focalPointImageUrl" }] : []));
5362
+ /** Current focal point value */
5363
+ currentFocalPoint = computed(() => {
5364
+ const fp = this.formModel()['focalPoint'];
5365
+ if (fp != null && typeof fp === 'object' && !Array.isArray(fp)) {
5366
+ const obj = fp; // eslint-disable-line @typescript-eslint/consistent-type-assertions
5367
+ const x = obj['x'];
5368
+ const y = obj['y'];
5369
+ if (typeof x === 'number' && typeof y === 'number') {
5370
+ return { x, y };
5371
+ }
5372
+ }
5373
+ return { x: 0.5, y: 0.5 };
5374
+ }, ...(ngDevMode ? [{ debugName: "currentFocalPoint" }] : []));
5375
+ /** Natural image dimensions (pending file detection or existing media) */
5376
+ imageNaturalDimensions = computed(() => {
5377
+ if (this.pendingFile())
5378
+ return this.pendingImageDimensions();
5379
+ const model = this.formModel();
5380
+ return {
5381
+ width: typeof model['width'] === 'number' ? model['width'] : 0,
5382
+ height: typeof model['height'] === 'number' ? model['height'] : 0,
5383
+ };
5384
+ }, ...(ngDevMode ? [{ debugName: "imageNaturalDimensions" }] : []));
5385
+ /** Alt text for the focal point picker */
5386
+ focalPointAlt = computed(() => {
5387
+ const model = this.formModel();
5388
+ const alt = model['alt'];
5389
+ if (typeof alt === 'string' && alt)
5390
+ return alt;
5391
+ const fn = model['filename'];
5392
+ if (typeof fn === 'string')
5393
+ return fn;
5394
+ return '';
5395
+ }, ...(ngDevMode ? [{ debugName: "focalPointAlt" }] : []));
5396
+ /** Generated image sizes from the form model */
5397
+ formModelSizes = computed(() => {
5398
+ const sizes = this.formModel()['sizes'];
5399
+ if (sizes != null &&
5400
+ typeof sizes === 'object' &&
5401
+ !Array.isArray(sizes) &&
5402
+ Object.keys(sizes).length > 0) {
5403
+ return sizes; // eslint-disable-line @typescript-eslint/consistent-type-assertions
5404
+ }
5405
+ return null;
5406
+ }, ...(ngDevMode ? [{ debugName: "formModelSizes" }] : []));
4902
5407
  /** Whether the form has been set up */
4903
5408
  formCreated = false;
4904
5409
  /** Whether the form has unsaved changes (from signal forms dirty tracking) */
@@ -4997,16 +5502,46 @@ class EntityFormWidget {
4997
5502
  this.loadGlobal(gSlug);
4998
5503
  }
4999
5504
  else if (currentMode === 'create' || !id) {
5000
- this.formModel.set(createInitialFormData(col));
5001
- const ef = this.entityForm();
5002
- if (ef)
5003
- ef().reset();
5505
+ // Guard: don't reset formModel if the user has already selected a file.
5506
+ // On Analog (SSR), reactive route signals may re-emit after hydration,
5507
+ // causing this effect to re-run and wipe user input.
5508
+ const hasPendingFile = untracked(() => this.pendingFile());
5509
+ if (!hasPendingFile) {
5510
+ this.formModel.set(createInitialFormData(col));
5511
+ const ef = this.entityForm();
5512
+ if (ef)
5513
+ ef().reset();
5514
+ }
5004
5515
  }
5005
5516
  else {
5006
5517
  this.loadEntity(col.slug, id);
5007
5518
  }
5008
5519
  }
5009
5520
  });
5521
+ // Manage preview URL for focal point picker and detect image dimensions
5522
+ effect((onCleanup) => {
5523
+ const file = this.pendingFile();
5524
+ if (file && file.type.startsWith('image/')) {
5525
+ const url = URL.createObjectURL(file);
5526
+ this.pendingFileUrl.set(url);
5527
+ let cancelled = false;
5528
+ onCleanup(() => {
5529
+ cancelled = true;
5530
+ URL.revokeObjectURL(url);
5531
+ });
5532
+ const img = new Image();
5533
+ img.onload = () => {
5534
+ if (!cancelled) {
5535
+ this.pendingImageDimensions.set({ width: img.naturalWidth, height: img.naturalHeight });
5536
+ }
5537
+ };
5538
+ img.src = url;
5539
+ }
5540
+ else {
5541
+ this.pendingFileUrl.set(null);
5542
+ this.pendingImageDimensions.set({ width: 0, height: 0 });
5543
+ }
5544
+ });
5010
5545
  }
5011
5546
  /**
5012
5547
  * Get a FieldTree node for a top-level field by name.
@@ -5115,6 +5650,14 @@ class EntityFormWidget {
5115
5650
  data['filesize'] = file.size;
5116
5651
  this.formModel.set(data);
5117
5652
  }
5653
+ /**
5654
+ * Handle focal point change from the picker.
5655
+ */
5656
+ onFocalPointChange(fp) {
5657
+ const data = { ...this.formModel() };
5658
+ data['focalPoint'] = fp;
5659
+ this.formModel.set(data);
5660
+ }
5118
5661
  /**
5119
5662
  * Handle file removed from the upload zone.
5120
5663
  */
@@ -5327,8 +5870,8 @@ class EntityFormWidget {
5327
5870
  this.isSavingDraft.set(false);
5328
5871
  }
5329
5872
  }
5330
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EntityFormWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
5331
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: EntityFormWidget, isStandalone: true, selector: "mcms-entity-form", inputs: { collection: { classPropertyName: "collection", publicName: "collection", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: false, transformFunction: null }, showBreadcrumbs: { classPropertyName: "showBreadcrumbs", publicName: "showBreadcrumbs", isSignal: true, isRequired: false, transformFunction: null }, suppressNavigation: { classPropertyName: "suppressNavigation", publicName: "suppressNavigation", isSignal: true, isRequired: false, transformFunction: null }, isGlobal: { classPropertyName: "isGlobal", publicName: "isGlobal", isSignal: true, isRequired: false, transformFunction: null }, globalSlug: { classPropertyName: "globalSlug", publicName: "globalSlug", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved", cancelled: "cancelled", saveError: "saveError", modeChange: "modeChange", draftSaved: "draftSaved" }, host: { classAttribute: "block" }, ngImport: i0, template: `
5873
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EntityFormWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
5874
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: EntityFormWidget, isStandalone: true, selector: "mcms-entity-form", inputs: { collection: { classPropertyName: "collection", publicName: "collection", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: false, transformFunction: null }, showBreadcrumbs: { classPropertyName: "showBreadcrumbs", publicName: "showBreadcrumbs", isSignal: true, isRequired: false, transformFunction: null }, suppressNavigation: { classPropertyName: "suppressNavigation", publicName: "suppressNavigation", isSignal: true, isRequired: false, transformFunction: null }, isGlobal: { classPropertyName: "isGlobal", publicName: "isGlobal", isSignal: true, isRequired: false, transformFunction: null }, globalSlug: { classPropertyName: "globalSlug", publicName: "globalSlug", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { saved: "saved", cancelled: "cancelled", saveError: "saveError", modeChange: "modeChange", draftSaved: "draftSaved" }, host: { classAttribute: "block" }, ngImport: i0, template: `
5332
5875
  <div class="max-w-3xl">
5333
5876
  @if (showBreadcrumbs()) {
5334
5877
  <mcms-breadcrumbs class="mb-6">
@@ -5390,7 +5933,7 @@ class EntityFormWidget {
5390
5933
  <mcms-collection-upload-zone
5391
5934
  [uploadConfig]="collection().upload"
5392
5935
  [pendingFile]="pendingFile()"
5393
- [existingMedia]="mode() === 'edit' && !pendingFile() ? formModel() : null"
5936
+ [existingMedia]="mode() !== 'create' && !pendingFile() ? formModel() : null"
5394
5937
  [disabled]="mode() === 'view'"
5395
5938
  [isUploading]="isUploadingFile()"
5396
5939
  [uploadProgress]="uploadFileProgress()"
@@ -5400,6 +5943,27 @@ class EntityFormWidget {
5400
5943
  />
5401
5944
  }
5402
5945
 
5946
+ @if (isUploadCol() && isImageFile() && focalPointImageUrl()) {
5947
+ <div class="mb-6" [class.pointer-events-none]="mode() === 'view'">
5948
+ <p class="mb-2 text-sm font-medium">Focal Point</p>
5949
+ <mcms-focal-point-picker
5950
+ [imageUrl]="focalPointImageUrl()"
5951
+ [focalPoint]="currentFocalPoint()"
5952
+ [naturalWidth]="imageNaturalDimensions().width"
5953
+ [naturalHeight]="imageNaturalDimensions().height"
5954
+ [alt]="focalPointAlt()"
5955
+ [imageSizes]="uploadImageSizes()"
5956
+ (focalPointChange)="onFocalPointChange($event)"
5957
+ />
5958
+ </div>
5959
+ }
5960
+
5961
+ @if (isUploadCol() && formModelSizes()) {
5962
+ <div class="mb-6">
5963
+ <mcms-image-variants-display [sizes]="formModelSizes()" />
5964
+ </div>
5965
+ }
5966
+
5403
5967
  <div class="space-y-6">
5404
5968
  @for (field of visibleFields(); track field.name) {
5405
5969
  <mcms-field-renderer
@@ -5468,9 +6032,9 @@ class EntityFormWidget {
5468
6032
  </div>
5469
6033
  }
5470
6034
  </div>
5471
- `, isInline: true, dependencies: [{ kind: "component", type: Card, selector: "mcms-card" }, { kind: "component", type: CardContent, selector: "mcms-card-content" }, { kind: "component", type: CardFooter, selector: "mcms-card-footer" }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Spinner, selector: "mcms-spinner", inputs: ["size", "label", "class"] }, { kind: "component", type: Alert, selector: "mcms-alert", inputs: ["variant", "class"] }, { kind: "component", type: FieldRenderer, selector: "mcms-field-renderer", inputs: ["field", "formNode", "formTree", "formModel", "mode", "path"] }, { kind: "component", type: Breadcrumbs, selector: "mcms-breadcrumbs", inputs: ["class"] }, { kind: "component", type: BreadcrumbItem, selector: "mcms-breadcrumb-item", inputs: ["href", "current", "class"] }, { kind: "component", type: BreadcrumbSeparator, selector: "mcms-breadcrumb-separator", inputs: ["class"] }, { kind: "component", type: VersionHistoryWidget, selector: "mcms-version-history", inputs: ["collection", "documentId", "documentLabel"], outputs: ["restored"] }, { kind: "component", type: CollectionUploadZoneComponent, selector: "mcms-collection-upload-zone", inputs: ["uploadConfig", "disabled", "pendingFile", "isUploading", "uploadProgress", "error", "existingMedia"], outputs: ["fileSelected", "fileRemoved"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6035
+ `, isInline: true, dependencies: [{ kind: "component", type: Card, selector: "mcms-card" }, { kind: "component", type: CardContent, selector: "mcms-card-content" }, { kind: "component", type: CardFooter, selector: "mcms-card-footer" }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Spinner, selector: "mcms-spinner", inputs: ["size", "label", "class"] }, { kind: "component", type: Alert, selector: "mcms-alert", inputs: ["variant", "class"] }, { kind: "component", type: FieldRenderer, selector: "mcms-field-renderer", inputs: ["field", "formNode", "formTree", "formModel", "mode", "path"] }, { kind: "component", type: Breadcrumbs, selector: "mcms-breadcrumbs", inputs: ["class"] }, { kind: "component", type: BreadcrumbItem, selector: "mcms-breadcrumb-item", inputs: ["href", "current", "class"] }, { kind: "component", type: BreadcrumbSeparator, selector: "mcms-breadcrumb-separator", inputs: ["class"] }, { kind: "component", type: VersionHistoryWidget, selector: "mcms-version-history", inputs: ["collection", "documentId", "documentLabel"], outputs: ["restored"] }, { kind: "component", type: CollectionUploadZoneComponent, selector: "mcms-collection-upload-zone", inputs: ["uploadConfig", "disabled", "pendingFile", "isUploading", "uploadProgress", "error", "existingMedia"], outputs: ["fileSelected", "fileRemoved"] }, { kind: "component", type: FocalPointPickerComponent, selector: "mcms-focal-point-picker", inputs: ["imageUrl", "focalPoint", "alt", "naturalWidth", "naturalHeight", "imageSizes"], outputs: ["focalPointChange"] }, { kind: "component", type: ImageVariantsDisplay, selector: "mcms-image-variants-display", inputs: ["sizes"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5472
6036
  }
5473
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EntityFormWidget, decorators: [{
6037
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EntityFormWidget, decorators: [{
5474
6038
  type: Component,
5475
6039
  args: [{
5476
6040
  selector: 'mcms-entity-form',
@@ -5487,6 +6051,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
5487
6051
  BreadcrumbSeparator,
5488
6052
  VersionHistoryWidget,
5489
6053
  CollectionUploadZoneComponent,
6054
+ FocalPointPickerComponent,
6055
+ ImageVariantsDisplay,
5490
6056
  ],
5491
6057
  changeDetection: ChangeDetectionStrategy.OnPush,
5492
6058
  host: { class: 'block' },
@@ -5552,7 +6118,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
5552
6118
  <mcms-collection-upload-zone
5553
6119
  [uploadConfig]="collection().upload"
5554
6120
  [pendingFile]="pendingFile()"
5555
- [existingMedia]="mode() === 'edit' && !pendingFile() ? formModel() : null"
6121
+ [existingMedia]="mode() !== 'create' && !pendingFile() ? formModel() : null"
5556
6122
  [disabled]="mode() === 'view'"
5557
6123
  [isUploading]="isUploadingFile()"
5558
6124
  [uploadProgress]="uploadFileProgress()"
@@ -5562,6 +6128,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
5562
6128
  />
5563
6129
  }
5564
6130
 
6131
+ @if (isUploadCol() && isImageFile() && focalPointImageUrl()) {
6132
+ <div class="mb-6" [class.pointer-events-none]="mode() === 'view'">
6133
+ <p class="mb-2 text-sm font-medium">Focal Point</p>
6134
+ <mcms-focal-point-picker
6135
+ [imageUrl]="focalPointImageUrl()"
6136
+ [focalPoint]="currentFocalPoint()"
6137
+ [naturalWidth]="imageNaturalDimensions().width"
6138
+ [naturalHeight]="imageNaturalDimensions().height"
6139
+ [alt]="focalPointAlt()"
6140
+ [imageSizes]="uploadImageSizes()"
6141
+ (focalPointChange)="onFocalPointChange($event)"
6142
+ />
6143
+ </div>
6144
+ }
6145
+
6146
+ @if (isUploadCol() && formModelSizes()) {
6147
+ <div class="mb-6">
6148
+ <mcms-image-variants-display [sizes]="formModelSizes()" />
6149
+ </div>
6150
+ }
6151
+
5565
6152
  <div class="space-y-6">
5566
6153
  @for (field of visibleFields(); track field.name) {
5567
6154
  <mcms-field-renderer
@@ -5748,8 +6335,8 @@ class PublishControlsWidget {
5748
6335
  this.isUpdating.set(false);
5749
6336
  }
5750
6337
  }
5751
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: PublishControlsWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
5752
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: PublishControlsWidget, isStandalone: true, selector: "mcms-publish-controls", inputs: { collection: { classPropertyName: "collection", publicName: "collection", isSignal: true, isRequired: true, transformFunction: null }, documentId: { classPropertyName: "documentId", publicName: "documentId", isSignal: true, isRequired: true, transformFunction: null }, documentLabel: { classPropertyName: "documentLabel", publicName: "documentLabel", isSignal: true, isRequired: false, transformFunction: null }, initialStatus: { classPropertyName: "initialStatus", publicName: "initialStatus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { statusChanged: "statusChanged" }, host: { classAttribute: "inline-flex items-center gap-3" }, ngImport: i0, template: `
6338
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: PublishControlsWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
6339
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: PublishControlsWidget, isStandalone: true, selector: "mcms-publish-controls", inputs: { collection: { classPropertyName: "collection", publicName: "collection", isSignal: true, isRequired: true, transformFunction: null }, documentId: { classPropertyName: "documentId", publicName: "documentId", isSignal: true, isRequired: true, transformFunction: null }, documentLabel: { classPropertyName: "documentLabel", publicName: "documentLabel", isSignal: true, isRequired: false, transformFunction: null }, initialStatus: { classPropertyName: "initialStatus", publicName: "initialStatus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { statusChanged: "statusChanged" }, host: { classAttribute: "inline-flex items-center gap-3" }, ngImport: i0, template: `
5753
6340
  <mcms-badge [variant]="statusVariant()">
5754
6341
  {{ statusLabel() }}
5755
6342
  </mcms-badge>
@@ -5785,7 +6372,7 @@ class PublishControlsWidget {
5785
6372
  }
5786
6373
  `, isInline: true, dependencies: [{ kind: "component", type: Badge, selector: "mcms-badge", inputs: ["variant", "class", "role", "ariaLabel"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5787
6374
  }
5788
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: PublishControlsWidget, decorators: [{
6375
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: PublishControlsWidget, decorators: [{
5789
6376
  type: Component,
5790
6377
  args: [{
5791
6378
  selector: 'mcms-publish-controls',
@@ -5940,6 +6527,81 @@ class EntityViewWidget {
5940
6527
  canDelete = computed(() => {
5941
6528
  return this.collectionAccess.canDelete(this.collection().slug);
5942
6529
  }, ...(ngDevMode ? [{ debugName: "canDelete" }] : []));
6530
+ /** Whether this collection is an upload collection */
6531
+ isUploadCol = computed(() => isUploadCollection(this.collection()), ...(ngDevMode ? [{ debugName: "isUploadCol" }] : []));
6532
+ /** Whether the entity is an image */
6533
+ isEntityImage = computed(() => {
6534
+ const e = this.entity();
6535
+ if (!e)
6536
+ return false;
6537
+ const mimeType = e['mimeType'];
6538
+ return typeof mimeType === 'string' && mimeType.startsWith('image/');
6539
+ }, ...(ngDevMode ? [{ debugName: "isEntityImage" }] : []));
6540
+ /** Media URL for preview */
6541
+ entityMediaUrl = computed(() => {
6542
+ const e = this.entity();
6543
+ if (!e)
6544
+ return '';
6545
+ if (typeof e['url'] === 'string' && e['url'])
6546
+ return e['url'];
6547
+ if (typeof e['path'] === 'string' && e['path'])
6548
+ return `/api/media/file/${e['path']}`;
6549
+ return '';
6550
+ }, ...(ngDevMode ? [{ debugName: "entityMediaUrl" }] : []));
6551
+ /** Focal point from entity data */
6552
+ entityFocalPoint = computed(() => {
6553
+ const e = this.entity();
6554
+ if (!e)
6555
+ return { x: 0.5, y: 0.5 };
6556
+ const fp = e['focalPoint'];
6557
+ if (fp != null && typeof fp === 'object' && !Array.isArray(fp)) {
6558
+ const obj = fp; // eslint-disable-line @typescript-eslint/consistent-type-assertions
6559
+ const x = obj['x'];
6560
+ const y = obj['y'];
6561
+ if (typeof x === 'number' && typeof y === 'number')
6562
+ return { x, y };
6563
+ }
6564
+ return { x: 0.5, y: 0.5 };
6565
+ }, ...(ngDevMode ? [{ debugName: "entityFocalPoint" }] : []));
6566
+ /** Image dimensions from entity data */
6567
+ entityDimensions = computed(() => {
6568
+ const e = this.entity();
6569
+ return {
6570
+ width: typeof e?.['width'] === 'number' ? e['width'] : 0,
6571
+ height: typeof e?.['height'] === 'number' ? e['height'] : 0,
6572
+ };
6573
+ }, ...(ngDevMode ? [{ debugName: "entityDimensions" }] : []));
6574
+ /** Image sizes from collection upload config */
6575
+ viewImageSizes = computed(() => {
6576
+ return this.collection().upload?.imageSizes ?? [];
6577
+ }, ...(ngDevMode ? [{ debugName: "viewImageSizes" }] : []));
6578
+ /** Generated image sizes from entity data */
6579
+ entitySizes = computed(() => {
6580
+ const e = this.entity();
6581
+ if (!e)
6582
+ return null;
6583
+ const sizes = e['sizes'];
6584
+ if (sizes != null &&
6585
+ typeof sizes === 'object' &&
6586
+ !Array.isArray(sizes) &&
6587
+ Object.keys(sizes).length > 0) {
6588
+ return sizes; // eslint-disable-line @typescript-eslint/consistent-type-assertions
6589
+ }
6590
+ return null;
6591
+ }, ...(ngDevMode ? [{ debugName: "entitySizes" }] : []));
6592
+ /** Media preview data for non-image files */
6593
+ entityMediaPreview = computed(() => {
6594
+ const e = this.entity();
6595
+ if (!e)
6596
+ return null;
6597
+ return {
6598
+ url: typeof e['url'] === 'string' ? e['url'] : undefined,
6599
+ path: typeof e['path'] === 'string' ? e['path'] : undefined,
6600
+ mimeType: typeof e['mimeType'] === 'string' ? e['mimeType'] : undefined,
6601
+ filename: typeof e['filename'] === 'string' ? e['filename'] : undefined,
6602
+ alt: typeof e['alt'] === 'string' ? e['alt'] : undefined,
6603
+ };
6604
+ }, ...(ngDevMode ? [{ debugName: "entityMediaPreview" }] : []));
5943
6605
  /** Whether collection has soft delete enabled */
5944
6606
  hasSoftDelete = computed(() => !!this.collection().softDelete, ...(ngDevMode ? [{ debugName: "hasSoftDelete" }] : []));
5945
6607
  /** Whether the current entity is soft-deleted */
@@ -6294,8 +6956,8 @@ class EntityViewWidget {
6294
6956
  });
6295
6957
  }
6296
6958
  }
6297
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EntityViewWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
6298
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: EntityViewWidget, isStandalone: true, selector: "mcms-entity-view", inputs: { collection: { classPropertyName: "collection", publicName: "collection", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: true, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: false, transformFunction: null }, showBreadcrumbs: { classPropertyName: "showBreadcrumbs", publicName: "showBreadcrumbs", isSignal: true, isRequired: false, transformFunction: null }, fieldConfigs: { classPropertyName: "fieldConfigs", publicName: "fieldConfigs", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, showVersionHistory: { classPropertyName: "showVersionHistory", publicName: "showVersionHistory", isSignal: true, isRequired: false, transformFunction: null }, suppressNavigation: { classPropertyName: "suppressNavigation", publicName: "suppressNavigation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { edit: "edit", statusChanged: "statusChanged", delete_: "delete_", actionClick: "actionClick" }, host: { classAttribute: "block" }, ngImport: i0, template: `
6959
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EntityViewWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
6960
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: EntityViewWidget, isStandalone: true, selector: "mcms-entity-view", inputs: { collection: { classPropertyName: "collection", publicName: "collection", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: true, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: false, transformFunction: null }, showBreadcrumbs: { classPropertyName: "showBreadcrumbs", publicName: "showBreadcrumbs", isSignal: true, isRequired: false, transformFunction: null }, fieldConfigs: { classPropertyName: "fieldConfigs", publicName: "fieldConfigs", isSignal: true, isRequired: false, transformFunction: null }, actions: { classPropertyName: "actions", publicName: "actions", isSignal: true, isRequired: false, transformFunction: null }, showVersionHistory: { classPropertyName: "showVersionHistory", publicName: "showVersionHistory", isSignal: true, isRequired: false, transformFunction: null }, suppressNavigation: { classPropertyName: "suppressNavigation", publicName: "suppressNavigation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { edit: "edit", statusChanged: "statusChanged", delete_: "delete_", actionClick: "actionClick" }, host: { classAttribute: "block" }, ngImport: i0, template: `
6299
6961
  <div class="max-w-4xl">
6300
6962
  @if (showBreadcrumbs()) {
6301
6963
  <mcms-breadcrumbs class="mb-6">
@@ -6395,6 +7057,28 @@ class EntityViewWidget {
6395
7057
  {{ loadError() }}
6396
7058
  </mcms-alert>
6397
7059
  } @else if (entity()) {
7060
+ @if (isUploadCol() && entityMediaUrl()) {
7061
+ <div class="mb-6">
7062
+ @if (isEntityImage()) {
7063
+ <div class="pointer-events-none">
7064
+ <mcms-focal-point-picker
7065
+ [imageUrl]="entityMediaUrl()"
7066
+ [focalPoint]="entityFocalPoint()"
7067
+ [naturalWidth]="entityDimensions().width"
7068
+ [naturalHeight]="entityDimensions().height"
7069
+ [imageSizes]="viewImageSizes()"
7070
+ />
7071
+ </div>
7072
+ } @else {
7073
+ <mcms-media-preview [media]="entityMediaPreview()" size="xl" />
7074
+ }
7075
+ </div>
7076
+ }
7077
+ @if (isUploadCol() && entitySizes()) {
7078
+ <div class="mb-6">
7079
+ <mcms-image-variants-display [sizes]="entitySizes()" />
7080
+ </div>
7081
+ }
6398
7082
  <div class="grid gap-6 md:grid-cols-2">
6399
7083
  @for (field of visibleFields(); track field.name) {
6400
7084
  <mcms-field-display
@@ -6443,9 +7127,9 @@ class EntityViewWidget {
6443
7127
  </div>
6444
7128
  }
6445
7129
  </div>
6446
- `, isInline: true, dependencies: [{ kind: "component", type: Card, selector: "mcms-card" }, { kind: "component", type: CardContent, selector: "mcms-card-content" }, { kind: "component", type: CardFooter, selector: "mcms-card-footer" }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Alert, selector: "mcms-alert", inputs: ["variant", "class"] }, { kind: "component", type: Skeleton, selector: "mcms-skeleton", inputs: ["class"] }, { kind: "component", type: FieldDisplay, selector: "mcms-field-display", inputs: ["value", "type", "label", "format", "emptyText", "badgeConfig", "openInNewTab", "maxItems", "class", "fieldMeta", "numberFormat", "dateFormat"] }, { kind: "component", type: Breadcrumbs, selector: "mcms-breadcrumbs", inputs: ["class"] }, { kind: "component", type: BreadcrumbItem, selector: "mcms-breadcrumb-item", inputs: ["href", "current", "class"] }, { kind: "component", type: BreadcrumbSeparator, selector: "mcms-breadcrumb-separator", inputs: ["class"] }, { kind: "component", type: VersionHistoryWidget, selector: "mcms-version-history", inputs: ["collection", "documentId", "documentLabel"], outputs: ["restored"] }, { kind: "component", type: PublishControlsWidget, selector: "mcms-publish-controls", inputs: ["collection", "documentId", "documentLabel", "initialStatus"], outputs: ["statusChanged"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7130
+ `, isInline: true, dependencies: [{ kind: "component", type: Card, selector: "mcms-card" }, { kind: "component", type: CardContent, selector: "mcms-card-content" }, { kind: "component", type: CardFooter, selector: "mcms-card-footer" }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Alert, selector: "mcms-alert", inputs: ["variant", "class"] }, { kind: "component", type: Skeleton, selector: "mcms-skeleton", inputs: ["class"] }, { kind: "component", type: FieldDisplay, selector: "mcms-field-display", inputs: ["value", "type", "label", "format", "emptyText", "badgeConfig", "openInNewTab", "maxItems", "class", "fieldMeta", "numberFormat", "dateFormat"] }, { kind: "component", type: Breadcrumbs, selector: "mcms-breadcrumbs", inputs: ["class"] }, { kind: "component", type: BreadcrumbItem, selector: "mcms-breadcrumb-item", inputs: ["href", "current", "class"] }, { kind: "component", type: BreadcrumbSeparator, selector: "mcms-breadcrumb-separator", inputs: ["class"] }, { kind: "component", type: VersionHistoryWidget, selector: "mcms-version-history", inputs: ["collection", "documentId", "documentLabel"], outputs: ["restored"] }, { kind: "component", type: PublishControlsWidget, selector: "mcms-publish-controls", inputs: ["collection", "documentId", "documentLabel", "initialStatus"], outputs: ["statusChanged"] }, { kind: "component", type: MediaPreviewComponent, selector: "mcms-media-preview", inputs: ["media", "size", "class", "rounded"] }, { kind: "component", type: FocalPointPickerComponent, selector: "mcms-focal-point-picker", inputs: ["imageUrl", "focalPoint", "alt", "naturalWidth", "naturalHeight", "imageSizes"], outputs: ["focalPointChange"] }, { kind: "component", type: ImageVariantsDisplay, selector: "mcms-image-variants-display", inputs: ["sizes"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6447
7131
  }
6448
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EntityViewWidget, decorators: [{
7132
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EntityViewWidget, decorators: [{
6449
7133
  type: Component,
6450
7134
  args: [{
6451
7135
  selector: 'mcms-entity-view',
@@ -6462,6 +7146,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
6462
7146
  BreadcrumbSeparator,
6463
7147
  VersionHistoryWidget,
6464
7148
  PublishControlsWidget,
7149
+ MediaPreviewComponent,
7150
+ FocalPointPickerComponent,
7151
+ ImageVariantsDisplay,
6465
7152
  ],
6466
7153
  changeDetection: ChangeDetectionStrategy.OnPush,
6467
7154
  host: { class: 'block' },
@@ -6565,6 +7252,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
6565
7252
  {{ loadError() }}
6566
7253
  </mcms-alert>
6567
7254
  } @else if (entity()) {
7255
+ @if (isUploadCol() && entityMediaUrl()) {
7256
+ <div class="mb-6">
7257
+ @if (isEntityImage()) {
7258
+ <div class="pointer-events-none">
7259
+ <mcms-focal-point-picker
7260
+ [imageUrl]="entityMediaUrl()"
7261
+ [focalPoint]="entityFocalPoint()"
7262
+ [naturalWidth]="entityDimensions().width"
7263
+ [naturalHeight]="entityDimensions().height"
7264
+ [imageSizes]="viewImageSizes()"
7265
+ />
7266
+ </div>
7267
+ } @else {
7268
+ <mcms-media-preview [media]="entityMediaPreview()" size="xl" />
7269
+ }
7270
+ </div>
7271
+ }
7272
+ @if (isUploadCol() && entitySizes()) {
7273
+ <div class="mb-6">
7274
+ <mcms-image-variants-display [sizes]="entitySizes()" />
7275
+ </div>
7276
+ }
6568
7277
  <div class="grid gap-6 md:grid-cols-2">
6569
7278
  @for (field of visibleFields(); track field.name) {
6570
7279
  <mcms-field-display
@@ -6711,8 +7420,8 @@ class EntitySheetContentComponent {
6711
7420
  queryParamsHandling: 'merge',
6712
7421
  });
6713
7422
  }
6714
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EntitySheetContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6715
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: EntitySheetContentComponent, isStandalone: true, selector: "mcms-entity-sheet-content", host: { classAttribute: "flex flex-col h-full" }, providers: [provideIcons({ heroXMark })], ngImport: i0, template: `
7423
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EntitySheetContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7424
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: EntitySheetContentComponent, isStandalone: true, selector: "mcms-entity-sheet-content", host: { classAttribute: "flex flex-col h-full" }, providers: [provideIcons({ heroXMark })], ngImport: i0, template: `
6716
7425
  <!-- Header -->
6717
7426
  <header
6718
7427
  class="flex items-center justify-between gap-4 border-b border-border bg-card px-6 py-4 shrink-0"
@@ -6757,7 +7466,7 @@ class EntitySheetContentComponent {
6757
7466
  </div>
6758
7467
  `, isInline: true, dependencies: [{ kind: "component", type: EntityFormWidget, selector: "mcms-entity-form", inputs: ["collection", "entityId", "mode", "basePath", "showBreadcrumbs", "suppressNavigation", "isGlobal", "globalSlug"], outputs: ["saved", "cancelled", "saveError", "modeChange", "draftSaved"] }, { kind: "component", type: EntityViewWidget, selector: "mcms-entity-view", inputs: ["collection", "entityId", "basePath", "showBreadcrumbs", "fieldConfigs", "actions", "showVersionHistory", "suppressNavigation"], outputs: ["edit", "statusChanged", "delete_", "actionClick"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6759
7468
  }
6760
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EntitySheetContentComponent, decorators: [{
7469
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EntitySheetContentComponent, decorators: [{
6761
7470
  type: Component,
6762
7471
  args: [{
6763
7472
  selector: 'mcms-entity-sheet-content',
@@ -6994,8 +7703,8 @@ class AdminSidebarWidget {
6994
7703
  onSignOutClick() {
6995
7704
  this.signOut.emit();
6996
7705
  }
6997
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AdminSidebarWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
6998
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: AdminSidebarWidget, isStandalone: true, selector: "mcms-admin-sidebar", inputs: { branding: { classPropertyName: "branding", publicName: "branding", isSignal: true, isRequired: false, transformFunction: null }, collections: { classPropertyName: "collections", publicName: "collections", isSignal: true, isRequired: false, transformFunction: null }, globals: { classPropertyName: "globals", publicName: "globals", isSignal: true, isRequired: false, transformFunction: null }, pluginRoutes: { classPropertyName: "pluginRoutes", publicName: "pluginRoutes", isSignal: true, isRequired: false, transformFunction: null }, user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: false, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { signOut: "signOut" }, host: { classAttribute: "shrink-0" }, providers: [
7706
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AdminSidebarWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
7707
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: AdminSidebarWidget, isStandalone: true, selector: "mcms-admin-sidebar", inputs: { branding: { classPropertyName: "branding", publicName: "branding", isSignal: true, isRequired: false, transformFunction: null }, collections: { classPropertyName: "collections", publicName: "collections", isSignal: true, isRequired: false, transformFunction: null }, globals: { classPropertyName: "globals", publicName: "globals", isSignal: true, isRequired: false, transformFunction: null }, pluginRoutes: { classPropertyName: "pluginRoutes", publicName: "pluginRoutes", isSignal: true, isRequired: false, transformFunction: null }, user: { classPropertyName: "user", publicName: "user", isSignal: true, isRequired: false, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { signOut: "signOut" }, host: { classAttribute: "shrink-0" }, providers: [
6999
7708
  provideIcons({
7000
7709
  heroSquares2x2,
7001
7710
  heroNewspaper,
@@ -7147,7 +7856,7 @@ class AdminSidebarWidget {
7147
7856
  </mcms-sidebar>
7148
7857
  `, isInline: true, dependencies: [{ kind: "component", type: Sidebar, selector: "mcms-sidebar", inputs: ["width", "collapsedWidth", "collapsed", "class"] }, { kind: "component", type: SidebarNav, selector: "mcms-sidebar-nav", inputs: ["ariaLabel", "class"] }, { kind: "component", type: SidebarNavItem, selector: "mcms-sidebar-nav-item", inputs: ["label", "href", "icon", "badge", "active", "disabled", "exact", "class"], outputs: ["clicked"] }, { kind: "component", type: SidebarSection, selector: "mcms-sidebar-section", inputs: ["title", "collapsible", "expanded", "class"], outputs: ["expandedChange"] }, { kind: "component", type: Avatar, selector: "mcms-avatar", inputs: ["size", "class", "ariaLabel"] }, { kind: "component", type: AvatarFallback, selector: "mcms-avatar-fallback", inputs: ["delayMs", "class"] }, { kind: "component", type: DropdownMenu, selector: "mcms-dropdown-menu", inputs: ["disabled", "wrap", "typeaheadDelay", "class"], outputs: ["itemSelected"] }, { kind: "component", type: DropdownMenuItem, selector: "button[mcms-dropdown-item], a[mcms-dropdown-item]", inputs: ["value", "disabled", "shortcut", "class"], outputs: ["selected"] }, { kind: "component", type: DropdownSeparator, selector: "mcms-dropdown-separator" }, { kind: "component", type: DropdownLabel, selector: "mcms-dropdown-label" }, { kind: "directive", type: DropdownTrigger, selector: "[mcmsDropdownTrigger]", inputs: ["mcmsDropdownTrigger", "dropdownSide", "dropdownAlign", "dropdownOffset", "dropdownDisabled"], outputs: ["opened", "closed"], exportAs: ["mcmsDropdownTrigger"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7149
7858
  }
7150
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AdminSidebarWidget, decorators: [{
7859
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AdminSidebarWidget, decorators: [{
7151
7860
  type: Component,
7152
7861
  args: [{
7153
7862
  selector: 'mcms-admin-sidebar',
@@ -7437,8 +8146,8 @@ class AdminShellComponent {
7437
8146
  await this.auth.signOut();
7438
8147
  await this.router.navigate(['/admin/login']);
7439
8148
  }
7440
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AdminShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7441
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: AdminShellComponent, isStandalone: true, selector: "mcms-admin-shell", host: { listeners: { "document:keydown.escape": "onEscapeKey()" }, classAttribute: "flex h-screen overflow-hidden bg-background" }, ngImport: i0, template: `
8149
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AdminShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8150
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: AdminShellComponent, isStandalone: true, selector: "mcms-admin-shell", host: { listeners: { "document:keydown.escape": "onEscapeKey()" }, classAttribute: "flex h-screen overflow-hidden bg-background" }, ngImport: i0, template: `
7442
8151
  <!-- Skip navigation link for keyboard users -->
7443
8152
  <a
7444
8153
  href="#mcms-main-content"
@@ -7468,7 +8177,7 @@ class AdminShellComponent {
7468
8177
  <!-- Main Content (with top padding on mobile for header, normal padding at md+) -->
7469
8178
  <main id="mcms-main-content" class="flex-1 p-8 overflow-y-auto overflow-x-hidden pt-20 md:pt-8">
7470
8179
  @defer (hydrate on immediate) {
7471
- <router-outlet></router-outlet>
8180
+ <router-outlet />
7472
8181
  }
7473
8182
  </main>
7474
8183
 
@@ -7506,7 +8215,7 @@ class AdminShellComponent {
7506
8215
  }
7507
8216
  `, isInline: true, styles: ["@keyframes mcms-fade-in{0%{opacity:0}to{opacity:1}}@keyframes mcms-fade-out{0%{opacity:1}to{opacity:0}}@keyframes mcms-slide-in-right{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes mcms-slide-out-right{0%{transform:translate(0)}to{transform:translate(100%)}}.sheet-backdrop{animation:mcms-fade-in .15s ease-out}.sheet-backdrop-closing{animation:mcms-fade-out .15s ease-in forwards}.sheet-panel{animation:mcms-slide-in-right .2s ease-out}.sheet-panel-closing{animation:mcms-slide-out-right .2s ease-in forwards}\n"], dependencies: [{ kind: "component", type: AdminSidebarWidget, selector: "mcms-admin-sidebar", inputs: ["branding", "collections", "globals", "pluginRoutes", "user", "basePath", "collapsed", "width"], outputs: ["signOut"] }, { kind: "component", type: SidebarTrigger, selector: "mcms-sidebar-trigger", inputs: ["class"] }, { kind: "ngmodule", type: A11yModule }, { kind: "directive", type: i1.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "component", type: EntitySheetContentComponent, selector: "mcms-entity-sheet-content" }, { kind: "component", type: ToastContainer, selector: "mcms-toast-container" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [RouterOutlet]] });
7508
8217
  }
7509
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AdminShellComponent, decorators: [{
8218
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AdminShellComponent, decorators: [{
7510
8219
  type: Component,
7511
8220
  args: [{ selector: 'mcms-admin-shell', imports: [
7512
8221
  RouterOutlet,
@@ -7548,7 +8257,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
7548
8257
  <!-- Main Content (with top padding on mobile for header, normal padding at md+) -->
7549
8258
  <main id="mcms-main-content" class="flex-1 p-8 overflow-y-auto overflow-x-hidden pt-20 md:pt-8">
7550
8259
  @defer (hydrate on immediate) {
7551
- <router-outlet></router-outlet>
8260
+ <router-outlet />
7552
8261
  }
7553
8262
  </main>
7554
8263
 
@@ -7668,8 +8377,8 @@ class ForgotPasswordFormComponent {
7668
8377
  onBackToLogin() {
7669
8378
  this.backToLogin.emit();
7670
8379
  }
7671
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ForgotPasswordFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7672
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: ForgotPasswordFormComponent, isStandalone: true, selector: "mcms-forgot-password-form", outputs: { resetRequested: "resetRequested", backToLogin: "backToLogin" }, ngImport: i0, template: `
8380
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ForgotPasswordFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8381
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: ForgotPasswordFormComponent, isStandalone: true, selector: "mcms-forgot-password-form", outputs: { resetRequested: "resetRequested", backToLogin: "backToLogin" }, ngImport: i0, template: `
7673
8382
  <form (submit)="onSubmit($event)" class="space-y-4">
7674
8383
  @if (submitted() && !error()) {
7675
8384
  <div
@@ -7733,12 +8442,12 @@ class ForgotPasswordFormComponent {
7733
8442
  r="10"
7734
8443
  stroke="currentColor"
7735
8444
  stroke-width="4"
7736
- ></circle>
8445
+ />
7737
8446
  <path
7738
8447
  class="opacity-75"
7739
8448
  fill="currentColor"
7740
8449
  d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
7741
- ></path>
8450
+ />
7742
8451
  </svg>
7743
8452
  Sending...
7744
8453
  } @else {
@@ -7759,7 +8468,7 @@ class ForgotPasswordFormComponent {
7759
8468
  </form>
7760
8469
  `, isInline: true, dependencies: [{ kind: "component", type: Input, selector: "mcms-input", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "type", "id", "name", "placeholder", "autocomplete", "ariaLabel", "describedBy", "min", "max", "step"], outputs: ["valueChange", "blurred"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: McmsFormField, selector: "mcms-form-field", inputs: ["id", "required", "disabled", "errors", "hint", "hasLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
7761
8470
  }
7762
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ForgotPasswordFormComponent, decorators: [{
8471
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ForgotPasswordFormComponent, decorators: [{
7763
8472
  type: Component,
7764
8473
  args: [{
7765
8474
  selector: 'mcms-forgot-password-form',
@@ -7829,12 +8538,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
7829
8538
  r="10"
7830
8539
  stroke="currentColor"
7831
8540
  stroke-width="4"
7832
- ></circle>
8541
+ />
7833
8542
  <path
7834
8543
  class="opacity-75"
7835
8544
  fill="currentColor"
7836
8545
  d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
7837
- ></path>
8546
+ />
7838
8547
  </svg>
7839
8548
  Sending...
7840
8549
  } @else {
@@ -7962,8 +8671,8 @@ class ResetPasswordFormComponent {
7962
8671
  onGoToForgotPassword() {
7963
8672
  this.goToForgotPassword.emit();
7964
8673
  }
7965
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ResetPasswordFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7966
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: ResetPasswordFormComponent, isStandalone: true, selector: "mcms-reset-password-form", inputs: { token: { classPropertyName: "token", publicName: "token", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { resetComplete: "resetComplete", resetFailed: "resetFailed", goToLogin: "goToLogin", goToForgotPassword: "goToForgotPassword" }, ngImport: i0, template: `
8674
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ResetPasswordFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8675
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: ResetPasswordFormComponent, isStandalone: true, selector: "mcms-reset-password-form", inputs: { token: { classPropertyName: "token", publicName: "token", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { resetComplete: "resetComplete", resetFailed: "resetFailed", goToLogin: "goToLogin", goToForgotPassword: "goToForgotPassword" }, ngImport: i0, template: `
7967
8676
  <form (submit)="onSubmit($event)" class="space-y-4">
7968
8677
  @if (resetSuccess()) {
7969
8678
  <div
@@ -8053,12 +8762,12 @@ class ResetPasswordFormComponent {
8053
8762
  r="10"
8054
8763
  stroke="currentColor"
8055
8764
  stroke-width="4"
8056
- ></circle>
8765
+ />
8057
8766
  <path
8058
8767
  class="opacity-75"
8059
8768
  fill="currentColor"
8060
8769
  d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
8061
- ></path>
8770
+ />
8062
8771
  </svg>
8063
8772
  Resetting...
8064
8773
  } @else {
@@ -8070,7 +8779,7 @@ class ResetPasswordFormComponent {
8070
8779
  </form>
8071
8780
  `, isInline: true, dependencies: [{ kind: "component", type: Input, selector: "mcms-input", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "type", "id", "name", "placeholder", "autocomplete", "ariaLabel", "describedBy", "min", "max", "step"], outputs: ["valueChange", "blurred"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: McmsFormField, selector: "mcms-form-field", inputs: ["id", "required", "disabled", "errors", "hint", "hasLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8072
8781
  }
8073
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ResetPasswordFormComponent, decorators: [{
8782
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ResetPasswordFormComponent, decorators: [{
8074
8783
  type: Component,
8075
8784
  args: [{
8076
8785
  selector: 'mcms-reset-password-form',
@@ -8166,12 +8875,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
8166
8875
  r="10"
8167
8876
  stroke="currentColor"
8168
8877
  stroke-width="4"
8169
- ></circle>
8878
+ />
8170
8879
  <path
8171
8880
  class="opacity-75"
8172
8881
  fill="currentColor"
8173
8882
  d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
8174
- ></path>
8883
+ />
8175
8884
  </svg>
8176
8885
  Resetting...
8177
8886
  } @else {
@@ -8266,8 +8975,8 @@ class CollectionCardWidget {
8266
8975
  this.loading.set(false);
8267
8976
  }
8268
8977
  }
8269
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionCardWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
8270
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: CollectionCardWidget, isStandalone: true, selector: "mcms-collection-card", inputs: { collection: { classPropertyName: "collection", publicName: "collection", isSignal: true, isRequired: true, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: false, transformFunction: null }, showDocumentCount: { classPropertyName: "showDocumentCount", publicName: "showDocumentCount", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { viewAll: "viewAll" }, host: { classAttribute: "block" }, ngImport: i0, template: `
8978
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionCardWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
8979
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: CollectionCardWidget, isStandalone: true, selector: "mcms-collection-card", inputs: { collection: { classPropertyName: "collection", publicName: "collection", isSignal: true, isRequired: true, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: false, transformFunction: null }, showDocumentCount: { classPropertyName: "showDocumentCount", publicName: "showDocumentCount", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { viewAll: "viewAll" }, host: { classAttribute: "block" }, ngImport: i0, template: `
8271
8980
  <mcms-card>
8272
8981
  <mcms-card-header>
8273
8982
  <div class="flex items-center justify-between">
@@ -8301,7 +9010,7 @@ class CollectionCardWidget {
8301
9010
  </mcms-card>
8302
9011
  `, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: Card, selector: "mcms-card" }, { kind: "component", type: CardHeader, selector: "mcms-card-header" }, { kind: "component", type: CardContent, selector: "mcms-card-content" }, { kind: "component", type: CardFooter, selector: "mcms-card-footer" }, { kind: "component", type: Badge, selector: "mcms-badge", inputs: ["variant", "class", "role", "ariaLabel"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Skeleton, selector: "mcms-skeleton", inputs: ["class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8303
9012
  }
8304
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionCardWidget, decorators: [{
9013
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionCardWidget, decorators: [{
8305
9014
  type: Component,
8306
9015
  args: [{
8307
9016
  selector: 'mcms-collection-card',
@@ -8370,8 +9079,8 @@ class DashboardPage {
8370
9079
  }, ...(ngDevMode ? [{ debugName: "collections" }] : []));
8371
9080
  /** Visible collections grouped by admin.group. Named groups first, default last. */
8372
9081
  collectionGroups = computed(() => groupCollections(this.collections()), ...(ngDevMode ? [{ debugName: "collectionGroups" }] : []));
8373
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: DashboardPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
8374
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: DashboardPage, isStandalone: true, selector: "mcms-dashboard", host: { classAttribute: "block max-w-6xl" }, ngImport: i0, template: `
9082
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DashboardPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
9083
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: DashboardPage, isStandalone: true, selector: "mcms-dashboard", host: { classAttribute: "block max-w-6xl" }, ngImport: i0, template: `
8375
9084
  <header class="mb-10">
8376
9085
  <h1 class="text-4xl font-bold tracking-tight text-foreground">Dashboard</h1>
8377
9086
  <p class="text-muted-foreground mt-3 text-lg">Manage your content and collections</p>
@@ -8423,7 +9132,7 @@ class DashboardPage {
8423
9132
  }
8424
9133
  `, isInline: true, dependencies: [{ kind: "component", type: CollectionCardWidget, selector: "mcms-collection-card", inputs: ["collection", "basePath", "showDocumentCount"], outputs: ["viewAll"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8425
9134
  }
8426
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: DashboardPage, decorators: [{
9135
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DashboardPage, decorators: [{
8427
9136
  type: Component,
8428
9137
  args: [{
8429
9138
  selector: 'mcms-dashboard',
@@ -8537,8 +9246,8 @@ class DataPreviewDialog {
8537
9246
  close() {
8538
9247
  this.dialogRef.close();
8539
9248
  }
8540
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: DataPreviewDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
8541
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: DataPreviewDialog, isStandalone: true, selector: "mcms-data-preview-dialog", host: { styleAttribute: "display: block; width: 100%" }, ngImport: i0, template: `
9249
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DataPreviewDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
9250
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.0", type: DataPreviewDialog, isStandalone: true, selector: "mcms-data-preview-dialog", host: { styleAttribute: "display: block; width: 100%" }, ngImport: i0, template: `
8542
9251
  <mcms-dialog>
8543
9252
  <mcms-dialog-header>
8544
9253
  <mcms-dialog-title>{{ data.title }}</mcms-dialog-title>
@@ -8561,7 +9270,7 @@ class DataPreviewDialog {
8561
9270
  </mcms-dialog>
8562
9271
  `, isInline: true, dependencies: [{ kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Dialog, selector: "mcms-dialog", inputs: ["class"] }, { kind: "component", type: DialogHeader, selector: "mcms-dialog-header" }, { kind: "component", type: DialogTitle, selector: "mcms-dialog-title", inputs: ["id"] }, { kind: "component", type: DialogContent, selector: "mcms-dialog-content" }, { kind: "component", type: DialogFooter, selector: "mcms-dialog-footer" }, { kind: "directive", type: DialogClose, selector: "[mcmsDialogClose]", inputs: ["mcmsDialogClose"] }, { kind: "component", type: FieldDisplay, selector: "mcms-field-display", inputs: ["value", "type", "label", "format", "emptyText", "badgeConfig", "openInNewTab", "maxItems", "class", "fieldMeta", "numberFormat", "dateFormat"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
8563
9272
  }
8564
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: DataPreviewDialog, decorators: [{
9273
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DataPreviewDialog, decorators: [{
8565
9274
  type: Component,
8566
9275
  args: [{
8567
9276
  selector: 'mcms-data-preview-dialog',
@@ -9164,8 +9873,8 @@ class EntityListWidget {
9164
9873
  const path = `${this.basePath()}/${this.collection().slug}/new`;
9165
9874
  this.router.navigate([path]);
9166
9875
  }
9167
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EntityListWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
9168
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: EntityListWidget, isStandalone: true, selector: "mcms-entity-list", inputs: { collection: { classPropertyName: "collection", publicName: "collection", isSignal: true, isRequired: true, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, showBreadcrumbs: { classPropertyName: "showBreadcrumbs", publicName: "showBreadcrumbs", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null }, bulkActions: { classPropertyName: "bulkActions", publicName: "bulkActions", isSignal: true, isRequired: false, transformFunction: null }, headerActions: { classPropertyName: "headerActions", publicName: "headerActions", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, searchFields: { classPropertyName: "searchFields", publicName: "searchFields", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, paginated: { classPropertyName: "paginated", publicName: "paginated", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, emptyTitle: { classPropertyName: "emptyTitle", publicName: "emptyTitle", isSignal: true, isRequired: false, transformFunction: null }, emptyDescription: { classPropertyName: "emptyDescription", publicName: "emptyDescription", isSignal: true, isRequired: false, transformFunction: null }, searchQuery: { classPropertyName: "searchQuery", publicName: "searchQuery", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { headerActionClick: "headerActionClick", entityClick: "entityClick", entityAction: "entityAction", bulkAction: "bulkAction", dataLoaded: "dataLoaded", searchQuery: "searchQueryChange" }, host: { classAttribute: "block" }, providers: [provideIcons({ heroEye })], viewQueries: [{ propertyName: "complexCellTemplate", first: true, predicate: ["complexCell"], descendants: true, isSignal: true }], ngImport: i0, template: `
9876
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EntityListWidget, deps: [], target: i0.ɵɵFactoryTarget.Component });
9877
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: EntityListWidget, isStandalone: true, selector: "mcms-entity-list", inputs: { collection: { classPropertyName: "collection", publicName: "collection", isSignal: true, isRequired: true, transformFunction: null }, basePath: { classPropertyName: "basePath", publicName: "basePath", isSignal: true, isRequired: false, transformFunction: null }, showHeader: { classPropertyName: "showHeader", publicName: "showHeader", isSignal: true, isRequired: false, transformFunction: null }, showBreadcrumbs: { classPropertyName: "showBreadcrumbs", publicName: "showBreadcrumbs", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null }, bulkActions: { classPropertyName: "bulkActions", publicName: "bulkActions", isSignal: true, isRequired: false, transformFunction: null }, headerActions: { classPropertyName: "headerActions", publicName: "headerActions", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, searchFields: { classPropertyName: "searchFields", publicName: "searchFields", isSignal: true, isRequired: false, transformFunction: null }, sortable: { classPropertyName: "sortable", publicName: "sortable", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, paginated: { classPropertyName: "paginated", publicName: "paginated", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, emptyTitle: { classPropertyName: "emptyTitle", publicName: "emptyTitle", isSignal: true, isRequired: false, transformFunction: null }, emptyDescription: { classPropertyName: "emptyDescription", publicName: "emptyDescription", isSignal: true, isRequired: false, transformFunction: null }, searchQuery: { classPropertyName: "searchQuery", publicName: "searchQuery", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { headerActionClick: "headerActionClick", entityClick: "entityClick", entityAction: "entityAction", bulkAction: "bulkAction", dataLoaded: "dataLoaded", searchQuery: "searchQueryChange" }, host: { classAttribute: "block" }, providers: [provideIcons({ heroEye })], viewQueries: [{ propertyName: "complexCellTemplate", first: true, predicate: ["complexCell"], descendants: true, isSignal: true }], ngImport: i0, template: `
9169
9878
  @if (showHeader()) {
9170
9879
  @if (showBreadcrumbs()) {
9171
9880
  <mcms-breadcrumbs class="mb-6">
@@ -9281,7 +9990,7 @@ class EntityListWidget {
9281
9990
  </ng-template>
9282
9991
  `, isInline: true, dependencies: [{ kind: "component", type: DataTable, selector: "mcms-data-table", inputs: ["data", "columns", "loading", "searchable", "searchPlaceholder", "searchFields", "sortable", "sort", "selectable", "selectedItems", "paginated", "pageSize", "pageSizeOptions", "currentPage", "totalItems", "emptyTitle", "emptyDescription", "clickableRows", "rowActions", "trackByFn", "class", "searchQuery"], outputs: ["sortChange", "selectedItemsChange", "currentPageChange", "searchChange", "selectionChange", "pageChange", "pageSizeChange", "rowClick", "rowAction", "searchQueryChange"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Badge, selector: "mcms-badge", inputs: ["variant", "class", "role", "ariaLabel"] }, { kind: "component", type: Breadcrumbs, selector: "mcms-breadcrumbs", inputs: ["class"] }, { kind: "component", type: BreadcrumbItem, selector: "mcms-breadcrumb-item", inputs: ["href", "current", "class"] }, { kind: "component", type: BreadcrumbSeparator, selector: "mcms-breadcrumb-separator", inputs: ["class"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9283
9992
  }
9284
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: EntityListWidget, decorators: [{
9993
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: EntityListWidget, decorators: [{
9285
9994
  type: Component,
9286
9995
  args: [{
9287
9996
  selector: 'mcms-entity-list',
@@ -9474,8 +10183,8 @@ class GenerateApiKeyDialog {
9474
10183
  // Clipboard API not available, user can manually copy
9475
10184
  }
9476
10185
  }
9477
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: GenerateApiKeyDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
9478
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: GenerateApiKeyDialog, isStandalone: true, selector: "mcms-generate-api-key-dialog", host: { styleAttribute: "display: block; width: 100%" }, ngImport: i0, template: `
10186
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: GenerateApiKeyDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
10187
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: GenerateApiKeyDialog, isStandalone: true, selector: "mcms-generate-api-key-dialog", host: { styleAttribute: "display: block; width: 100%" }, ngImport: i0, template: `
9479
10188
  <mcms-dialog>
9480
10189
  <mcms-dialog-header>
9481
10190
  <mcms-dialog-title>Generate API Key</mcms-dialog-title>
@@ -9588,7 +10297,7 @@ class GenerateApiKeyDialog {
9588
10297
  </mcms-dialog>
9589
10298
  `, isInline: true, dependencies: [{ kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Dialog, selector: "mcms-dialog", inputs: ["class"] }, { kind: "component", type: DialogHeader, selector: "mcms-dialog-header" }, { kind: "component", type: DialogTitle, selector: "mcms-dialog-title", inputs: ["id"] }, { kind: "component", type: DialogContent, selector: "mcms-dialog-content" }, { kind: "component", type: DialogFooter, selector: "mcms-dialog-footer" }, { kind: "directive", type: DialogClose, selector: "[mcmsDialogClose]", inputs: ["mcmsDialogClose"] }, { kind: "component", type: Input, selector: "mcms-input", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "type", "id", "name", "placeholder", "autocomplete", "ariaLabel", "describedBy", "min", "max", "step"], outputs: ["valueChange", "blurred"] }, { kind: "component", type: Label, selector: "mcms-label", inputs: ["for", "required", "disabled", "class"] }, { kind: "component", type: Select, selector: "mcms-select", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "id", "name", "placeholder", "options", "describedBy", "ariaLabel"], outputs: ["valueChange", "blurred"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9590
10299
  }
9591
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: GenerateApiKeyDialog, decorators: [{
10300
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: GenerateApiKeyDialog, decorators: [{
9592
10301
  type: Component,
9593
10302
  args: [{
9594
10303
  selector: 'mcms-generate-api-key-dialog',
@@ -9789,8 +10498,8 @@ class CollectionListPage {
9789
10498
  }
9790
10499
  }
9791
10500
  }
9792
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionListPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
9793
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: CollectionListPage, isStandalone: true, selector: "mcms-collection-list", host: { classAttribute: "block" }, viewQueries: [{ propertyName: "entityList", first: true, predicate: ["entityList"], descendants: true, isSignal: true }], ngImport: i0, template: `
10501
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionListPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
10502
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: CollectionListPage, isStandalone: true, selector: "mcms-collection-list", host: { classAttribute: "block" }, viewQueries: [{ propertyName: "entityList", first: true, predicate: ["entityList"], descendants: true, isSignal: true }], ngImport: i0, template: `
9794
10503
  @if (collection(); as col) {
9795
10504
  <mcms-entity-list
9796
10505
  #entityList
@@ -9808,7 +10517,7 @@ class CollectionListPage {
9808
10517
  }
9809
10518
  `, isInline: true, dependencies: [{ kind: "component", type: EntityListWidget, selector: "mcms-entity-list", inputs: ["collection", "basePath", "showHeader", "showBreadcrumbs", "columns", "rowActions", "bulkActions", "headerActions", "searchable", "searchPlaceholder", "searchFields", "sortable", "selectable", "paginated", "pageSize", "emptyTitle", "emptyDescription", "searchQuery"], outputs: ["headerActionClick", "entityClick", "entityAction", "bulkAction", "dataLoaded", "searchQueryChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9810
10519
  }
9811
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionListPage, decorators: [{
10520
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionListPage, decorators: [{
9812
10521
  type: Component,
9813
10522
  args: [{
9814
10523
  selector: 'mcms-collection-list',
@@ -9874,8 +10583,8 @@ class CollectionViewPage {
9874
10583
  onDelete(_entity) {
9875
10584
  // Navigation is handled by EntityViewWidget
9876
10585
  }
9877
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionViewPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
9878
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: CollectionViewPage, isStandalone: true, selector: "mcms-collection-view", host: { classAttribute: "block" }, ngImport: i0, template: `
10586
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionViewPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
10587
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: CollectionViewPage, isStandalone: true, selector: "mcms-collection-view", host: { classAttribute: "block" }, ngImport: i0, template: `
9879
10588
  @if (collection(); as col) {
9880
10589
  @if (entityId(); as id) {
9881
10590
  <mcms-entity-view
@@ -9893,7 +10602,7 @@ class CollectionViewPage {
9893
10602
  }
9894
10603
  `, isInline: true, dependencies: [{ kind: "component", type: EntityViewWidget, selector: "mcms-entity-view", inputs: ["collection", "entityId", "basePath", "showBreadcrumbs", "fieldConfigs", "actions", "showVersionHistory", "suppressNavigation"], outputs: ["edit", "statusChanged", "delete_", "actionClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
9895
10604
  }
9896
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionViewPage, decorators: [{
10605
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionViewPage, decorators: [{
9897
10606
  type: Component,
9898
10607
  args: [{
9899
10608
  selector: 'mcms-collection-view',
@@ -9931,8 +10640,9 @@ var collectionView_page = /*#__PURE__*/Object.freeze({
9931
10640
  * Displays an iframe that shows a live preview of the document being edited.
9932
10641
  *
9933
10642
  * Two modes based on preview config type:
9934
- * - `preview: true` (server-rendered HTML): iframe loads API endpoint with scripts enabled
9935
- * for postMessage live updates.
10643
+ * - `preview: true` (server-rendered HTML): initial GET loads from database, then
10644
+ * subsequent form changes are POSTed to the same endpoint with the current form data
10645
+ * for realtime preview updates (no page reload needed).
9936
10646
  * - `preview: string/function` (URL-based): iframe loads the page URL with scripts DISABLED.
9937
10647
  * This prevents loading a second Angular app instance (with Vite HMR, SSR hydration, etc.)
9938
10648
  * which causes tab crashes in dev mode. The SSR-rendered HTML displays correctly without JS.
@@ -9960,6 +10670,8 @@ class LivePreviewComponent {
9960
10670
  refreshCounter = signal(0, ...(ngDevMode ? [{ debugName: "refreshCounter" }] : []));
9961
10671
  /** Reference to the static iframe element (available when previewUrl is non-null) */
9962
10672
  previewIframe = viewChild('previewIframe', ...(ngDevMode ? [{ debugName: "previewIframe" }] : []));
10673
+ /** Whether the initial iframe load from GET is complete */
10674
+ initialLoadDone = false;
9963
10675
  /** Compute the raw preview URL */
9964
10676
  previewUrl = computed(() => {
9965
10677
  // Force recomputation on refresh
@@ -10016,8 +10728,10 @@ class LivePreviewComponent {
10016
10728
  // URL-based preview: no scripts to prevent full Angular app from loading
10017
10729
  return 'allow-same-origin allow-popups allow-forms';
10018
10730
  }, ...(ngDevMode ? [{ debugName: "sandboxValue" }] : []));
10019
- /** Debounce timer for postMessage updates */
10731
+ /** Debounce timer for live preview updates */
10020
10732
  debounceTimer = undefined;
10733
+ /** AbortController for in-flight POST requests */
10734
+ fetchAbort = undefined;
10021
10735
  constructor() {
10022
10736
  // Effect 1: Set iframe src and sandbox when URL or sandbox config changes.
10023
10737
  // Uses untracked() for iframeWidth so device size toggles don't trigger a reload.
@@ -10029,10 +10743,17 @@ class LivePreviewComponent {
10029
10743
  const url = this.previewUrl();
10030
10744
  if (!url)
10031
10745
  return;
10746
+ this.initialLoadDone = false;
10032
10747
  iframe.setAttribute('sandbox', this.sandboxValue());
10033
10748
  iframe.src = url;
10034
10749
  // Set initial width without tracking the signal
10035
10750
  iframe.style.width = untracked(() => this.iframeWidth());
10751
+ // Mark initial load as done once the iframe finishes loading
10752
+ const onLoad = () => {
10753
+ this.initialLoadDone = true;
10754
+ iframe.removeEventListener('load', onLoad);
10755
+ };
10756
+ iframe.addEventListener('load', onLoad);
10036
10757
  });
10037
10758
  // Effect 2: Update iframe width only (no reload).
10038
10759
  // Changing CSS width on an iframe does not trigger navigation.
@@ -10042,25 +10763,43 @@ class LivePreviewComponent {
10042
10763
  return;
10043
10764
  iframeRef.nativeElement.style.width = this.iframeWidth();
10044
10765
  });
10045
- // Send form data to iframe via postMessage whenever data changes.
10046
- // Only effective for server-rendered previews (preview: true) where
10047
- // allow-scripts is enabled. URL-based previews have scripts disabled
10048
- // so the postMessage is a no-op (which is fine).
10766
+ // Effect 3: Live preview updates via POST (for preview: true mode).
10767
+ // When form data changes, POST it to the preview endpoint and write the
10768
+ // response HTML directly to the iframe. This works for all collection types
10769
+ // including email templates where postMessage isn't sufficient.
10049
10770
  effect(() => {
10050
10771
  const data = this.documentData();
10051
- const iframeRef = this.previewIframe();
10052
- if (!iframeRef?.nativeElement.contentWindow)
10772
+ const previewConfig = this.preview();
10773
+ // Only use POST-based updates for server-rendered previews (preview: true)
10774
+ if (previewConfig !== true) {
10775
+ // For URL-based previews, use postMessage as before
10776
+ const iframeRef = this.previewIframe();
10777
+ if (!iframeRef?.nativeElement.contentWindow)
10778
+ return;
10779
+ if (this.debounceTimer) {
10780
+ clearTimeout(this.debounceTimer);
10781
+ }
10782
+ this.debounceTimer = this.document.defaultView?.setTimeout(() => {
10783
+ const iframeWindow = iframeRef.nativeElement.contentWindow;
10784
+ if (iframeWindow) {
10785
+ const targetOrigin = this.document.defaultView?.location?.origin ?? '';
10786
+ iframeWindow.postMessage({ type: 'momentum-preview-update', data }, targetOrigin);
10787
+ }
10788
+ }, 300);
10789
+ return;
10790
+ }
10791
+ // For preview: true, POST form data to the server preview endpoint
10792
+ const url = untracked(() => this.previewUrl());
10793
+ if (!url)
10794
+ return;
10795
+ // Skip the first emission (initial load is handled by iframe src)
10796
+ if (!this.initialLoadDone)
10053
10797
  return;
10054
- // Debounce to avoid thrashing
10055
10798
  if (this.debounceTimer) {
10056
10799
  clearTimeout(this.debounceTimer);
10057
10800
  }
10058
10801
  this.debounceTimer = this.document.defaultView?.setTimeout(() => {
10059
- const iframeWindow = iframeRef.nativeElement.contentWindow;
10060
- if (iframeWindow) {
10061
- const targetOrigin = this.document.defaultView?.location?.origin ?? '';
10062
- iframeWindow.postMessage({ type: 'momentum-preview-update', data }, targetOrigin);
10063
- }
10802
+ this.fetchPreviewHtml(url, data);
10064
10803
  }, 300);
10065
10804
  });
10066
10805
  // Listen for edit block requests from preview iframe
@@ -10079,20 +10818,62 @@ class LivePreviewComponent {
10079
10818
  win.addEventListener('message', editHandler);
10080
10819
  this.destroyRef.onDestroy(() => win.removeEventListener('message', editHandler));
10081
10820
  }
10082
- // Clean up debounce timer on destroy
10821
+ // Clean up on destroy
10083
10822
  this.destroyRef.onDestroy(() => {
10084
10823
  if (this.debounceTimer) {
10085
10824
  clearTimeout(this.debounceTimer);
10086
10825
  this.debounceTimer = undefined;
10087
10826
  }
10827
+ this.fetchAbort?.abort();
10088
10828
  });
10089
10829
  }
10090
- /** Force iframe to reload */
10830
+ /** Force iframe to reload from server (GET) */
10091
10831
  refreshPreview() {
10092
10832
  this.refreshCounter.update((c) => c + 1);
10093
10833
  }
10094
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: LivePreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10095
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: LivePreviewComponent, isStandalone: true, selector: "mcms-live-preview", inputs: { preview: { classPropertyName: "preview", publicName: "preview", isSignal: true, isRequired: true, transformFunction: null }, documentData: { classPropertyName: "documentData", publicName: "documentData", isSignal: true, isRequired: true, transformFunction: null }, collectionSlug: { classPropertyName: "collectionSlug", publicName: "collectionSlug", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { editBlockRequest: "editBlockRequest" }, host: { classAttribute: "flex flex-col h-full border-l border-border" }, viewQueries: [{ propertyName: "previewIframe", first: true, predicate: ["previewIframe"], descendants: true, isSignal: true }], ngImport: i0, template: `
10834
+ /** POST form data to the preview endpoint and write the HTML response to the iframe. */
10835
+ fetchPreviewHtml(url, data) {
10836
+ // Cancel any in-flight request
10837
+ this.fetchAbort?.abort();
10838
+ this.fetchAbort = new AbortController();
10839
+ const win = this.document.defaultView;
10840
+ if (!win)
10841
+ return;
10842
+ win
10843
+ .fetch(url, {
10844
+ method: 'POST',
10845
+ headers: { 'Content-Type': 'application/json' },
10846
+ body: JSON.stringify({ data }),
10847
+ credentials: 'include',
10848
+ signal: this.fetchAbort.signal,
10849
+ })
10850
+ .then((response) => {
10851
+ if (!response.ok)
10852
+ return null;
10853
+ return response.text();
10854
+ })
10855
+ .then((html) => {
10856
+ if (!html)
10857
+ return;
10858
+ const iframeRef = this.previewIframe();
10859
+ if (!iframeRef)
10860
+ return;
10861
+ const doc = iframeRef.nativeElement.contentDocument;
10862
+ if (doc) {
10863
+ doc.open();
10864
+ doc.write(html);
10865
+ doc.close();
10866
+ }
10867
+ })
10868
+ .catch((err) => {
10869
+ // Ignore abort errors (expected when a new request supersedes)
10870
+ if (err instanceof DOMException && err.name === 'AbortError')
10871
+ return;
10872
+ console.warn('[momentum:live-preview] Preview fetch failed:', err);
10873
+ });
10874
+ }
10875
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: LivePreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
10876
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: LivePreviewComponent, isStandalone: true, selector: "mcms-live-preview", inputs: { preview: { classPropertyName: "preview", publicName: "preview", isSignal: true, isRequired: true, transformFunction: null }, documentData: { classPropertyName: "documentData", publicName: "documentData", isSignal: true, isRequired: true, transformFunction: null }, collectionSlug: { classPropertyName: "collectionSlug", publicName: "collectionSlug", isSignal: true, isRequired: true, transformFunction: null }, entityId: { classPropertyName: "entityId", publicName: "entityId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { editBlockRequest: "editBlockRequest" }, host: { classAttribute: "flex flex-col h-full border-l border-border" }, viewQueries: [{ propertyName: "previewIframe", first: true, predicate: ["previewIframe"], descendants: true, isSignal: true }], ngImport: i0, template: `
10096
10877
  <!-- Preview toolbar -->
10097
10878
  <div class="flex items-center gap-2 px-4 py-2 border-b border-border bg-muted/50">
10098
10879
  <span class="text-sm font-medium text-foreground">Preview</span>
@@ -10177,7 +10958,7 @@ class LivePreviewComponent {
10177
10958
  </div>
10178
10959
  `, isInline: true, dependencies: [{ kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10179
10960
  }
10180
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: LivePreviewComponent, decorators: [{
10961
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: LivePreviewComponent, decorators: [{
10181
10962
  type: Component,
10182
10963
  args: [{
10183
10964
  selector: 'mcms-live-preview',
@@ -10290,15 +11071,15 @@ class BlockEditDialog {
10290
11071
  getFieldPath(fieldName) {
10291
11072
  return `${this.data.path}.${this.data.blockIndex}.${fieldName}`;
10292
11073
  }
10293
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BlockEditDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
10294
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: BlockEditDialog, isStandalone: true, selector: "mcms-block-edit-dialog", host: { styleAttribute: "display: block; width: 100%" }, ngImport: i0, template: `
11074
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: BlockEditDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
11075
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: BlockEditDialog, isStandalone: true, selector: "mcms-block-edit-dialog", host: { styleAttribute: "display: block; width: 100%" }, ngImport: i0, template: `
10295
11076
  <mcms-dialog>
10296
11077
  <mcms-dialog-header>
10297
11078
  <mcms-dialog-title>Edit {{ blockLabel }}</mcms-dialog-title>
10298
11079
  </mcms-dialog-header>
10299
11080
 
10300
11081
  <mcms-dialog-content>
10301
- <div class="space-y-4 max-h-[60vh] overflow-y-auto py-1">
11082
+ <div class="space-y-4 max-h-[60vh] overflow-y-auto p-1">
10302
11083
  @for (field of visibleFields; track field.name) {
10303
11084
  <mcms-field-renderer
10304
11085
  [field]="field"
@@ -10318,7 +11099,7 @@ class BlockEditDialog {
10318
11099
  </mcms-dialog>
10319
11100
  `, isInline: true, dependencies: [{ kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Dialog, selector: "mcms-dialog", inputs: ["class"] }, { kind: "component", type: DialogHeader, selector: "mcms-dialog-header" }, { kind: "component", type: DialogTitle, selector: "mcms-dialog-title", inputs: ["id"] }, { kind: "component", type: DialogContent, selector: "mcms-dialog-content" }, { kind: "component", type: DialogFooter, selector: "mcms-dialog-footer" }, { kind: "directive", type: DialogClose, selector: "[mcmsDialogClose]", inputs: ["mcmsDialogClose"] }, { kind: "component", type: FieldRenderer, selector: "mcms-field-renderer", inputs: ["field", "formNode", "formTree", "formModel", "mode", "path"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10320
11101
  }
10321
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BlockEditDialog, decorators: [{
11102
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: BlockEditDialog, decorators: [{
10322
11103
  type: Component,
10323
11104
  args: [{
10324
11105
  selector: 'mcms-block-edit-dialog',
@@ -10341,7 +11122,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
10341
11122
  </mcms-dialog-header>
10342
11123
 
10343
11124
  <mcms-dialog-content>
10344
- <div class="space-y-4 max-h-[60vh] overflow-y-auto py-1">
11125
+ <div class="space-y-4 max-h-[60vh] overflow-y-auto p-1">
10345
11126
  @for (field of visibleFields; track field.name) {
10346
11127
  <mcms-field-renderer
10347
11128
  [field]="field"
@@ -10452,8 +11233,8 @@ class CollectionEditPage {
10452
11233
  },
10453
11234
  });
10454
11235
  }
10455
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionEditPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
10456
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: CollectionEditPage, isStandalone: true, selector: "mcms-collection-edit", host: { classAttribute: "block" }, viewQueries: [{ propertyName: "entityFormRef", first: true, predicate: ["entityForm"], descendants: true, isSignal: true }], ngImport: i0, template: `
11236
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionEditPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
11237
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: CollectionEditPage, isStandalone: true, selector: "mcms-collection-edit", host: { classAttribute: "block" }, viewQueries: [{ propertyName: "entityFormRef", first: true, predicate: ["entityForm"], descendants: true, isSignal: true }], ngImport: i0, template: `
10457
11238
  @if (collection(); as col) {
10458
11239
  @if (previewConfig(); as preview) {
10459
11240
  @if (showPreview()) {
@@ -10527,7 +11308,7 @@ class CollectionEditPage {
10527
11308
  }
10528
11309
  `, isInline: true, dependencies: [{ kind: "component", type: EntityFormWidget, selector: "mcms-entity-form", inputs: ["collection", "entityId", "mode", "basePath", "showBreadcrumbs", "suppressNavigation", "isGlobal", "globalSlug"], outputs: ["saved", "cancelled", "saveError", "modeChange", "draftSaved"] }, { kind: "component", type: LivePreviewComponent, selector: "mcms-live-preview", inputs: ["preview", "documentData", "collectionSlug", "entityId"], outputs: ["editBlockRequest"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10529
11310
  }
10530
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CollectionEditPage, decorators: [{
11311
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CollectionEditPage, decorators: [{
10531
11312
  type: Component,
10532
11313
  args: [{
10533
11314
  selector: 'mcms-collection-edit',
@@ -10692,8 +11473,8 @@ class LoginPage {
10692
11473
  this.isSubmitting.set(false);
10693
11474
  }
10694
11475
  }
10695
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: LoginPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
10696
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: LoginPage, isStandalone: true, selector: "mcms-login-page", host: { classAttribute: "flex min-h-screen items-center justify-center bg-background p-4" }, ngImport: i0, template: `
11476
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: LoginPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
11477
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: LoginPage, isStandalone: true, selector: "mcms-login-page", host: { classAttribute: "flex min-h-screen items-center justify-center bg-background p-4" }, ngImport: i0, template: `
10697
11478
  <main>
10698
11479
  <mcms-card class="w-full max-w-md">
10699
11480
  <mcms-card-header class="text-center">
@@ -10835,7 +11616,7 @@ class LoginPage {
10835
11616
  </main>
10836
11617
  `, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: Input, selector: "mcms-input", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "type", "id", "name", "placeholder", "autocomplete", "ariaLabel", "describedBy", "min", "max", "step"], outputs: ["valueChange", "blurred"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: McmsFormField, selector: "mcms-form-field", inputs: ["id", "required", "disabled", "errors", "hint", "hasLabel"] }, { kind: "component", type: Card, selector: "mcms-card" }, { kind: "component", type: CardHeader, selector: "mcms-card-header" }, { kind: "component", type: CardTitle, selector: "mcms-card-title", inputs: ["level"] }, { kind: "component", type: CardDescription, selector: "mcms-card-description" }, { kind: "component", type: CardContent, selector: "mcms-card-content" }, { kind: "component", type: CardFooter, selector: "mcms-card-footer" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
10837
11618
  }
10838
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: LoginPage, decorators: [{
11619
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: LoginPage, decorators: [{
10839
11620
  type: Component,
10840
11621
  args: [{
10841
11622
  selector: 'mcms-login-page',
@@ -11113,8 +11894,8 @@ class SetupPage {
11113
11894
  this.isSubmitting.set(false);
11114
11895
  }
11115
11896
  }
11116
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SetupPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
11117
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: SetupPage, isStandalone: true, selector: "mcms-setup-page", host: { classAttribute: "flex min-h-screen items-center justify-center bg-background p-4" }, ngImport: i0, template: `
11897
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SetupPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
11898
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: SetupPage, isStandalone: true, selector: "mcms-setup-page", host: { classAttribute: "flex min-h-screen items-center justify-center bg-background p-4" }, ngImport: i0, template: `
11118
11899
  <main>
11119
11900
  <mcms-card class="w-full max-w-md">
11120
11901
  <mcms-card-header class="text-center">
@@ -11213,7 +11994,7 @@ class SetupPage {
11213
11994
  </main>
11214
11995
  `, isInline: true, dependencies: [{ kind: "component", type: Input, selector: "mcms-input", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "type", "id", "name", "placeholder", "autocomplete", "ariaLabel", "describedBy", "min", "max", "step"], outputs: ["valueChange", "blurred"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: McmsFormField, selector: "mcms-form-field", inputs: ["id", "required", "disabled", "errors", "hint", "hasLabel"] }, { kind: "component", type: Card, selector: "mcms-card" }, { kind: "component", type: CardHeader, selector: "mcms-card-header" }, { kind: "component", type: CardTitle, selector: "mcms-card-title", inputs: ["level"] }, { kind: "component", type: CardDescription, selector: "mcms-card-description" }, { kind: "component", type: CardContent, selector: "mcms-card-content" }, { kind: "component", type: CardFooter, selector: "mcms-card-footer" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11215
11996
  }
11216
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SetupPage, decorators: [{
11997
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SetupPage, decorators: [{
11217
11998
  type: Component,
11218
11999
  args: [{
11219
12000
  selector: 'mcms-setup-page',
@@ -11375,14 +12156,27 @@ class MediaEditDialog {
11375
12156
  data = inject(DIALOG_DATA);
11376
12157
  api = injectMomentumAPI();
11377
12158
  media = this.data.media;
12159
+ imageSizes = this.data.imageSizes ?? [];
11378
12160
  filename = signal(this.data.media.filename, ...(ngDevMode ? [{ debugName: "filename" }] : []));
11379
12161
  altText = signal(this.data.media.alt ?? '', ...(ngDevMode ? [{ debugName: "altText" }] : []));
12162
+ focalPointValue = signal(this.data.media.focalPoint ?? { x: 0.5, y: 0.5 }, ...(ngDevMode ? [{ debugName: "focalPointValue" }] : []));
11380
12163
  isSaving = signal(false, ...(ngDevMode ? [{ debugName: "isSaving" }] : []));
11381
12164
  saveError = signal(null, ...(ngDevMode ? [{ debugName: "saveError" }] : []));
11382
12165
  formattedSize = formatFileSize(this.data.media.filesize);
12166
+ isImage = computed(() => this.media.mimeType.startsWith('image/'), ...(ngDevMode ? [{ debugName: "isImage" }] : []));
12167
+ imageUrl = computed(() => {
12168
+ return this.media.url ?? `/api/media/file/${this.media.path}`;
12169
+ }, ...(ngDevMode ? [{ debugName: "imageUrl" }] : []));
11383
12170
  hasChanges = computed(() => {
11384
- return this.filename() !== this.media.filename || this.altText() !== (this.media.alt ?? '');
12171
+ const fpChanged = this.focalPointValue().x !== (this.media.focalPoint?.x ?? 0.5) ||
12172
+ this.focalPointValue().y !== (this.media.focalPoint?.y ?? 0.5);
12173
+ return (this.filename() !== this.media.filename ||
12174
+ this.altText() !== (this.media.alt ?? '') ||
12175
+ fpChanged);
11385
12176
  }, ...(ngDevMode ? [{ debugName: "hasChanges" }] : []));
12177
+ onFocalPointChange(fp) {
12178
+ this.focalPointValue.set(fp);
12179
+ }
11386
12180
  /**
11387
12181
  * Save media metadata changes via API.
11388
12182
  */
@@ -11390,10 +12184,14 @@ class MediaEditDialog {
11390
12184
  this.isSaving.set(true);
11391
12185
  this.saveError.set(null);
11392
12186
  try {
11393
- const result = await this.api.collection('media').update(this.media.id, {
12187
+ const updateData = {
11394
12188
  filename: this.filename(),
11395
12189
  alt: this.altText(),
11396
- });
12190
+ };
12191
+ if (this.isImage()) {
12192
+ updateData['focalPoint'] = this.focalPointValue();
12193
+ }
12194
+ const result = await this.api.collection('media').update(this.media.id, updateData);
11397
12195
  if (isMediaEditItem(result)) {
11398
12196
  this.dialogRef.close({ updated: true, media: result });
11399
12197
  }
@@ -11408,8 +12206,8 @@ class MediaEditDialog {
11408
12206
  this.isSaving.set(false);
11409
12207
  }
11410
12208
  }
11411
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MediaEditDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
11412
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: MediaEditDialog, isStandalone: true, selector: "mcms-media-edit-dialog", host: { styleAttribute: "display: block; width: 100%" }, ngImport: i0, template: `
12209
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MediaEditDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
12210
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: MediaEditDialog, isStandalone: true, selector: "mcms-media-edit-dialog", host: { styleAttribute: "display: block; width: 100%" }, ngImport: i0, template: `
11413
12211
  <mcms-dialog>
11414
12212
  <mcms-dialog-header>
11415
12213
  <mcms-dialog-title>Edit Media</mcms-dialog-title>
@@ -11450,6 +12248,21 @@ class MediaEditDialog {
11450
12248
  </div>
11451
12249
  </div>
11452
12250
 
12251
+ @if (isImage()) {
12252
+ <div class="mt-4">
12253
+ <p class="mb-2 text-sm font-medium">Focal Point</p>
12254
+ <mcms-focal-point-picker
12255
+ [imageUrl]="imageUrl()"
12256
+ [focalPoint]="focalPointValue()"
12257
+ [naturalWidth]="media.width ?? 0"
12258
+ [naturalHeight]="media.height ?? 0"
12259
+ [alt]="media.alt ?? media.filename"
12260
+ [imageSizes]="imageSizes"
12261
+ (focalPointChange)="onFocalPointChange($event)"
12262
+ />
12263
+ </div>
12264
+ }
12265
+
11453
12266
  @if (saveError()) {
11454
12267
  <mcms-alert variant="destructive" class="mt-4">
11455
12268
  {{ saveError() }}
@@ -11467,9 +12280,9 @@ class MediaEditDialog {
11467
12280
  </button>
11468
12281
  </mcms-dialog-footer>
11469
12282
  </mcms-dialog>
11470
- `, isInline: true, dependencies: [{ kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Dialog, selector: "mcms-dialog", inputs: ["class"] }, { kind: "component", type: DialogHeader, selector: "mcms-dialog-header" }, { kind: "component", type: DialogTitle, selector: "mcms-dialog-title", inputs: ["id"] }, { kind: "component", type: DialogContent, selector: "mcms-dialog-content" }, { kind: "component", type: DialogFooter, selector: "mcms-dialog-footer" }, { kind: "directive", type: DialogClose, selector: "[mcmsDialogClose]", inputs: ["mcmsDialogClose"] }, { kind: "component", type: Input, selector: "mcms-input", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "type", "id", "name", "placeholder", "autocomplete", "ariaLabel", "describedBy", "min", "max", "step"], outputs: ["valueChange", "blurred"] }, { kind: "component", type: Textarea, selector: "mcms-textarea", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "id", "name", "placeholder", "rows", "ariaLabel", "describedBy"], outputs: ["valueChange", "blurred"] }, { kind: "component", type: Label, selector: "mcms-label", inputs: ["for", "required", "disabled", "class"] }, { kind: "component", type: Spinner, selector: "mcms-spinner", inputs: ["size", "label", "class"] }, { kind: "component", type: Alert, selector: "mcms-alert", inputs: ["variant", "class"] }, { kind: "component", type: MediaPreviewComponent, selector: "mcms-media-preview", inputs: ["media", "size", "class", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12283
+ `, isInline: true, dependencies: [{ kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Dialog, selector: "mcms-dialog", inputs: ["class"] }, { kind: "component", type: DialogHeader, selector: "mcms-dialog-header" }, { kind: "component", type: DialogTitle, selector: "mcms-dialog-title", inputs: ["id"] }, { kind: "component", type: DialogContent, selector: "mcms-dialog-content" }, { kind: "component", type: DialogFooter, selector: "mcms-dialog-footer" }, { kind: "directive", type: DialogClose, selector: "[mcmsDialogClose]", inputs: ["mcmsDialogClose"] }, { kind: "component", type: Input, selector: "mcms-input", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "type", "id", "name", "placeholder", "autocomplete", "ariaLabel", "describedBy", "min", "max", "step"], outputs: ["valueChange", "blurred"] }, { kind: "component", type: Textarea, selector: "mcms-textarea", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "id", "name", "placeholder", "rows", "ariaLabel", "describedBy"], outputs: ["valueChange", "blurred"] }, { kind: "component", type: Label, selector: "mcms-label", inputs: ["for", "required", "disabled", "class"] }, { kind: "component", type: Spinner, selector: "mcms-spinner", inputs: ["size", "label", "class"] }, { kind: "component", type: Alert, selector: "mcms-alert", inputs: ["variant", "class"] }, { kind: "component", type: MediaPreviewComponent, selector: "mcms-media-preview", inputs: ["media", "size", "class", "rounded"] }, { kind: "component", type: FocalPointPickerComponent, selector: "mcms-focal-point-picker", inputs: ["imageUrl", "focalPoint", "alt", "naturalWidth", "naturalHeight", "imageSizes"], outputs: ["focalPointChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
11471
12284
  }
11472
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MediaEditDialog, decorators: [{
12285
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MediaEditDialog, decorators: [{
11473
12286
  type: Component,
11474
12287
  args: [{
11475
12288
  selector: 'mcms-media-edit-dialog',
@@ -11487,6 +12300,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
11487
12300
  Spinner,
11488
12301
  Alert,
11489
12302
  MediaPreviewComponent,
12303
+ FocalPointPickerComponent,
11490
12304
  ],
11491
12305
  changeDetection: ChangeDetectionStrategy.OnPush,
11492
12306
  host: { style: 'display: block; width: 100%' },
@@ -11531,6 +12345,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
11531
12345
  </div>
11532
12346
  </div>
11533
12347
 
12348
+ @if (isImage()) {
12349
+ <div class="mt-4">
12350
+ <p class="mb-2 text-sm font-medium">Focal Point</p>
12351
+ <mcms-focal-point-picker
12352
+ [imageUrl]="imageUrl()"
12353
+ [focalPoint]="focalPointValue()"
12354
+ [naturalWidth]="media.width ?? 0"
12355
+ [naturalHeight]="media.height ?? 0"
12356
+ [alt]="media.alt ?? media.filename"
12357
+ [imageSizes]="imageSizes"
12358
+ (focalPointChange)="onFocalPointChange($event)"
12359
+ />
12360
+ </div>
12361
+ }
12362
+
11534
12363
  @if (saveError()) {
11535
12364
  <mcms-alert variant="destructive" class="mt-4">
11536
12365
  {{ saveError() }}
@@ -11591,6 +12420,7 @@ function getInputElement(event) {
11591
12420
  */
11592
12421
  class MediaLibraryPage {
11593
12422
  document = inject(DOCUMENT);
12423
+ route = inject(ActivatedRoute);
11594
12424
  api = injectMomentumAPI();
11595
12425
  uploadService = inject(UploadService);
11596
12426
  feedback = inject(FeedbackService);
@@ -11598,6 +12428,12 @@ class MediaLibraryPage {
11598
12428
  dialog = inject(DialogService);
11599
12429
  destroyRef = inject(DestroyRef);
11600
12430
  uploadSubscriptions = [];
12431
+ /** Image sizes config from the media collection (for crop previews in edit dialog) */
12432
+ mediaImageSizes = (() => {
12433
+ const collections = getCollectionsFromRouteData(this.route.parent?.snapshot.data);
12434
+ const mediaColl = collections.find((c) => c.slug === 'media');
12435
+ return mediaColl?.upload?.imageSizes ?? [];
12436
+ })();
11601
12437
  /** Internal state */
11602
12438
  isLoading = signal(true, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
11603
12439
  mediaItems = signal([], ...(ngDevMode ? [{ debugName: "mediaItems" }] : []));
@@ -11749,7 +12585,7 @@ class MediaLibraryPage {
11749
12585
  */
11750
12586
  editMedia(media) {
11751
12587
  const dialogRef = this.dialog.open(MediaEditDialog, {
11752
- data: { media },
12588
+ data: { media, imageSizes: this.mediaImageSizes },
11753
12589
  width: '36rem',
11754
12590
  });
11755
12591
  dialogRef.afterClosed.subscribe((result) => {
@@ -11819,8 +12655,8 @@ class MediaLibraryPage {
11819
12655
  }
11820
12656
  return `${bytes} bytes`;
11821
12657
  }
11822
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MediaLibraryPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
11823
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: MediaLibraryPage, isStandalone: true, selector: "mcms-media-library", host: { classAttribute: "block" }, providers: [
12658
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MediaLibraryPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
12659
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: MediaLibraryPage, isStandalone: true, selector: "mcms-media-library", host: { classAttribute: "block" }, providers: [
11824
12660
  provideIcons({ heroCloudArrowUp, heroTrash, heroArrowDownTray, heroEye, heroPencilSquare }),
11825
12661
  ], ngImport: i0, template: `
11826
12662
  <div class="space-y-6">
@@ -12035,7 +12871,7 @@ class MediaLibraryPage {
12035
12871
  </div>
12036
12872
  `, isInline: true, dependencies: [{ kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Spinner, selector: "mcms-spinner", inputs: ["size", "label", "class"] }, { kind: "component", type: Pagination, selector: "mcms-pagination", inputs: ["currentPage", "totalPages", "siblingCount", "class"], outputs: ["pageChange"] }, { kind: "component", type: SearchInput, selector: "mcms-search-input", inputs: ["value", "placeholder", "debounce", "disabled", "ariaLabel", "class"], outputs: ["valueChange", "searchChange", "clear"] }, { kind: "component", type: Badge, selector: "mcms-badge", inputs: ["variant", "class", "role", "ariaLabel"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: MediaPreviewComponent, selector: "mcms-media-preview", inputs: ["media", "size", "class", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12037
12873
  }
12038
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MediaLibraryPage, decorators: [{
12874
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MediaLibraryPage, decorators: [{
12039
12875
  type: Component,
12040
12876
  args: [{
12041
12877
  selector: 'mcms-media-library',
@@ -12276,8 +13112,8 @@ class ForgotPasswordPage {
12276
13112
  navigateToLogin() {
12277
13113
  void this.router.navigate(['/admin/login']);
12278
13114
  }
12279
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ForgotPasswordPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
12280
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: ForgotPasswordPage, isStandalone: true, selector: "mcms-forgot-password-page", host: { classAttribute: "flex min-h-screen items-center justify-center bg-background p-4" }, ngImport: i0, template: `
13115
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ForgotPasswordPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
13116
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.0", type: ForgotPasswordPage, isStandalone: true, selector: "mcms-forgot-password-page", host: { classAttribute: "flex min-h-screen items-center justify-center bg-background p-4" }, ngImport: i0, template: `
12281
13117
  <main>
12282
13118
  <mcms-card class="w-full max-w-md">
12283
13119
  <mcms-card-header class="text-center">
@@ -12298,7 +13134,7 @@ class ForgotPasswordPage {
12298
13134
  </main>
12299
13135
  `, isInline: true, dependencies: [{ kind: "component", type: Card, selector: "mcms-card" }, { kind: "component", type: CardHeader, selector: "mcms-card-header" }, { kind: "component", type: CardTitle, selector: "mcms-card-title", inputs: ["level"] }, { kind: "component", type: CardDescription, selector: "mcms-card-description" }, { kind: "component", type: CardContent, selector: "mcms-card-content" }, { kind: "component", type: CardFooter, selector: "mcms-card-footer" }, { kind: "component", type: ForgotPasswordFormComponent, selector: "mcms-forgot-password-form", outputs: ["resetRequested", "backToLogin"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12300
13136
  }
12301
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ForgotPasswordPage, decorators: [{
13137
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ForgotPasswordPage, decorators: [{
12302
13138
  type: Component,
12303
13139
  args: [{
12304
13140
  selector: 'mcms-forgot-password-page',
@@ -12366,8 +13202,8 @@ class ResetPasswordPage {
12366
13202
  navigateToForgotPassword() {
12367
13203
  void this.router.navigate(['/admin/forgot-password']);
12368
13204
  }
12369
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ResetPasswordPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
12370
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.2", type: ResetPasswordPage, isStandalone: true, selector: "mcms-reset-password-page", host: { classAttribute: "flex min-h-screen items-center justify-center bg-background p-4" }, ngImport: i0, template: `
13205
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ResetPasswordPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
13206
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.0", type: ResetPasswordPage, isStandalone: true, selector: "mcms-reset-password-page", host: { classAttribute: "flex min-h-screen items-center justify-center bg-background p-4" }, ngImport: i0, template: `
12371
13207
  <main>
12372
13208
  <mcms-card class="w-full max-w-md">
12373
13209
  <mcms-card-header class="text-center">
@@ -12390,7 +13226,7 @@ class ResetPasswordPage {
12390
13226
  </main>
12391
13227
  `, isInline: true, dependencies: [{ kind: "component", type: Card, selector: "mcms-card" }, { kind: "component", type: CardHeader, selector: "mcms-card-header" }, { kind: "component", type: CardTitle, selector: "mcms-card-title", inputs: ["level"] }, { kind: "component", type: CardDescription, selector: "mcms-card-description" }, { kind: "component", type: CardContent, selector: "mcms-card-content" }, { kind: "component", type: CardFooter, selector: "mcms-card-footer" }, { kind: "component", type: ResetPasswordFormComponent, selector: "mcms-reset-password-form", inputs: ["token"], outputs: ["resetComplete", "resetFailed", "goToLogin", "goToForgotPassword"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12392
13228
  }
12393
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ResetPasswordPage, decorators: [{
13229
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ResetPasswordPage, decorators: [{
12394
13230
  type: Component,
12395
13231
  args: [{
12396
13232
  selector: 'mcms-reset-password-page',
@@ -12508,8 +13344,8 @@ class BlockWrapperComponent {
12508
13344
  getBlockSubFieldPath(fieldName) {
12509
13345
  return `${this.path()}.${this.blockIndex()}.${fieldName}`;
12510
13346
  }
12511
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BlockWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12512
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: BlockWrapperComponent, isStandalone: true, selector: "mcms-block-wrapper", inputs: { block: { classPropertyName: "block", publicName: "block", isSignal: true, isRequired: true, transformFunction: null }, blockIndex: { classPropertyName: "blockIndex", publicName: "blockIndex", isSignal: true, isRequired: true, transformFunction: null }, blockConfig: { classPropertyName: "blockConfig", publicName: "blockConfig", isSignal: true, isRequired: true, transformFunction: null }, blockLabel: { classPropertyName: "blockLabel", publicName: "blockLabel", isSignal: true, isRequired: true, transformFunction: null }, isSelected: { classPropertyName: "isSelected", publicName: "isSelected", isSignal: true, isRequired: false, transformFunction: null }, isHovered: { classPropertyName: "isHovered", publicName: "isHovered", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null }, isCollapsed: { classPropertyName: "isCollapsed", publicName: "isCollapsed", isSignal: true, isRequired: false, transformFunction: null }, canMoveUp: { classPropertyName: "canMoveUp", publicName: "canMoveUp", isSignal: true, isRequired: false, transformFunction: null }, canMoveDown: { classPropertyName: "canMoveDown", publicName: "canMoveDown", isSignal: true, isRequired: false, transformFunction: null }, canDelete: { classPropertyName: "canDelete", publicName: "canDelete", isSignal: true, isRequired: false, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, formTree: { classPropertyName: "formTree", publicName: "formTree", isSignal: true, isRequired: false, transformFunction: null }, formModel: { classPropertyName: "formModel", publicName: "formModel", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected", hoverStart: "hoverStart", hoverEnd: "hoverEnd", moveUp: "moveUp", moveDown: "moveDown", deleteBlock: "deleteBlock", toggleCollapse: "toggleCollapse" }, host: { listeners: { "click": "selected.emit()", "mouseenter": "hoverStart.emit()", "mouseleave": "hoverEnd.emit()", "focus": "selected.emit()" }, properties: { "class.border-primary": "isSelected()", "class.border-border": "!isSelected()", "attr.data-testid": "\"block-wrapper\"", "attr.data-block-index": "blockIndex()", "attr.data-block-type": "block().blockType", "attr.role": "\"listitem\"", "attr.tabindex": "\"0\"", "attr.aria-label": "blockAriaLabel()" }, classAttribute: "block relative rounded-lg border transition-colors overflow-hidden" }, providers: [provideIcons({ heroChevronUp, heroChevronDown, heroChevronRight, heroTrash })], ngImport: i0, template: `
13347
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: BlockWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13348
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: BlockWrapperComponent, isStandalone: true, selector: "mcms-block-wrapper", inputs: { block: { classPropertyName: "block", publicName: "block", isSignal: true, isRequired: true, transformFunction: null }, blockIndex: { classPropertyName: "blockIndex", publicName: "blockIndex", isSignal: true, isRequired: true, transformFunction: null }, blockConfig: { classPropertyName: "blockConfig", publicName: "blockConfig", isSignal: true, isRequired: true, transformFunction: null }, blockLabel: { classPropertyName: "blockLabel", publicName: "blockLabel", isSignal: true, isRequired: true, transformFunction: null }, isSelected: { classPropertyName: "isSelected", publicName: "isSelected", isSignal: true, isRequired: false, transformFunction: null }, isHovered: { classPropertyName: "isHovered", publicName: "isHovered", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null }, isCollapsed: { classPropertyName: "isCollapsed", publicName: "isCollapsed", isSignal: true, isRequired: false, transformFunction: null }, canMoveUp: { classPropertyName: "canMoveUp", publicName: "canMoveUp", isSignal: true, isRequired: false, transformFunction: null }, canMoveDown: { classPropertyName: "canMoveDown", publicName: "canMoveDown", isSignal: true, isRequired: false, transformFunction: null }, canDelete: { classPropertyName: "canDelete", publicName: "canDelete", isSignal: true, isRequired: false, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, formTree: { classPropertyName: "formTree", publicName: "formTree", isSignal: true, isRequired: false, transformFunction: null }, formModel: { classPropertyName: "formModel", publicName: "formModel", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selected: "selected", hoverStart: "hoverStart", hoverEnd: "hoverEnd", moveUp: "moveUp", moveDown: "moveDown", deleteBlock: "deleteBlock", toggleCollapse: "toggleCollapse" }, host: { listeners: { "click": "selected.emit()", "mouseenter": "hoverStart.emit()", "mouseleave": "hoverEnd.emit()", "focus": "selected.emit()" }, properties: { "class.border-primary": "isSelected()", "class.border-border": "!isSelected()", "attr.data-testid": "\"block-wrapper\"", "attr.data-block-index": "blockIndex()", "attr.data-block-type": "block().blockType", "attr.role": "\"listitem\"", "attr.tabindex": "\"0\"", "attr.aria-label": "blockAriaLabel()" }, classAttribute: "block relative rounded-lg border transition-colors overflow-hidden" }, providers: [provideIcons({ heroChevronUp, heroChevronDown, heroChevronRight, heroTrash })], ngImport: i0, template: `
12513
13349
  <!-- Header: always visible -->
12514
13350
  <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
12515
13351
  <div
@@ -12601,7 +13437,7 @@ class BlockWrapperComponent {
12601
13437
  }
12602
13438
  `, isInline: true, dependencies: [{ kind: "component", type: FieldRenderer, selector: "mcms-field-renderer", inputs: ["field", "formNode", "formTree", "formModel", "mode", "path"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: Badge, selector: "mcms-badge", inputs: ["variant", "class", "role", "ariaLabel"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12603
13439
  }
12604
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BlockWrapperComponent, decorators: [{
13440
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: BlockWrapperComponent, decorators: [{
12605
13441
  type: Component,
12606
13442
  args: [{
12607
13443
  selector: 'mcms-block-wrapper',
@@ -12754,8 +13590,8 @@ class BlockInserterComponent {
12754
13590
  onPopoverClosed() {
12755
13591
  this.searchQuery.set('');
12756
13592
  }
12757
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BlockInserterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12758
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: BlockInserterComponent, isStandalone: true, selector: "mcms-block-inserter", inputs: { insertIndex: { classPropertyName: "insertIndex", publicName: "insertIndex", isSignal: true, isRequired: true, transformFunction: null }, blockDefinitions: { classPropertyName: "blockDefinitions", publicName: "blockDefinitions", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { blockTypeSelected: "blockTypeSelected" }, host: { properties: { "attr.data-testid": "\"block-inserter\"", "attr.data-insert-index": "insertIndex()" }, classAttribute: "group relative flex items-center justify-center py-1" }, providers: [provideIcons({ heroPlus })], viewQueries: [{ propertyName: "popover", first: true, predicate: ["popover"], descendants: true, isSignal: true }], ngImport: i0, template: `
13593
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: BlockInserterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13594
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: BlockInserterComponent, isStandalone: true, selector: "mcms-block-inserter", inputs: { insertIndex: { classPropertyName: "insertIndex", publicName: "insertIndex", isSignal: true, isRequired: true, transformFunction: null }, blockDefinitions: { classPropertyName: "blockDefinitions", publicName: "blockDefinitions", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { blockTypeSelected: "blockTypeSelected" }, host: { properties: { "attr.data-testid": "\"block-inserter\"", "attr.data-insert-index": "insertIndex()" }, classAttribute: "group relative flex items-center justify-center py-1" }, providers: [provideIcons({ heroPlus })], viewQueries: [{ propertyName: "popover", first: true, predicate: ["popover"], descendants: true, isSignal: true }], ngImport: i0, template: `
12759
13595
  <!-- Horizontal line -->
12760
13596
  <div
12761
13597
  class="absolute inset-x-0 top-1/2 h-px bg-border opacity-0 transition-opacity group-hover:opacity-100"
@@ -12804,7 +13640,7 @@ class BlockInserterComponent {
12804
13640
  </ng-template>
12805
13641
  `, isInline: true, dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: PopoverTrigger, selector: "[mcmsPopoverTrigger]", inputs: ["mcmsPopoverTrigger", "popoverSide", "popoverAlign", "popoverOffset", "popoverDisabled"], outputs: ["opened", "closed"], exportAs: ["mcmsPopoverTrigger"] }, { kind: "component", type: PopoverContent, selector: "mcms-popover-content" }, { kind: "component", type: Command, selector: "mcms-command", inputs: ["filterMode", "disabled", "alwaysExpanded", "class"] }, { kind: "component", type: CommandInput, selector: "mcms-command-input", inputs: ["placeholder", "value", "disabled", "autofocus", "ariaControls", "ariaExpanded", "ariaLabel", "class"], outputs: ["valueChange"] }, { kind: "component", type: CommandList, selector: "mcms-command-list", inputs: ["maxHeight", "class"] }, { kind: "component", type: CommandGroup, selector: "mcms-command-group", inputs: ["label", "class"] }, { kind: "component", type: CommandItem, selector: "mcms-command-item", inputs: ["value", "label", "disabled", "selected", "class"], outputs: ["itemSelect"] }, { kind: "component", type: CommandEmpty, selector: "mcms-command-empty", inputs: ["class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12806
13642
  }
12807
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: BlockInserterComponent, decorators: [{
13643
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: BlockInserterComponent, decorators: [{
12808
13644
  type: Component,
12809
13645
  args: [{
12810
13646
  selector: 'mcms-block-inserter',
@@ -13133,8 +13969,8 @@ class VisualBlockEditorComponent {
13133
13969
  break;
13134
13970
  }
13135
13971
  }
13136
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: VisualBlockEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13137
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: VisualBlockEditorComponent, isStandalone: true, selector: "mcms-visual-block-editor", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, formTree: { classPropertyName: "formTree", publicName: "formTree", isSignal: true, isRequired: false, transformFunction: null }, formModel: { classPropertyName: "formModel", publicName: "formModel", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "attr.data-testid": "\"visual-block-editor\"" }, classAttribute: "block" }, ngImport: i0, template: `
13972
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: VisualBlockEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
13973
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: VisualBlockEditorComponent, isStandalone: true, selector: "mcms-visual-block-editor", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, formTree: { classPropertyName: "formTree", publicName: "formTree", isSignal: true, isRequired: false, transformFunction: null }, formModel: { classPropertyName: "formModel", publicName: "formModel", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "attr.data-testid": "\"visual-block-editor\"" }, classAttribute: "block" }, ngImport: i0, template: `
13138
13974
  <!-- Header -->
13139
13975
  <div class="mb-4">
13140
13976
  <h3 class="text-sm font-medium text-foreground">{{ label() }}</h3>
@@ -13228,7 +14064,7 @@ class VisualBlockEditorComponent {
13228
14064
  </div>
13229
14065
  `, isInline: true, dependencies: [{ kind: "directive", type: i0.forwardRef(() => 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: i0.forwardRef(() => 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: i0.forwardRef(() => CdkDragPlaceholder), selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "component", type: i0.forwardRef(() => BlockWrapperComponent), selector: "mcms-block-wrapper", inputs: ["block", "blockIndex", "blockConfig", "blockLabel", "isSelected", "isHovered", "isDisabled", "isCollapsed", "canMoveUp", "canMoveDown", "canDelete", "formNode", "formTree", "formModel", "mode", "path"], outputs: ["selected", "hoverStart", "hoverEnd", "moveUp", "moveDown", "deleteBlock", "toggleCollapse"] }, { kind: "component", type: i0.forwardRef(() => BlockInserterComponent), selector: "mcms-block-inserter", inputs: ["insertIndex", "blockDefinitions", "disabled"], outputs: ["blockTypeSelected"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
13230
14066
  }
13231
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: VisualBlockEditorComponent, decorators: [{
14067
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: VisualBlockEditorComponent, decorators: [{
13232
14068
  type: Component,
13233
14069
  args: [{
13234
14070
  selector: 'mcms-visual-block-editor',
@@ -13377,18 +14213,18 @@ function provideMomentumFieldRenderers() {
13377
14213
  registry.register('checkbox', () => Promise.resolve().then(function () { return checkboxField_component; }).then((m) => m.CheckboxFieldRenderer));
13378
14214
  registry.register('date', () => Promise.resolve().then(function () { return dateField_component; }).then((m) => m.DateFieldRenderer));
13379
14215
  registry.register('upload', () => Promise.resolve().then(function () { return uploadField_component; }).then((m) => m.UploadFieldRenderer));
13380
- registry.register('richText', () => import('./momentumcms-admin-rich-text-field.component-BvpufJs3.mjs').then((m) => m.RichTextFieldRenderer));
14216
+ registry.register('richText', () => import('./momentumcms-admin-rich-text-field.component-BVAQkX3O.mjs').then((m) => m.RichTextFieldRenderer));
13381
14217
  // Layout field renderers (support nested field rendering)
13382
- registry.register('group', () => import('./momentumcms-admin-group-field.component-ffsgbC6o.mjs').then((m) => m.GroupFieldRenderer));
13383
- registry.register('array', () => import('./momentumcms-admin-array-field.component-CLV4Ny9t.mjs').then((m) => m.ArrayFieldRenderer));
13384
- registry.register('blocks', () => import('./momentumcms-admin-blocks-field.component-hHiTfUf9.mjs').then((m) => m.BlocksFieldRenderer));
14218
+ registry.register('group', () => import('./momentumcms-admin-group-field.component-CMKcqfjy.mjs').then((m) => m.GroupFieldRenderer));
14219
+ registry.register('array', () => import('./momentumcms-admin-array-field.component-DH6vaHO-.mjs').then((m) => m.ArrayFieldRenderer));
14220
+ registry.register('blocks', () => import('./momentumcms-admin-blocks-field.component-BxJRfiV3.mjs').then((m) => m.BlocksFieldRenderer));
13385
14221
  // Visual block editor variant (blocks field with admin.editor === 'visual')
13386
14222
  registry.register('blocks-visual', () => Promise.resolve().then(function () { return visualBlockEditor_component; }).then((m) => m.VisualBlockEditorComponent));
13387
- registry.register('relationship', () => import('./momentumcms-admin-relationship-field.component-DO0kyAkE.mjs').then((m) => m.RelationshipFieldRenderer));
14223
+ registry.register('relationship', () => import('./momentumcms-admin-relationship-field.component-DNZUCENa.mjs').then((m) => m.RelationshipFieldRenderer));
13388
14224
  // Layout-only renderers (tabs, collapsible, row)
13389
- registry.register('tabs', () => import('./momentumcms-admin-tabs-field.component-Uatoyjg8.mjs').then((m) => m.TabsFieldRenderer));
13390
- registry.register('collapsible', () => import('./momentumcms-admin-collapsible-field.component-BeskwGvi.mjs').then((m) => m.CollapsibleFieldRenderer));
13391
- registry.register('row', () => import('./momentumcms-admin-row-field.component-C8ZsdA2w.mjs').then((m) => m.RowFieldRenderer));
14225
+ registry.register('tabs', () => import('./momentumcms-admin-tabs-field.component-qYlbl8Ud.mjs').then((m) => m.TabsFieldRenderer));
14226
+ registry.register('collapsible', () => import('./momentumcms-admin-collapsible-field.component-CsjYCkGw.mjs').then((m) => m.CollapsibleFieldRenderer));
14227
+ registry.register('row', () => import('./momentumcms-admin-row-field.component-0F6cnUK_.mjs').then((m) => m.RowFieldRenderer));
13392
14228
  };
13393
14229
  },
13394
14230
  },
@@ -13515,8 +14351,8 @@ class TextFieldRenderer {
13515
14351
  if (state)
13516
14352
  state.markAsTouched();
13517
14353
  }
13518
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: TextFieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
13519
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: TextFieldRenderer, isStandalone: true, selector: "mcms-text-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
14354
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: TextFieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
14355
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: TextFieldRenderer, isStandalone: true, selector: "mcms-text-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
13520
14356
  <mcms-form-field
13521
14357
  [id]="fieldId()"
13522
14358
  [required]="required()"
@@ -13570,7 +14406,7 @@ class TextFieldRenderer {
13570
14406
  </mcms-form-field>
13571
14407
  `, isInline: true, dependencies: [{ kind: "component", type: McmsFormField, selector: "mcms-form-field", inputs: ["id", "required", "disabled", "errors", "hint", "hasLabel"] }, { kind: "component", type: Input, selector: "mcms-input", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "type", "id", "name", "placeholder", "autocomplete", "ariaLabel", "describedBy", "min", "max", "step"], outputs: ["valueChange", "blurred"] }, { kind: "component", type: Textarea, selector: "mcms-textarea", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "id", "name", "placeholder", "rows", "ariaLabel", "describedBy"], outputs: ["valueChange", "blurred"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
13572
14408
  }
13573
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: TextFieldRenderer, decorators: [{
14409
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: TextFieldRenderer, decorators: [{
13574
14410
  type: Component,
13575
14411
  args: [{
13576
14412
  selector: 'mcms-text-field-renderer',
@@ -13741,8 +14577,8 @@ class NumberFieldRenderer {
13741
14577
  if (state)
13742
14578
  state.markAsTouched();
13743
14579
  }
13744
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NumberFieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
13745
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: NumberFieldRenderer, isStandalone: true, selector: "mcms-number-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
14580
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: NumberFieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
14581
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: NumberFieldRenderer, isStandalone: true, selector: "mcms-number-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
13746
14582
  <mcms-form-field
13747
14583
  [id]="fieldId()"
13748
14584
  [required]="required()"
@@ -13769,7 +14605,7 @@ class NumberFieldRenderer {
13769
14605
  </mcms-form-field>
13770
14606
  `, isInline: true, dependencies: [{ kind: "component", type: McmsFormField, selector: "mcms-form-field", inputs: ["id", "required", "disabled", "errors", "hint", "hasLabel"] }, { kind: "component", type: Input, selector: "mcms-input", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "type", "id", "name", "placeholder", "autocomplete", "ariaLabel", "describedBy", "min", "max", "step"], outputs: ["valueChange", "blurred"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
13771
14607
  }
13772
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: NumberFieldRenderer, decorators: [{
14608
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: NumberFieldRenderer, decorators: [{
13773
14609
  type: Component,
13774
14610
  args: [{
13775
14611
  selector: 'mcms-number-field-renderer',
@@ -13875,8 +14711,8 @@ class SelectFieldRenderer {
13875
14711
  state.value.set(value || null);
13876
14712
  state.markAsTouched();
13877
14713
  }
13878
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SelectFieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
13879
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: SelectFieldRenderer, isStandalone: true, selector: "mcms-select-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
14714
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SelectFieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
14715
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.0", type: SelectFieldRenderer, isStandalone: true, selector: "mcms-select-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
13880
14716
  <mcms-form-field
13881
14717
  [id]="fieldId()"
13882
14718
  [required]="required()"
@@ -13896,7 +14732,7 @@ class SelectFieldRenderer {
13896
14732
  </mcms-form-field>
13897
14733
  `, isInline: true, dependencies: [{ kind: "component", type: McmsFormField, selector: "mcms-form-field", inputs: ["id", "required", "disabled", "errors", "hint", "hasLabel"] }, { kind: "component", type: Select, selector: "mcms-select", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "id", "name", "placeholder", "options", "describedBy", "ariaLabel"], outputs: ["valueChange", "blurred"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
13898
14734
  }
13899
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SelectFieldRenderer, decorators: [{
14735
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SelectFieldRenderer, decorators: [{
13900
14736
  type: Component,
13901
14737
  args: [{
13902
14738
  selector: 'mcms-select-field-renderer',
@@ -13984,8 +14820,8 @@ class CheckboxFieldRenderer {
13984
14820
  state.value.set(value);
13985
14821
  state.markAsTouched();
13986
14822
  }
13987
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CheckboxFieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
13988
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: CheckboxFieldRenderer, isStandalone: true, selector: "mcms-checkbox-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
14823
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CheckboxFieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
14824
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: CheckboxFieldRenderer, isStandalone: true, selector: "mcms-checkbox-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
13989
14825
  <mcms-form-field [id]="fieldId()" [hasLabel]="false" [errors]="touchedErrors()">
13990
14826
  <mcms-checkbox
13991
14827
  [id]="fieldId()"
@@ -14005,7 +14841,7 @@ class CheckboxFieldRenderer {
14005
14841
  </mcms-form-field>
14006
14842
  `, isInline: true, dependencies: [{ kind: "component", type: McmsFormField, selector: "mcms-form-field", inputs: ["id", "required", "disabled", "errors", "hint", "hasLabel"] }, { kind: "component", type: Checkbox, selector: "mcms-checkbox", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "id", "describedBy", "indeterminate", "ariaLabel"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
14007
14843
  }
14008
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: CheckboxFieldRenderer, decorators: [{
14844
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: CheckboxFieldRenderer, decorators: [{
14009
14845
  type: Component,
14010
14846
  args: [{
14011
14847
  selector: 'mcms-checkbox-field-renderer',
@@ -14129,8 +14965,8 @@ class DateFieldRenderer {
14129
14965
  if (state)
14130
14966
  state.markAsTouched();
14131
14967
  }
14132
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: DateFieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
14133
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.2", type: DateFieldRenderer, isStandalone: true, selector: "mcms-date-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
14968
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DateFieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
14969
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.0", type: DateFieldRenderer, isStandalone: true, selector: "mcms-date-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
14134
14970
  <mcms-form-field
14135
14971
  [id]="fieldId()"
14136
14972
  [required]="required()"
@@ -14151,7 +14987,7 @@ class DateFieldRenderer {
14151
14987
  </mcms-form-field>
14152
14988
  `, isInline: true, dependencies: [{ kind: "component", type: McmsFormField, selector: "mcms-form-field", inputs: ["id", "required", "disabled", "errors", "hint", "hasLabel"] }, { kind: "component", type: Input, selector: "mcms-input", inputs: ["value", "disabled", "errors", "touched", "invalid", "readonly", "required", "type", "id", "name", "placeholder", "autocomplete", "ariaLabel", "describedBy", "min", "max", "step"], outputs: ["valueChange", "blurred"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
14153
14989
  }
14154
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: DateFieldRenderer, decorators: [{
14990
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: DateFieldRenderer, decorators: [{
14155
14991
  type: Component,
14156
14992
  args: [{
14157
14993
  selector: 'mcms-date-field-renderer',
@@ -14317,8 +15153,8 @@ class MediaPickerDialog {
14317
15153
  this.dialogRef.close({ media: selected });
14318
15154
  }
14319
15155
  }
14320
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MediaPickerDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
14321
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: MediaPickerDialog, isStandalone: true, selector: "mcms-media-picker-dialog", ngImport: i0, template: `
15156
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MediaPickerDialog, deps: [], target: i0.ɵɵFactoryTarget.Component });
15157
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: MediaPickerDialog, isStandalone: true, selector: "mcms-media-picker-dialog", ngImport: i0, template: `
14322
15158
  <mcms-dialog>
14323
15159
  <mcms-dialog-header>
14324
15160
  <mcms-dialog-title>Select Media</mcms-dialog-title>
@@ -14403,7 +15239,7 @@ class MediaPickerDialog {
14403
15239
  </mcms-dialog>
14404
15240
  `, isInline: true, dependencies: [{ kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Dialog, selector: "mcms-dialog", inputs: ["class"] }, { kind: "component", type: DialogHeader, selector: "mcms-dialog-header" }, { kind: "component", type: DialogTitle, selector: "mcms-dialog-title", inputs: ["id"] }, { kind: "component", type: DialogContent, selector: "mcms-dialog-content" }, { kind: "component", type: DialogFooter, selector: "mcms-dialog-footer" }, { kind: "directive", type: DialogClose, selector: "[mcmsDialogClose]", inputs: ["mcmsDialogClose"] }, { kind: "component", type: Spinner, selector: "mcms-spinner", inputs: ["size", "label", "class"] }, { kind: "component", type: Pagination, selector: "mcms-pagination", inputs: ["currentPage", "totalPages", "siblingCount", "class"], outputs: ["pageChange"] }, { kind: "component", type: MediaPreviewComponent, selector: "mcms-media-preview", inputs: ["media", "size", "class", "rounded"] }, { kind: "component", type: SearchInput, selector: "mcms-search-input", inputs: ["value", "placeholder", "debounce", "disabled", "ariaLabel", "class"], outputs: ["valueChange", "searchChange", "clear"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
14405
15241
  }
14406
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: MediaPickerDialog, decorators: [{
15242
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: MediaPickerDialog, decorators: [{
14407
15243
  type: Component,
14408
15244
  args: [{
14409
15245
  selector: 'mcms-media-picker-dialog',
@@ -14880,8 +15716,8 @@ class UploadFieldRenderer {
14880
15716
  state.value.set(null);
14881
15717
  }
14882
15718
  }
14883
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UploadFieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
14884
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: UploadFieldRenderer, isStandalone: true, selector: "mcms-upload-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "block" }, viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
15719
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: UploadFieldRenderer, deps: [], target: i0.ɵɵFactoryTarget.Component });
15720
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: UploadFieldRenderer, isStandalone: true, selector: "mcms-upload-field-renderer", inputs: { field: { classPropertyName: "field", publicName: "field", isSignal: true, isRequired: true, transformFunction: null }, formNode: { classPropertyName: "formNode", publicName: "formNode", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, path: { classPropertyName: "path", publicName: "path", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "block" }, viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
14885
15721
  <mcms-form-field
14886
15722
  [id]="fieldId()"
14887
15723
  [required]="required()"
@@ -15014,7 +15850,7 @@ class UploadFieldRenderer {
15014
15850
  </mcms-form-field>
15015
15851
  `, isInline: true, dependencies: [{ kind: "component", type: McmsFormField, selector: "mcms-form-field", inputs: ["id", "required", "disabled", "errors", "hint", "hasLabel"] }, { kind: "component", type: Button, selector: "button[mcms-button], a[mcms-button]", inputs: ["variant", "size", "disabled", "loading", "ariaLabel", "class"] }, { kind: "component", type: Progress, selector: "mcms-progress", inputs: ["value", "max", "ariaLabel", "class"] }, { kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "component", type: MediaPreviewComponent, selector: "mcms-media-preview", inputs: ["media", "size", "class", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
15016
15852
  }
15017
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: UploadFieldRenderer, decorators: [{
15853
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: UploadFieldRenderer, decorators: [{
15018
15854
  type: Component,
15019
15855
  args: [{
15020
15856
  selector: 'mcms-upload-field-renderer',
@@ -15168,4 +16004,4 @@ var uploadField_component = /*#__PURE__*/Object.freeze({
15168
16004
  */
15169
16005
 
15170
16006
  export { adminGuard as $, AdminShellComponent as A, BlockEditDialog as B, CheckboxFieldRenderer as C, DashboardPage as D, EntityFormWidget as E, FieldRenderer as F, MediaLibraryPage as G, MediaPickerDialog as H, MediaPreviewComponent as I, MomentumApiService as J, MomentumAuthService as K, LivePreviewComponent as L, MOMENTUM_API as M, NumberFieldRenderer as N, ResetPasswordPage as O, PublishControlsWidget as P, SKIP_AUTO_TOAST as Q, ResetPasswordFormComponent as R, SHEET_QUERY_PARAMS as S, SelectFieldRenderer as T, SetupPage as U, TextFieldRenderer as V, UploadFieldRenderer as W, UploadService as X, VersionHistoryWidget as Y, VersionService as Z, VisualBlockEditorComponent as _, getFieldNodeState as a, authGuard as a0, collectionAccessGuard as a1, crudToastInterceptor as a2, guestGuard as a3, injectHasAnyRole as a4, injectHasRole as a5, injectIsAdmin as a6, injectIsAuthenticated as a7, injectMomentumAPI as a8, injectTypedMomentumAPI as a9, injectUser as aa, injectUserRole as ab, injectVersionService as ac, momentumAdminRoutes as ad, provideFieldRenderer as ae, provideMomentumAPI as af, provideMomentumFieldRenderers as ag, setupGuard as ah, unsavedChangesGuard as ai, getSubNode as b, getFieldDefaultValue as c, EntitySheetService as d, getTitleField as e, AdminSidebarWidget as f, getGlobalsFromRouteData as g, BlockInserterComponent as h, isRecord as i, BlockWrapperComponent as j, CollectionAccessService as k, CollectionCardWidget as l, CollectionEditPage as m, normalizeBlockDefaults as n, CollectionListPage as o, CollectionViewPage as p, DateFieldRenderer as q, EntityListWidget as r, EntityViewWidget as s, FeedbackService as t, FieldRendererRegistry as u, ForgotPasswordFormComponent as v, ForgotPasswordPage as w, LoginPage as x, MOMENTUM_API_CONTEXT as y, McmsThemeService as z };
15171
- //# sourceMappingURL=momentumcms-admin-momentumcms-admin-De5FLr2L.mjs.map
16007
+ //# sourceMappingURL=momentumcms-admin-momentumcms-admin-BTZEdMNj.mjs.map