@dotcms/angular 0.0.1-beta.14 → 0.0.1-beta.15

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 (45) hide show
  1. package/esm2022/next/components/dotcms-editable-text/dotcms-editable-text.component.mjs +1 -1
  2. package/esm2022/next/components/dotcms-layout-body/components/column/column.component.mjs +45 -0
  3. package/esm2022/next/components/dotcms-layout-body/components/container/components/container-not-found/container-not-found.component.mjs +52 -0
  4. package/esm2022/next/components/dotcms-layout-body/components/container/components/empty-container/empty-container.component.mjs +43 -0
  5. package/esm2022/next/components/dotcms-layout-body/components/container/container.component.mjs +99 -0
  6. package/esm2022/next/components/dotcms-layout-body/components/contentlet/contentlet.component.mjs +145 -0
  7. package/esm2022/next/components/dotcms-layout-body/components/fallback-component/fallback-component.component.mjs +47 -0
  8. package/esm2022/next/components/dotcms-layout-body/components/page-error-message/page-error-message.component.mjs +55 -0
  9. package/esm2022/next/components/dotcms-layout-body/components/row/row.component.mjs +46 -0
  10. package/esm2022/next/components/dotcms-layout-body/dotcms-layout-body.component.mjs +69 -0
  11. package/esm2022/next/models/index.mjs +2 -2
  12. package/esm2022/next/public_api.mjs +2 -1
  13. package/esm2022/next/store/dotcms.store.mjs +61 -0
  14. package/fesm2022/dotcms-angular-next.mjs +620 -3
  15. package/fesm2022/dotcms-angular-next.mjs.map +1 -1
  16. package/next/components/dotcms-editable-text/dotcms-editable-text.component.d.ts +1 -1
  17. package/next/components/dotcms-editable-text/dotcms-editable-text.component.d.ts.map +1 -1
  18. package/next/components/dotcms-layout-body/components/column/column.component.d.ts +21 -0
  19. package/next/components/dotcms-layout-body/components/column/column.component.d.ts.map +1 -0
  20. package/next/components/dotcms-layout-body/components/container/components/container-not-found/container-not-found.component.d.ts +27 -0
  21. package/next/components/dotcms-layout-body/components/container/components/container-not-found/container-not-found.component.d.ts.map +1 -0
  22. package/next/components/dotcms-layout-body/components/container/components/empty-container/empty-container.component.d.ts +23 -0
  23. package/next/components/dotcms-layout-body/components/container/components/empty-container/empty-container.component.d.ts.map +1 -0
  24. package/next/components/dotcms-layout-body/components/container/container.component.d.ts +31 -0
  25. package/next/components/dotcms-layout-body/components/container/container.component.d.ts.map +1 -0
  26. package/next/components/dotcms-layout-body/components/contentlet/contentlet.component.d.ts +47 -0
  27. package/next/components/dotcms-layout-body/components/contentlet/contentlet.component.d.ts.map +1 -0
  28. package/next/components/dotcms-layout-body/components/fallback-component/fallback-component.component.d.ts +16 -0
  29. package/next/components/dotcms-layout-body/components/fallback-component/fallback-component.component.d.ts.map +1 -0
  30. package/next/components/dotcms-layout-body/components/page-error-message/page-error-message.component.d.ts +13 -0
  31. package/next/components/dotcms-layout-body/components/page-error-message/page-error-message.component.d.ts.map +1 -0
  32. package/next/components/dotcms-layout-body/components/row/row.component.d.ts +22 -0
  33. package/next/components/dotcms-layout-body/components/row/row.component.d.ts.map +1 -0
  34. package/next/components/dotcms-layout-body/dotcms-layout-body.component.d.ts +30 -0
  35. package/next/components/dotcms-layout-body/dotcms-layout-body.component.d.ts.map +1 -0
  36. package/next/models/index.d.ts +9 -10
  37. package/next/models/index.d.ts.map +1 -1
  38. package/next/public_api.d.ts +1 -0
  39. package/next/public_api.d.ts.map +1 -1
  40. package/next/store/dotcms.store.d.ts +36 -0
  41. package/next/store/dotcms.store.d.ts.map +1 -0
  42. package/package.json +3 -3
  43. package/esm2022/next/models/dotcms.model.mjs +0 -3
  44. package/next/models/dotcms.model.d.ts +0 -416
  45. package/next/models/dotcms.model.d.ts.map +0 -1
@@ -1,11 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ViewContainerRef, TemplateRef, Directive, Input, Renderer2, ElementRef, SecurityContext, Component, ViewChild, HostListener } from '@angular/core';
2
+ import { inject, ViewContainerRef, TemplateRef, Directive, Input, Renderer2, ElementRef, SecurityContext, Component, ViewChild, HostListener, ChangeDetectionStrategy, signal, computed, Injectable, HostBinding } from '@angular/core';
3
3
  import { getUVEState } from '@dotcms/uve';
4
4
  import { UVE_MODE } from '@dotcms/uve/types';
5
- import { IMAGE_LOADER } from '@angular/common';
5
+ import { IMAGE_LOADER, NgStyle, AsyncPipe, NgComponentOutlet } from '@angular/common';
6
6
  import { TINYMCE_SCRIPT_SRC, EditorComponent } from '@tinymce/tinymce-angular';
7
7
  import { DomSanitizer } from '@angular/platform-browser';
8
8
  import { NOTIFY_CLIENT, isInsideEditor, DotCmsClient, postMessageToEditor, CLIENT_ACTIONS } from '@dotcms/client';
9
+ import { PRODUCTION_MODE, DEVELOPMENT_MODE, EMPTY_CONTAINER_STYLE_ANGULAR, getDotContentletAttributes, CUSTOM_NO_COMPONENT, getDotContainerAttributes, getContainersData, getContentletsInContainer, getColumnPositionClasses, combineClasses } from '@dotcms/uve/internal';
9
10
 
10
11
  /**
11
12
  * Directive to show a template when the UVE is in a specific mode.
@@ -387,9 +388,625 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImpor
387
388
  args: ['window:message', ['$event']]
388
389
  }] } });
389
390
 
391
+ /**
392
+ * @description This component is used to display a message when a page is missing the required `layout.body` property.
393
+ * @internal
394
+ * @class PageErrorMessageComponent
395
+ */
396
+ class PageErrorMessageComponent {
397
+ ngOnInit() {
398
+ console.warn('Missing required layout.body property in page');
399
+ }
400
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: PageErrorMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
401
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.3", type: PageErrorMessageComponent, isStandalone: true, selector: "dotcms-page-error-message", ngImport: i0, template: `
402
+ <div
403
+ data-testid="error-message"
404
+ style="padding: 1rem; border: 1px solid #e0e0e0; border-radius: 4px;">
405
+ <p style="margin: 0 0 0.5rem; color: #666;">
406
+ The
407
+ <code>page</code>
408
+ is missing the required
409
+ <code>layout.body</code>
410
+ property.
411
+ </p>
412
+ <p style="margin: 0; color: #666;">
413
+ Make sure the page asset is properly loaded and includes a layout configuration.
414
+ </p>
415
+ </div>
416
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
417
+ }
418
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: PageErrorMessageComponent, decorators: [{
419
+ type: Component,
420
+ args: [{
421
+ selector: 'dotcms-page-error-message',
422
+ standalone: true,
423
+ imports: [],
424
+ template: `
425
+ <div
426
+ data-testid="error-message"
427
+ style="padding: 1rem; border: 1px solid #e0e0e0; border-radius: 4px;">
428
+ <p style="margin: 0 0 0.5rem; color: #666;">
429
+ The
430
+ <code>page</code>
431
+ is missing the required
432
+ <code>layout.body</code>
433
+ property.
434
+ </p>
435
+ <p style="margin: 0; color: #666;">
436
+ Make sure the page asset is properly loaded and includes a layout configuration.
437
+ </p>
438
+ </div>
439
+ `,
440
+ changeDetection: ChangeDetectionStrategy.OnPush
441
+ }]
442
+ }] });
443
+
444
+ const EMPTY_DOTCMS_PAGE_STORE = {
445
+ page: {},
446
+ components: {},
447
+ mode: PRODUCTION_MODE
448
+ };
449
+ /**
450
+ * @description This service is responsible for managing the page context.
451
+ * @internal
452
+ * @author dotCMS
453
+ * @export
454
+ * @class DotCMSStore
455
+ */
456
+ class DotCMSStore {
457
+ constructor() {
458
+ this.$store = signal(EMPTY_DOTCMS_PAGE_STORE);
459
+ /**
460
+ * @description Get if the current context is in development mode
461
+ * @readonly
462
+ * @type {boolean}
463
+ * @memberof DotCMSStore
464
+ */
465
+ this.$isDevMode = computed(() => {
466
+ const uveState = getUVEState();
467
+ if (uveState?.mode) {
468
+ return uveState?.mode === UVE_MODE.EDIT;
469
+ }
470
+ return this.$store()?.mode === DEVELOPMENT_MODE;
471
+ });
472
+ }
473
+ /**
474
+ * @description Get the store
475
+ * @readonly
476
+ * @type {DotCMSPageStore}
477
+ * @memberof DotCMSStore
478
+ */
479
+ get store() {
480
+ return this.$store();
481
+ }
482
+ /**
483
+ * @description Set the store
484
+ * @param {DotCMSPageStore} value
485
+ * @memberof DotCMSStore
486
+ */
487
+ setStore(store) {
488
+ this.$store.set(store);
489
+ }
490
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
491
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSStore, providedIn: 'root' }); }
492
+ }
493
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSStore, decorators: [{
494
+ type: Injectable,
495
+ args: [{
496
+ providedIn: 'root'
497
+ }]
498
+ }] });
499
+
500
+ /**
501
+ * @description This component is used to display a message when a container is not found.
502
+ * @export
503
+ * @internal
504
+ * @class ContainerNotFoundComponent
505
+ * @implements {OnInit}
506
+ */
507
+ class ContainerNotFoundComponent {
508
+ constructor() {
509
+ this.identifier = 'unknown';
510
+ this.#dotcmsContextService = inject(DotCMSStore);
511
+ this.$isDevMode = this.#dotcmsContextService.$isDevMode;
512
+ this.emptyContainerStyle = EMPTY_CONTAINER_STYLE_ANGULAR;
513
+ }
514
+ #dotcmsContextService;
515
+ ngOnInit() {
516
+ if (this.$isDevMode()) {
517
+ console.error(`Container with identifier ${this.identifier} not found`);
518
+ }
519
+ }
520
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContainerNotFoundComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
521
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: ContainerNotFoundComponent, isStandalone: true, selector: "dotcms-container-not-found", inputs: { identifier: "identifier" }, ngImport: i0, template: `
522
+ @if ($isDevMode()) {
523
+ <div [attr.data-testid]="'container-not-found'" [ngStyle]="emptyContainerStyle">
524
+ This container with identifier {{ identifier }} was not found.
525
+ </div>
526
+ }
527
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
528
+ }
529
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContainerNotFoundComponent, decorators: [{
530
+ type: Component,
531
+ args: [{
532
+ selector: 'dotcms-container-not-found',
533
+ standalone: true,
534
+ imports: [NgStyle],
535
+ template: `
536
+ @if ($isDevMode()) {
537
+ <div [attr.data-testid]="'container-not-found'" [ngStyle]="emptyContainerStyle">
538
+ This container with identifier {{ identifier }} was not found.
539
+ </div>
540
+ }
541
+ `
542
+ }]
543
+ }], propDecorators: { identifier: [{
544
+ type: Input
545
+ }] } });
546
+
547
+ /**
548
+ * @description This component is used to display a message when a container is empty.
549
+ * @export
550
+ * @internal
551
+ * @class EmptyContainerComponent
552
+ */
553
+ class EmptyContainerComponent {
554
+ constructor() {
555
+ this.emptyContainerStyle = EMPTY_CONTAINER_STYLE_ANGULAR;
556
+ this.#dotCMSStore = inject(DotCMSStore);
557
+ this.$isDevMode = this.#dotCMSStore.$isDevMode;
558
+ }
559
+ #dotCMSStore;
560
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: EmptyContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
561
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: EmptyContainerComponent, isStandalone: true, selector: "dotcms-empty-container", ngImport: i0, template: `
562
+ @if ($isDevMode()) {
563
+ <div [ngStyle]="emptyContainerStyle" data-testid="empty-container">
564
+ <span data-testid="empty-container-message">This container is empty.</span>
565
+ </div>
566
+ }
567
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] }); }
568
+ }
569
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: EmptyContainerComponent, decorators: [{
570
+ type: Component,
571
+ args: [{
572
+ selector: 'dotcms-empty-container',
573
+ standalone: true,
574
+ imports: [NgStyle],
575
+ template: `
576
+ @if ($isDevMode()) {
577
+ <div [ngStyle]="emptyContainerStyle" data-testid="empty-container">
578
+ <span data-testid="empty-container-message">This container is empty.</span>
579
+ </div>
580
+ }
581
+ `
582
+ }]
583
+ }] });
584
+
585
+ /**
586
+ * @description Fallback component that renders when no custom component is found for a contentlet
587
+ * @category Components
588
+ * @internal
589
+ * @class FallbackComponent
590
+ */
591
+ class FallbackComponent {
592
+ constructor() {
593
+ this.UserNoComponent = null;
594
+ }
595
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: FallbackComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
596
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: FallbackComponent, isStandalone: true, selector: "dotcms-fallback-component", inputs: { UserNoComponent: "UserNoComponent", contentlet: "contentlet" }, ngImport: i0, template: `
597
+ @if (UserNoComponent) {
598
+ <ng-container *ngComponentOutlet="UserNoComponent | async; inputs: { contentlet }" />
599
+ } @else {
600
+ <div data-testid="dotcms-fallback-component">
601
+ <p>No component found for content type: {{ contentlet.contentType }}</p>
602
+ </div>
603
+ }
604
+ `, isInline: true, dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
605
+ }
606
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: FallbackComponent, decorators: [{
607
+ type: Component,
608
+ args: [{
609
+ selector: 'dotcms-fallback-component',
610
+ standalone: true,
611
+ imports: [AsyncPipe, NgComponentOutlet],
612
+ template: `
613
+ @if (UserNoComponent) {
614
+ <ng-container *ngComponentOutlet="UserNoComponent | async; inputs: { contentlet }" />
615
+ } @else {
616
+ <div data-testid="dotcms-fallback-component">
617
+ <p>No component found for content type: {{ contentlet.contentType }}</p>
618
+ </div>
619
+ }
620
+ `,
621
+ changeDetection: ChangeDetectionStrategy.OnPush
622
+ }]
623
+ }], propDecorators: { UserNoComponent: [{
624
+ type: Input
625
+ }], contentlet: [{
626
+ type: Input
627
+ }] } });
628
+
629
+ /**
630
+ * @description Contentlet component that renders DotCMS content with development mode support
631
+ *
632
+ * @component
633
+ * @param {DotCMSContentlet} contentlet - The contentlet to be rendered
634
+ * @param {string} container - The container identifier
635
+ * @class ContentletComponent
636
+ */
637
+ class ContentletComponent {
638
+ constructor() {
639
+ this.dotObject = 'contentlet';
640
+ this.#dotCMSStore = inject(DotCMSStore);
641
+ this.$contentlet = signal(null);
642
+ this.$UserComponent = signal(null);
643
+ this.$UserNoComponent = signal(null);
644
+ this.$isDevMode = this.#dotCMSStore.$isDevMode;
645
+ this.$haveContent = signal(false);
646
+ this.$style = computed(() => this.$isDevMode() && !this.$haveContent() ? { minHeight: '4rem' } : {});
647
+ this.$dotAttributes = computed(() => {
648
+ const contentlet = this.$contentlet();
649
+ if (!contentlet || !this.$isDevMode())
650
+ return {};
651
+ return getDotContentletAttributes(contentlet, this.container);
652
+ });
653
+ this.identifier = null;
654
+ this.basetype = null;
655
+ this.title = null;
656
+ this.inode = null;
657
+ this.type = null;
658
+ this.containerAttribute = null;
659
+ this.onNumberOfPages = null;
660
+ this.styleAttribute = null;
661
+ }
662
+ #dotCMSStore;
663
+ ngOnChanges() {
664
+ this.$contentlet.set(this.contentlet);
665
+ this.setupComponents();
666
+ this.identifier = this.$dotAttributes()['data-dot-identifier'];
667
+ this.basetype = this.$dotAttributes()['data-dot-basetype'];
668
+ this.title = this.$dotAttributes()['data-dot-title'];
669
+ this.inode = this.$dotAttributes()['data-dot-inode'];
670
+ this.type = this.$dotAttributes()['data-dot-type'];
671
+ this.containerAttribute = this.$dotAttributes()['data-dot-container'];
672
+ this.onNumberOfPages = this.$dotAttributes()['data-dot-on-number-of-pages'];
673
+ this.styleAttribute = this.$style();
674
+ }
675
+ ngAfterViewInit() {
676
+ this.checkContent();
677
+ }
678
+ setupComponents() {
679
+ const store = this.#dotCMSStore.store;
680
+ if (!store)
681
+ return;
682
+ if (!store?.components)
683
+ return;
684
+ this.$UserComponent.set(store.components[this.contentlet?.contentType]);
685
+ this.$UserNoComponent.set(store.components[CUSTOM_NO_COMPONENT]);
686
+ }
687
+ checkContent() {
688
+ const element = this.contentletRef?.nativeElement;
689
+ if (element) {
690
+ const hasContent = element.getBoundingClientRect().height > 0;
691
+ this.$haveContent.set(hasContent);
692
+ }
693
+ }
694
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContentletComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
695
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: ContentletComponent, isStandalone: true, selector: "dotcms-contentlet", inputs: { contentlet: "contentlet", container: "container" }, host: { properties: { "attr.data-dot-object": "this.dotObject", "attr.data-dot-identifier": "this.identifier", "attr.data-dot-basetype": "this.basetype", "attr.data-dot-title": "this.title", "attr.data-dot-inode": "this.inode", "attr.data-dot-type": "this.type", "attr.data-dot-container": "this.containerAttribute", "attr.data-dot-on-number-of-pages": "this.onNumberOfPages", "style": "this.styleAttribute" } }, viewQueries: [{ propertyName: "contentletRef", first: true, predicate: ["contentletRef"], descendants: true }], usesOnChanges: true, ngImport: i0, template: `
696
+ @if ($UserComponent()) {
697
+ <ng-container
698
+ *ngComponentOutlet="
699
+ $UserComponent() | async;
700
+ inputs: { contentlet: $contentlet() ?? contentlet }
701
+ " />
702
+ } @else if ($UserNoComponent() && $isDevMode()) {
703
+ <dotcms-fallback-component
704
+ [UserNoComponent]="$UserNoComponent()"
705
+ [contentlet]="$contentlet() ?? contentlet" />
706
+ }
707
+ `, isInline: true, dependencies: [{ kind: "component", type: FallbackComponent, selector: "dotcms-fallback-component", inputs: ["UserNoComponent", "contentlet"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
708
+ }
709
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContentletComponent, decorators: [{
710
+ type: Component,
711
+ args: [{
712
+ selector: 'dotcms-contentlet',
713
+ standalone: true,
714
+ imports: [FallbackComponent, AsyncPipe, NgComponentOutlet],
715
+ template: `
716
+ @if ($UserComponent()) {
717
+ <ng-container
718
+ *ngComponentOutlet="
719
+ $UserComponent() | async;
720
+ inputs: { contentlet: $contentlet() ?? contentlet }
721
+ " />
722
+ } @else if ($UserNoComponent() && $isDevMode()) {
723
+ <dotcms-fallback-component
724
+ [UserNoComponent]="$UserNoComponent()"
725
+ [contentlet]="$contentlet() ?? contentlet" />
726
+ }
727
+ `,
728
+ changeDetection: ChangeDetectionStrategy.OnPush
729
+ }]
730
+ }], propDecorators: { contentlet: [{
731
+ type: Input,
732
+ args: [{ required: true }]
733
+ }], container: [{
734
+ type: Input,
735
+ args: [{ required: true }]
736
+ }], contentletRef: [{
737
+ type: ViewChild,
738
+ args: ['contentletRef']
739
+ }], dotObject: [{
740
+ type: HostBinding,
741
+ args: ['attr.data-dot-object']
742
+ }], identifier: [{
743
+ type: HostBinding,
744
+ args: ['attr.data-dot-identifier']
745
+ }], basetype: [{
746
+ type: HostBinding,
747
+ args: ['attr.data-dot-basetype']
748
+ }], title: [{
749
+ type: HostBinding,
750
+ args: ['attr.data-dot-title']
751
+ }], inode: [{
752
+ type: HostBinding,
753
+ args: ['attr.data-dot-inode']
754
+ }], type: [{
755
+ type: HostBinding,
756
+ args: ['attr.data-dot-type']
757
+ }], containerAttribute: [{
758
+ type: HostBinding,
759
+ args: ['attr.data-dot-container']
760
+ }], onNumberOfPages: [{
761
+ type: HostBinding,
762
+ args: ['attr.data-dot-on-number-of-pages']
763
+ }], styleAttribute: [{
764
+ type: HostBinding,
765
+ args: ['style']
766
+ }] } });
767
+
768
+ /**
769
+ * @description This component renders a container with all its content using the layout provided by dotCMS Page API.
770
+ *
771
+ * @see {@link https://www.dotcms.com/docs/latest/page-rest-api-layout-as-a-service-laas}
772
+ * @category Components
773
+ * @internal
774
+ * @class ContainerComponent
775
+ */
776
+ class ContainerComponent {
777
+ constructor() {
778
+ this.#dotCMSStore = inject(DotCMSStore);
779
+ this.$containerData = signal(null);
780
+ this.$contentlets = signal([]);
781
+ this.$isEmpty = computed(() => this.$contentlets().length === 0);
782
+ this.$dotAttributes = computed(() => {
783
+ const containerData = this.$containerData();
784
+ if (!containerData || !this.#dotCMSStore.$isDevMode()) {
785
+ return {};
786
+ }
787
+ return getDotContainerAttributes(containerData);
788
+ });
789
+ this.dotObject = 'container';
790
+ this.acceptTypes = null;
791
+ this.identifier = null;
792
+ this.maxContentlets = null;
793
+ this.uuid = null;
794
+ }
795
+ #dotCMSStore;
796
+ ngOnChanges() {
797
+ const { page } = this.#dotCMSStore.store ?? {};
798
+ if (!page) {
799
+ return;
800
+ }
801
+ this.$containerData.set(getContainersData(page, this.container));
802
+ this.$contentlets.set(getContentletsInContainer(page, this.container));
803
+ this.acceptTypes = this.$dotAttributes()['data-dot-accept-types'];
804
+ this.identifier = this.$dotAttributes()['data-dot-identifier'];
805
+ this.maxContentlets = this.$dotAttributes()['data-max-contentlets'];
806
+ this.uuid = this.$dotAttributes()['data-dot-uuid'];
807
+ }
808
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
809
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: ContainerComponent, isStandalone: true, selector: "dotcms-container", inputs: { container: "container" }, host: { properties: { "attr.data-dot-object": "this.dotObject", "attr.data-dot-accept-types": "this.acceptTypes", "attr.data-dot-identifier": "this.identifier", "attr.data-max-contentlets": "this.maxContentlets", "attr.data-dot-uuid": "this.uuid" } }, usesOnChanges: true, ngImport: i0, template: `
810
+ @if (!$containerData()) {
811
+ <dotcms-container-not-found [identifier]="container.identifier" />
812
+ } @else if ($isEmpty()) {
813
+ <dotcms-empty-container />
814
+ } @else {
815
+ @for (contentlet of $contentlets(); track contentlet.identifier) {
816
+ <dotcms-contentlet [contentlet]="contentlet" [container]="container.identifier" />
817
+ }
818
+ }
819
+ `, isInline: true, dependencies: [{ kind: "component", type: ContainerNotFoundComponent, selector: "dotcms-container-not-found", inputs: ["identifier"] }, { kind: "component", type: EmptyContainerComponent, selector: "dotcms-empty-container" }, { kind: "component", type: ContentletComponent, selector: "dotcms-contentlet", inputs: ["contentlet", "container"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
820
+ }
821
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ContainerComponent, decorators: [{
822
+ type: Component,
823
+ args: [{
824
+ selector: 'dotcms-container',
825
+ standalone: true,
826
+ imports: [ContainerNotFoundComponent, EmptyContainerComponent, ContentletComponent],
827
+ template: `
828
+ @if (!$containerData()) {
829
+ <dotcms-container-not-found [identifier]="container.identifier" />
830
+ } @else if ($isEmpty()) {
831
+ <dotcms-empty-container />
832
+ } @else {
833
+ @for (contentlet of $contentlets(); track contentlet.identifier) {
834
+ <dotcms-contentlet [contentlet]="contentlet" [container]="container.identifier" />
835
+ }
836
+ }
837
+ `,
838
+ changeDetection: ChangeDetectionStrategy.OnPush
839
+ }]
840
+ }], propDecorators: { container: [{
841
+ type: Input,
842
+ args: [{ required: true }]
843
+ }], dotObject: [{
844
+ type: HostBinding,
845
+ args: ['attr.data-dot-object']
846
+ }], acceptTypes: [{
847
+ type: HostBinding,
848
+ args: ['attr.data-dot-accept-types']
849
+ }], identifier: [{
850
+ type: HostBinding,
851
+ args: ['attr.data-dot-identifier']
852
+ }], maxContentlets: [{
853
+ type: HostBinding,
854
+ args: ['attr.data-max-contentlets']
855
+ }], uuid: [{
856
+ type: HostBinding,
857
+ args: ['attr.data-dot-uuid']
858
+ }] } });
859
+
860
+ /**
861
+ * This component renders a column with all its content using the layout provided by dotCMS Page API.
862
+ *
863
+ * @see {@link https://www.dotcms.com/docs/latest/page-rest-api-layout-as-a-service-laas}
864
+ * @category Components
865
+ * @internal
866
+ */
867
+ class ColumnComponent {
868
+ constructor() {
869
+ this.customClasses = '';
870
+ }
871
+ ngOnChanges() {
872
+ const positionClasses = getColumnPositionClasses(this.column);
873
+ this.customClasses = combineClasses([positionClasses.startClass, positionClasses.endClass]);
874
+ }
875
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ColumnComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
876
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: ColumnComponent, isStandalone: true, selector: "dotcms-column", inputs: { column: "column" }, host: { properties: { "class": "this.customClasses" } }, usesOnChanges: true, ngImport: i0, template: `
877
+ <div [class]="column.styleClass" data-testid="dotcms-column">
878
+ @for (container of column.containers; track $index) {
879
+ <dotcms-container [container]="container" />
880
+ }
881
+ </div>
882
+ `, isInline: true, styles: [":host.col-start-1{grid-column-start:1}:host.col-start-2{grid-column-start:2}:host.col-start-3{grid-column-start:3}:host.col-start-4{grid-column-start:4}:host.col-start-5{grid-column-start:5}:host.col-start-6{grid-column-start:6}:host.col-start-7{grid-column-start:7}:host.col-start-8{grid-column-start:8}:host.col-start-9{grid-column-start:9}:host.col-start-10{grid-column-start:10}:host.col-start-11{grid-column-start:11}:host.col-start-12{grid-column-start:12}:host.col-end-1{grid-column-end:1}:host.col-end-2{grid-column-end:2}:host.col-end-3{grid-column-end:3}:host.col-end-4{grid-column-end:4}:host.col-end-5{grid-column-end:5}:host.col-end-6{grid-column-end:6}:host.col-end-7{grid-column-end:7}:host.col-end-8{grid-column-end:8}:host.col-end-9{grid-column-end:9}:host.col-end-10{grid-column-end:10}:host.col-end-11{grid-column-end:11}:host.col-end-12{grid-column-end:12}:host.col-end-13{grid-column-end:13}\n"], dependencies: [{ kind: "component", type: ContainerComponent, selector: "dotcms-container", inputs: ["container"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
883
+ }
884
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: ColumnComponent, decorators: [{
885
+ type: Component,
886
+ args: [{ selector: 'dotcms-column', standalone: true, imports: [ContainerComponent], template: `
887
+ <div [class]="column.styleClass" data-testid="dotcms-column">
888
+ @for (container of column.containers; track $index) {
889
+ <dotcms-container [container]="container" />
890
+ }
891
+ </div>
892
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host.col-start-1{grid-column-start:1}:host.col-start-2{grid-column-start:2}:host.col-start-3{grid-column-start:3}:host.col-start-4{grid-column-start:4}:host.col-start-5{grid-column-start:5}:host.col-start-6{grid-column-start:6}:host.col-start-7{grid-column-start:7}:host.col-start-8{grid-column-start:8}:host.col-start-9{grid-column-start:9}:host.col-start-10{grid-column-start:10}:host.col-start-11{grid-column-start:11}:host.col-start-12{grid-column-start:12}:host.col-end-1{grid-column-end:1}:host.col-end-2{grid-column-end:2}:host.col-end-3{grid-column-end:3}:host.col-end-4{grid-column-end:4}:host.col-end-5{grid-column-end:5}:host.col-end-6{grid-column-end:6}:host.col-end-7{grid-column-end:7}:host.col-end-8{grid-column-end:8}:host.col-end-9{grid-column-end:9}:host.col-end-10{grid-column-end:10}:host.col-end-11{grid-column-end:11}:host.col-end-12{grid-column-end:12}:host.col-end-13{grid-column-end:13}\n"] }]
893
+ }], propDecorators: { column: [{
894
+ type: Input,
895
+ args: [{ required: true }]
896
+ }], customClasses: [{
897
+ type: HostBinding,
898
+ args: ['class']
899
+ }] } });
900
+
901
+ /**
902
+ * @description This component renders a row with all its content using the layout provided by dotCMS Page API.
903
+ *
904
+ * @see {@link https://www.dotcms.com/docs/latest/page-rest-api-layout-as-a-service-laas}
905
+ * @category Components
906
+ * @internal
907
+ * @class RowComponent
908
+ */
909
+ class RowComponent {
910
+ constructor() {
911
+ this.customClasses = signal('');
912
+ }
913
+ ngOnChanges() {
914
+ this.customClasses.set(combineClasses([this.row.styleClass || 'dot-row']));
915
+ }
916
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: RowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
917
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: RowComponent, isStandalone: true, selector: "dotcms-row", inputs: { row: "row" }, usesOnChanges: true, ngImport: i0, template: `
918
+ <div class="dot-row-container">
919
+ <div [class]="customClasses()" data-dot-object="row" data-testid="dotcms-row">
920
+ @for (column of row.columns; track $index) {
921
+ <dotcms-column [column]="column" />
922
+ }
923
+ </div>
924
+ </div>
925
+ `, isInline: true, styles: [".dot-row{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}\n"], dependencies: [{ kind: "component", type: ColumnComponent, selector: "dotcms-column", inputs: ["column"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
926
+ }
927
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: RowComponent, decorators: [{
928
+ type: Component,
929
+ args: [{ selector: 'dotcms-row', standalone: true, imports: [ColumnComponent], template: `
930
+ <div class="dot-row-container">
931
+ <div [class]="customClasses()" data-dot-object="row" data-testid="dotcms-row">
932
+ @for (column of row.columns; track $index) {
933
+ <dotcms-column [column]="column" />
934
+ }
935
+ </div>
936
+ </div>
937
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".dot-row{display:grid;grid-template-columns:repeat(12,1fr);gap:1rem}\n"] }]
938
+ }], propDecorators: { row: [{
939
+ type: Input,
940
+ args: [{ required: true }]
941
+ }] } });
942
+
943
+ /**
944
+ * @description This component is used to render the layout for a DotCMS page.
945
+ * @param {DotCMSPageAsset} page - The page to render the layout for
946
+ * @param {DotCMSPageComponent} components - The components to render the layout for
947
+ * @param {DotCMSPageRendererMode} mode - The mode to render the layout for
948
+ *
949
+ * @example
950
+ * <dotcms-layout-body [page]="page" [components]="components" [mode]="'development'" />
951
+ *
952
+ * @export
953
+ * @implements {OnChanges}
954
+ * @class DotCMSLayoutBodyComponent
955
+ */
956
+ class DotCMSLayoutBodyComponent {
957
+ constructor() {
958
+ this.components = {};
959
+ this.mode = 'production';
960
+ this.#dotCMSStore = inject(DotCMSStore);
961
+ this.$isDevMode = this.#dotCMSStore.$isDevMode;
962
+ this.$rows = signal([]);
963
+ this.$isEmpty = signal(false);
964
+ }
965
+ #dotCMSStore;
966
+ ngOnChanges() {
967
+ this.#dotCMSStore.setStore({
968
+ page: this.page,
969
+ components: this.components,
970
+ mode: this.mode
971
+ });
972
+ this.$isEmpty.set(!this.page?.layout?.body);
973
+ this.$rows.set(this.page?.layout?.body?.rows ?? []);
974
+ }
975
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSLayoutBodyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
976
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.3", type: DotCMSLayoutBodyComponent, isStandalone: true, selector: "dotcms-layout-body", inputs: { page: "page", components: "components", mode: "mode" }, providers: [DotCMSStore], usesOnChanges: true, ngImport: i0, template: `
977
+ @if ($isEmpty() && $isDevMode()) {
978
+ <dotcms-page-error-message />
979
+ } @else {
980
+ @for (row of $rows(); track row.identifier) {
981
+ <dotcms-row [row]="row" />
982
+ }
983
+ }
984
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: PageErrorMessageComponent, selector: "dotcms-page-error-message" }, { kind: "component", type: RowComponent, selector: "dotcms-row", inputs: ["row"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
985
+ }
986
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.3", ngImport: i0, type: DotCMSLayoutBodyComponent, decorators: [{
987
+ type: Component,
988
+ args: [{ selector: 'dotcms-layout-body', standalone: true, imports: [PageErrorMessageComponent, RowComponent], providers: [DotCMSStore], template: `
989
+ @if ($isEmpty() && $isDevMode()) {
990
+ <dotcms-page-error-message />
991
+ } @else {
992
+ @for (row of $rows(); track row.identifier) {
993
+ <dotcms-row [row]="row" />
994
+ }
995
+ }
996
+ `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}\n"] }]
997
+ }], propDecorators: { page: [{
998
+ type: Input,
999
+ args: [{ required: true }]
1000
+ }], components: [{
1001
+ type: Input,
1002
+ args: [{ required: true }]
1003
+ }], mode: [{
1004
+ type: Input
1005
+ }] } });
1006
+
390
1007
  /**
391
1008
  * Generated bundle index. Do not edit.
392
1009
  */
393
1010
 
394
- export { DotCMSEditableTextComponent, DotCMSShowWhenDirective, provideDotCMSImageLoader };
1011
+ export { DotCMSEditableTextComponent, DotCMSLayoutBodyComponent, DotCMSShowWhenDirective, provideDotCMSImageLoader };
395
1012
  //# sourceMappingURL=dotcms-angular-next.mjs.map