@dotcms/angular 0.0.1-alpha.37 → 0.0.1-alpha.39

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 (81) hide show
  1. package/.eslintrc.json +18 -0
  2. package/README.md +128 -78
  3. package/jest.config.ts +22 -0
  4. package/ng-package.json +7 -0
  5. package/package.json +4 -21
  6. package/project.json +33 -0
  7. package/{index.d.ts → src/index.ts} +0 -1
  8. package/src/lib/components/dot-editable-text/dot-editable-text.component.css +4 -0
  9. package/src/lib/components/dot-editable-text/dot-editable-text.component.html +8 -0
  10. package/src/lib/components/dot-editable-text/dot-editable-text.component.spec.ts +424 -0
  11. package/src/lib/components/dot-editable-text/dot-editable-text.component.ts +269 -0
  12. package/src/lib/components/dot-editable-text/utils.ts +51 -0
  13. package/src/lib/components/no-component/no-component.component.css +3 -0
  14. package/src/lib/components/no-component/no-component.component.spec.ts +24 -0
  15. package/src/lib/components/no-component/no-component.component.ts +31 -0
  16. package/src/lib/layout/column/column.component.css +99 -0
  17. package/src/lib/layout/column/column.component.spec.ts +33 -0
  18. package/src/lib/layout/column/column.component.ts +49 -0
  19. package/src/lib/layout/container/container.component.css +9 -0
  20. package/src/lib/layout/container/container.component.html +26 -0
  21. package/src/lib/layout/container/container.component.spec.ts +205 -0
  22. package/src/lib/layout/container/container.component.ts +140 -0
  23. package/src/lib/layout/contentlet/contentlet.component.spec.ts +22 -0
  24. package/src/lib/layout/contentlet/contentlet.component.ts +101 -0
  25. package/src/lib/layout/dotcms-layout/dotcms-layout.component.css +3 -0
  26. package/src/lib/layout/dotcms-layout/dotcms-layout.component.spec.ts +195 -0
  27. package/src/lib/layout/dotcms-layout/dotcms-layout.component.ts +150 -0
  28. package/src/lib/layout/row/row.component.css +6 -0
  29. package/src/lib/layout/row/row.component.spec.ts +28 -0
  30. package/src/lib/layout/row/row.component.ts +32 -0
  31. package/{lib/models/dotcms.model.d.ts → src/lib/models/dotcms.model.ts} +21 -3
  32. package/src/lib/models/index.ts +47 -0
  33. package/{lib/services/dotcms-context/page-context.service.d.ts → src/lib/services/dotcms-context/page-context.service.ts} +41 -12
  34. package/src/lib/services/dotcms-context/page-context.spec.ts +80 -0
  35. package/src/lib/utils/index.ts +92 -0
  36. package/src/lib/utils/testing.utils.ts +1019 -0
  37. package/src/test-setup.ts +8 -0
  38. package/tsconfig.json +29 -0
  39. package/tsconfig.lib.json +12 -0
  40. package/tsconfig.lib.prod.json +9 -0
  41. package/tsconfig.spec.json +11 -0
  42. package/dotcms-angular.d.ts.map +0 -1
  43. package/esm2022/dotcms-angular.mjs +0 -5
  44. package/esm2022/index.mjs +0 -5
  45. package/esm2022/lib/components/dot-editable-text/dot-editable-text.component.mjs +0 -225
  46. package/esm2022/lib/components/dot-editable-text/utils.mjs +0 -43
  47. package/esm2022/lib/components/no-component/no-component.component.mjs +0 -27
  48. package/esm2022/lib/layout/column/column.component.mjs +0 -33
  49. package/esm2022/lib/layout/container/container.component.mjs +0 -78
  50. package/esm2022/lib/layout/contentlet/contentlet.component.mjs +0 -65
  51. package/esm2022/lib/layout/dotcms-layout/dotcms-layout.component.mjs +0 -87
  52. package/esm2022/lib/layout/row/row.component.mjs +0 -23
  53. package/esm2022/lib/models/dotcms.model.mjs +0 -3
  54. package/esm2022/lib/models/index.mjs +0 -3
  55. package/esm2022/lib/services/dotcms-context/page-context.service.mjs +0 -75
  56. package/esm2022/lib/utils/index.mjs +0 -57
  57. package/fesm2022/dotcms-angular.mjs +0 -697
  58. package/fesm2022/dotcms-angular.mjs.map +0 -1
  59. package/index.d.ts.map +0 -1
  60. package/lib/components/dot-editable-text/dot-editable-text.component.d.ts +0 -129
  61. package/lib/components/dot-editable-text/dot-editable-text.component.d.ts.map +0 -1
  62. package/lib/components/dot-editable-text/utils.d.ts +0 -7
  63. package/lib/components/dot-editable-text/utils.d.ts.map +0 -1
  64. package/lib/components/no-component/no-component.component.d.ts +0 -13
  65. package/lib/components/no-component/no-component.component.d.ts.map +0 -1
  66. package/lib/layout/column/column.component.d.ts +0 -11
  67. package/lib/layout/column/column.component.d.ts.map +0 -1
  68. package/lib/layout/container/container.component.d.ts +0 -34
  69. package/lib/layout/container/container.component.d.ts.map +0 -1
  70. package/lib/layout/contentlet/contentlet.component.d.ts +0 -19
  71. package/lib/layout/contentlet/contentlet.component.d.ts.map +0 -1
  72. package/lib/layout/dotcms-layout/dotcms-layout.component.d.ts +0 -54
  73. package/lib/layout/dotcms-layout/dotcms-layout.component.d.ts.map +0 -1
  74. package/lib/layout/row/row.component.d.ts +0 -8
  75. package/lib/layout/row/row.component.d.ts.map +0 -1
  76. package/lib/models/dotcms.model.d.ts.map +0 -1
  77. package/lib/models/index.d.ts +0 -11
  78. package/lib/models/index.d.ts.map +0 -1
  79. package/lib/services/dotcms-context/page-context.service.d.ts.map +0 -1
  80. package/lib/utils/index.d.ts +0 -49
  81. package/lib/utils/index.d.ts.map +0 -1
@@ -0,0 +1,22 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ContentletComponent } from './contentlet.component';
4
+
5
+ describe('ContentletComponent', () => {
6
+ let component: ContentletComponent;
7
+ let fixture: ComponentFixture<ContentletComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [ContentletComponent]
12
+ }).compileComponents();
13
+
14
+ fixture = TestBed.createComponent(ContentletComponent);
15
+ component = fixture.componentInstance;
16
+ fixture.detectChanges();
17
+ });
18
+
19
+ it('should create', () => {
20
+ expect(component).toBeTruthy();
21
+ });
22
+ });
@@ -0,0 +1,101 @@
1
+ import { ChangeDetectionStrategy, Component, HostBinding, Input, OnChanges } from '@angular/core';
2
+
3
+ import { DotCMSContentlet } from '../../models';
4
+
5
+ /**
6
+ * This component is responsible to display a contentlet.
7
+ *
8
+ * @export
9
+ * @class ContentletComponent
10
+ * @implements {OnChanges}
11
+ */
12
+ @Component({
13
+ selector: 'dotcms-contentlet-wrapper',
14
+ standalone: true,
15
+ template: '<ng-content></ng-content>',
16
+ changeDetection: ChangeDetectionStrategy.OnPush
17
+ })
18
+ export class ContentletComponent implements OnChanges {
19
+ /**
20
+ * The contentlet object containing content data.
21
+ *
22
+ * @type {DotCMSContentlet}
23
+ * @memberof ContentletComponent
24
+ */
25
+ @Input({ required: true }) contentlet!: DotCMSContentlet;
26
+ /**
27
+ * The container data (as string) where the contentlet is located.
28
+ *
29
+ * @type {string}
30
+ * @memberof ContentletComponent
31
+ */
32
+ @Input() container!: string;
33
+
34
+ /**
35
+ * The identifier of contentlet component.
36
+ *
37
+ * @type {(string | null)}
38
+ * @memberof ContentletComponent
39
+ */
40
+ @HostBinding('attr.data-dot-identifier') identifier: string | null = null;
41
+ /**
42
+ * The base type of contentlet component.
43
+ *
44
+ * @type {(string | null)}
45
+ * @memberof ContentletComponent
46
+ */
47
+ @HostBinding('attr.data-dot-basetype') baseType: string | null = null;
48
+ /**
49
+ * The title of contentlet component.
50
+ *
51
+ * @type {(string | null)}
52
+ * @memberof ContentletComponent
53
+ */
54
+ @HostBinding('attr.data-dot-title') title: string | null = null;
55
+ /**
56
+ * The inode of contentlet component.
57
+ *
58
+ * @type {(string | null)}
59
+ * @memberof ContentletComponent
60
+ */
61
+ @HostBinding('attr.data-dot-inode') inode: string | null = null;
62
+ /**
63
+ * The type of contentlet component.
64
+ *
65
+ * @type {(string | null)}
66
+ * @memberof ContentletComponent
67
+ */
68
+ @HostBinding('attr.data-dot-type') dotType: string | null = null;
69
+ /**
70
+ * The container of contentlet component.
71
+ *
72
+ * @type {(string | null)}
73
+ * @memberof ContentletComponent
74
+ */
75
+ @HostBinding('attr.data-dot-container') dotContainer: string | null = null;
76
+ /**
77
+ * The number of pages where the contentlet appears
78
+ *
79
+ * @type {(string | null)}
80
+ * @memberof ContentletComponent
81
+ */
82
+ @HostBinding('attr.data-dot-on-number-of-pages') numberOfPages: string | null = null;
83
+ /**
84
+ * The content of contentlet component.
85
+ *
86
+ * @type {(string | null)}
87
+ * @memberof ContentletComponent
88
+ */
89
+ @HostBinding('attr.data-dot-object') dotContent: string | null = null;
90
+
91
+ ngOnChanges() {
92
+ this.identifier = this.contentlet.identifier;
93
+ this.baseType = this.contentlet.baseType;
94
+ this.title = this.contentlet.title;
95
+ this.inode = this.contentlet.inode;
96
+ this.dotType = this.contentlet.contentType;
97
+ this.dotContainer = this.container;
98
+ this.numberOfPages = this.contentlet['onNumberOfPages'];
99
+ this.dotContent = 'contentlet';
100
+ }
101
+ }
@@ -0,0 +1,3 @@
1
+ :host {
2
+ display: block;
3
+ }
@@ -0,0 +1,195 @@
1
+ import { expect } from '@jest/globals';
2
+ import { Spectator, createRoutingFactory } from '@ngneat/spectator/jest';
3
+ import { MockComponent } from 'ng-mocks';
4
+ import { of } from 'rxjs';
5
+
6
+ import { Component, Input } from '@angular/core';
7
+ import { ActivatedRoute, Router } from '@angular/router';
8
+
9
+ import * as dotcmsClient from '@dotcms/client';
10
+
11
+ import { PageResponseMock, PageResponseOneRowMock } from './../../utils/testing.utils';
12
+ import { DotcmsLayoutComponent } from './dotcms-layout.component';
13
+
14
+ import { DotCMSContentlet, DotCMSPageAsset } from '../../models';
15
+ import { PageContextService } from '../../services/dotcms-context/page-context.service';
16
+ import { RowComponent } from '../row/row.component';
17
+
18
+ interface Callback {
19
+ [key: string]: (data: unknown) => void;
20
+ }
21
+
22
+ interface DotCmsClientMock extends dotcmsClient.DotCmsClient {
23
+ editor: {
24
+ on: (type: string, callbackFn: (data: unknown) => void) => void;
25
+ off: jest.Mock;
26
+ callbacks: Callback;
27
+ };
28
+ }
29
+
30
+ @Component({
31
+ selector: 'dotcms-mock-component',
32
+ standalone: true,
33
+ template: 'Hello world'
34
+ })
35
+ class DotcmsSDKMockComponent {
36
+ @Input() contentlet!: DotCMSContentlet;
37
+ }
38
+
39
+ jest.mock('@dotcms/client', () => ({
40
+ ...jest.requireActual('@dotcms/client'),
41
+ isInsideEditor: jest.fn().mockReturnValue(true),
42
+ initEditor: jest.fn(),
43
+ updateNavigation: jest.fn(),
44
+ postMessageToEditor: jest.fn(),
45
+ DotCmsClient: {
46
+ instance: {
47
+ editor: {
48
+ on: function (type: string, callbackFn: (data: unknown) => void): void {
49
+ this.callbacks[type] = callbackFn;
50
+ },
51
+ off: jest.fn(),
52
+ callbacks: {} as Callback
53
+ }
54
+ }
55
+ },
56
+ CUSTOMER_ACTIONS: {
57
+ GET_PAGE_DATA: 'get-page-data'
58
+ }
59
+ }));
60
+
61
+ const { DotCmsClient } = dotcmsClient as jest.Mocked<typeof dotcmsClient>;
62
+
63
+ describe('DotcmsLayoutComponent', () => {
64
+ let spectator: Spectator<DotcmsLayoutComponent>;
65
+ let pageContextService: PageContextService;
66
+
67
+ const createComponent = createRoutingFactory({
68
+ component: DotcmsLayoutComponent,
69
+ imports: [MockComponent(RowComponent)],
70
+ providers: [
71
+ PageContextService,
72
+ { provide: ActivatedRoute, useValue: { url: of([]) } },
73
+ { provide: Router, useValue: {} }
74
+ ]
75
+ });
76
+
77
+ beforeEach(() => {
78
+ spectator = createComponent({
79
+ props: {
80
+ pageAsset: PageResponseMock as unknown as DotCMSPageAsset,
81
+ components: {
82
+ Banner: Promise.resolve(DotcmsSDKMockComponent)
83
+ }
84
+ },
85
+ detectChanges: false
86
+ });
87
+
88
+ pageContextService = spectator.inject(PageContextService, true);
89
+ });
90
+
91
+ afterEach(() => {
92
+ jest.clearAllMocks();
93
+ });
94
+
95
+ it('should render rows', () => {
96
+ spectator.detectChanges();
97
+ expect(spectator.queryAll(RowComponent).length).toBe(3);
98
+ });
99
+
100
+ it('should save pageContext', () => {
101
+ const setContextSpy = jest.spyOn(pageContextService, 'setContext');
102
+ spectator.detectChanges();
103
+ expect(setContextSpy).toHaveBeenCalled();
104
+ });
105
+
106
+ describe('inside editor', () => {
107
+ it('should call initEditor and updateNavigation from @dotcms/client', () => {
108
+ const initEditorSpy = jest.spyOn(dotcmsClient, 'initEditor');
109
+ const updateNavigationSpy = jest.spyOn(dotcmsClient, 'updateNavigation');
110
+
111
+ spectator.detectChanges();
112
+ expect(initEditorSpy).toHaveBeenCalled();
113
+ expect(updateNavigationSpy).toHaveBeenCalled();
114
+ });
115
+
116
+ describe('onReload', () => {
117
+ const client = DotCmsClient.instance;
118
+ let editorOnSpy: jest.SpyInstance;
119
+
120
+ beforeEach(() => {
121
+ editorOnSpy = jest.spyOn(client.editor, 'on');
122
+ spectator.setInput('onReload', () => {
123
+ /* do nothing */
124
+ });
125
+ spectator.detectChanges();
126
+ });
127
+
128
+ it('should subscribe to the `CHANGE` event', () => {
129
+ expect(editorOnSpy).toHaveBeenCalled();
130
+ });
131
+
132
+ it('should remove listener on unmount', () => {
133
+ spectator.component.ngOnDestroy();
134
+ spectator.detectChanges();
135
+
136
+ expect(client.editor.off).toHaveBeenCalledWith('changes');
137
+ });
138
+ });
139
+
140
+ describe('client is ready', () => {
141
+ const query = { query: 'query { ... }' };
142
+
143
+ beforeEach(() => {
144
+ spectator.setInput('editor', query);
145
+ spectator.detectChanges();
146
+ });
147
+
148
+ it('should post message to editor', () => {
149
+ spectator.detectChanges();
150
+ expect(dotcmsClient.postMessageToEditor).toHaveBeenCalledWith({
151
+ action: dotcmsClient.CUSTOMER_ACTIONS.CLIENT_READY,
152
+ payload: query
153
+ });
154
+ });
155
+ });
156
+
157
+ describe('onChange', () => {
158
+ const client = DotCmsClient.instance;
159
+ beforeEach(() => spectator.detectChanges());
160
+
161
+ it('should update the page asset when changes are made in the editor', () => {
162
+ const editorOnSpy = jest.spyOn(client.editor, 'on');
163
+ expect(editorOnSpy).toHaveBeenCalledWith('changes', expect.any(Function));
164
+ });
165
+ });
166
+ });
167
+
168
+ describe('template', () => {
169
+ beforeEach(() => spectator.detectChanges());
170
+
171
+ it('should render rows', () => {
172
+ expect(spectator.queryAll(RowComponent).length).toBe(3);
173
+ });
174
+
175
+ it('should pass the correct row to RowComponent', () => {
176
+ const rowComponents = spectator.queryAll(RowComponent);
177
+ const rows = PageResponseMock.layout.body.rows;
178
+ expect(rowComponents.length).toBe(rows.length);
179
+
180
+ rowComponents.forEach((component, index) => {
181
+ expect(component.row).toEqual(rows[index]);
182
+ });
183
+ });
184
+
185
+ it('should update the page asset when changes are made in the editor', () => {
186
+ const { editor } = DotCmsClient.instance as DotCmsClientMock;
187
+ editor.callbacks['changes'](PageResponseOneRowMock);
188
+ spectator.detectChanges();
189
+ const rowComponents = spectator.queryAll(RowComponent);
190
+ const rows = PageResponseMock.layout.body.rows;
191
+ expect(rowComponents.length).toBe(1);
192
+ expect(rowComponents[0].row).toEqual(rows[0]);
193
+ });
194
+ });
195
+ });
@@ -0,0 +1,150 @@
1
+ import { AsyncPipe } from '@angular/common';
2
+ import {
3
+ ChangeDetectionStrategy,
4
+ Component,
5
+ DestroyRef,
6
+ Input,
7
+ OnInit,
8
+ inject
9
+ } from '@angular/core';
10
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
11
+ import { ActivatedRoute } from '@angular/router';
12
+
13
+ import {
14
+ CUSTOMER_ACTIONS,
15
+ DotCmsClient,
16
+ EditorConfig,
17
+ initEditor,
18
+ isInsideEditor,
19
+ postMessageToEditor,
20
+ updateNavigation
21
+ } from '@dotcms/client';
22
+
23
+ import { DotCMSPageComponent } from '../../models';
24
+ import { DotCMSPageAsset } from '../../models/dotcms.model';
25
+ import { PageContextService } from '../../services/dotcms-context/page-context.service';
26
+ import { RowComponent } from '../row/row.component';
27
+
28
+ /**
29
+ * `DotcmsLayoutComponent` is a class that represents the layout for a DotCMS page.
30
+ * It includes a `pageAsset` property that represents the DotCMS page asset and a `components` property that represents the dynamic components for the page.
31
+ *
32
+ * @export
33
+ * @class DotcmsLayoutComponent
34
+ */
35
+ @Component({
36
+ selector: 'dotcms-layout',
37
+ standalone: true,
38
+ imports: [RowComponent, AsyncPipe],
39
+ template: `
40
+ @if (pageAsset$ | async; as page) {
41
+ @for (row of this.page?.layout?.body?.rows; track $index) {
42
+ <dotcms-row [row]="row" />
43
+ }
44
+ }
45
+ `,
46
+ styleUrl: './dotcms-layout.component.css',
47
+ changeDetection: ChangeDetectionStrategy.OnPush
48
+ })
49
+ export class DotcmsLayoutComponent implements OnInit {
50
+ private _pageAsset!: DotCMSPageAsset;
51
+
52
+ /**
53
+ * Represents the DotCMS page asset.
54
+ *
55
+ * @type {DotCMSPageAsset}
56
+ * @memberof DotcmsLayoutComponent
57
+ */
58
+ @Input({ required: true })
59
+ set pageAsset(value: DotCMSPageAsset) {
60
+ this._pageAsset = value;
61
+ if (!value.layout) {
62
+ console.warn(
63
+ 'Warning: pageAsset does not have a `layout` property. Might be using an advaced template or your dotCMS instance not have a enterprise license.'
64
+ );
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Returns the DotCMS page asset.
70
+ *
71
+ * @readonly
72
+ * @type {DotCMSPageAsset}
73
+ * @memberof DotcmsLayoutComponent
74
+ */
75
+ get pageAsset(): DotCMSPageAsset {
76
+ return this._pageAsset;
77
+ }
78
+
79
+ /**
80
+ * The `components` property is a record of dynamic components for each Contentlet on the page.
81
+ *
82
+ * @type {DotCMSPageComponent}
83
+ * @memberof DotcmsLayoutComponent
84
+ * @required
85
+ */
86
+ @Input({ required: true }) components!: DotCMSPageComponent;
87
+
88
+ /**
89
+ * The `onReload` property is a function that reloads the page after changes are made.
90
+ *
91
+ * @memberof DotcmsLayoutComponent
92
+ * @deprecated In future implementation we will be listening for the changes from the editor to update the page state so reload will not be needed.
93
+ */
94
+ @Input() onReload!: () => void;
95
+
96
+ /**
97
+ *
98
+ * @type {DotCMSFetchConfig}
99
+ * @memberof DotCMSPageEditorConfig
100
+ * @description The configuration custom params for data fetching on Edit Mode.
101
+ * @example <caption>Example with Custom GraphQL query</caption>
102
+ * <dotcms-layout [editor]="{ query: 'query { ... }' }"/>
103
+ *
104
+ * @example <caption>Example usage with Custom Page API parameters</caption>
105
+ * <dotcms-layout [editor]="{ params: { depth: '2' } }"/>;
106
+ */
107
+ @Input() editor!: EditorConfig;
108
+
109
+ private readonly route = inject(ActivatedRoute);
110
+ private readonly pageContextService = inject(PageContextService);
111
+ private readonly destroyRef$ = inject(DestroyRef);
112
+ private client!: DotCmsClient;
113
+ protected readonly pageAsset$ = this.pageContextService.currentPage$;
114
+
115
+ ngOnInit() {
116
+ this.pageContextService.setContext(this.pageAsset, this.components);
117
+
118
+ if (!isInsideEditor()) {
119
+ return;
120
+ }
121
+
122
+ this.client = DotCmsClient.instance;
123
+ this.route.url.pipe(takeUntilDestroyed(this.destroyRef$)).subscribe((urlSegments) => {
124
+ const pathname = '/' + urlSegments.join('/');
125
+
126
+ initEditor({ pathname });
127
+ updateNavigation(pathname || '/');
128
+ });
129
+
130
+ this.client.editor.on('changes', (data) => {
131
+ if (this.onReload) {
132
+ this.onReload();
133
+
134
+ return;
135
+ }
136
+
137
+ this.pageContextService.setPageAsset(data as DotCMSPageAsset);
138
+ });
139
+
140
+ postMessageToEditor({ action: CUSTOMER_ACTIONS.CLIENT_READY, payload: this.editor });
141
+ }
142
+
143
+ ngOnDestroy() {
144
+ if (!isInsideEditor()) {
145
+ return;
146
+ }
147
+
148
+ this.client.editor.off('changes');
149
+ }
150
+ }
@@ -0,0 +1,6 @@
1
+ :host {
2
+ display: grid;
3
+ grid-template-columns: repeat(12, 1fr);
4
+ gap: 1rem;
5
+ row-gap: 1rem;
6
+ }
@@ -0,0 +1,28 @@
1
+ import { Spectator, createComponentFactory } from '@ngneat/spectator/jest';
2
+ import { MockComponent } from 'ng-mocks';
3
+
4
+ import { RowComponent } from './row.component';
5
+
6
+ import { DotPageAssetLayoutRow } from '../../models';
7
+ import { PageResponseMock } from '../../utils/testing.utils';
8
+ import { ColumnComponent } from '../column/column.component';
9
+
10
+ describe('RowComponent', () => {
11
+ let spectator: Spectator<RowComponent>;
12
+ const createComponent = createComponentFactory({
13
+ component: RowComponent,
14
+ imports: [MockComponent(ColumnComponent)]
15
+ });
16
+
17
+ beforeEach(() => {
18
+ spectator = createComponent({
19
+ props: {
20
+ row: PageResponseMock.layout.body.rows[1] as DotPageAssetLayoutRow
21
+ }
22
+ });
23
+ });
24
+
25
+ it('should render two columns', () => {
26
+ expect(spectator.queryAll(ColumnComponent)?.length).toBe(4);
27
+ });
28
+ });
@@ -0,0 +1,32 @@
1
+ import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
2
+
3
+ import { DotPageAssetLayoutRow } from '../../models';
4
+ import { ColumnComponent } from '../column/column.component';
5
+
6
+ /**
7
+ * This component is responsible to display a row with columns.
8
+ *
9
+ * @export
10
+ * @class RowComponent
11
+ */
12
+ @Component({
13
+ selector: 'dotcms-row',
14
+ standalone: true,
15
+ imports: [ColumnComponent],
16
+ template: `
17
+ @for (column of row.columns; track $index) {
18
+ <dotcms-column [column]="column" />
19
+ }
20
+ `,
21
+ styleUrl: './row.component.css',
22
+ changeDetection: ChangeDetectionStrategy.OnPush
23
+ })
24
+ export class RowComponent {
25
+ /**
26
+ * The row object containing the columns.
27
+ *
28
+ * @type {DotPageAssetLayoutRow}
29
+ * @memberof RowComponent
30
+ */
31
+ @Input({ required: true }) row!: DotPageAssetLayoutRow;
32
+ }
@@ -1,3 +1,5 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+
1
3
  export interface DotCMSPageAsset {
2
4
  canCreateTemplate: boolean;
3
5
  containers: DotCMSPageAssetContainer;
@@ -20,6 +22,7 @@ export interface DotCMSPageAsset {
20
22
  forward: boolean;
21
23
  };
22
24
  }
25
+
23
26
  export interface DotPageAssetLayoutRow {
24
27
  identifier: number;
25
28
  value?: string;
@@ -27,6 +30,7 @@ export interface DotPageAssetLayoutRow {
27
30
  columns: DotPageAssetLayoutColumn[];
28
31
  styleClass?: string;
29
32
  }
33
+
30
34
  export interface DotPageAssetLayoutColumn {
31
35
  preview: boolean;
32
36
  containers: DotCMSContainer[];
@@ -36,6 +40,7 @@ export interface DotPageAssetLayoutColumn {
36
40
  left: number;
37
41
  styleClass?: string;
38
42
  }
43
+
39
44
  export interface DotCMSPageAssetContainer {
40
45
  [key: string]: {
41
46
  container: DotCMSContainer;
@@ -45,6 +50,7 @@ export interface DotCMSPageAssetContainer {
45
50
  };
46
51
  };
47
52
  }
53
+
48
54
  export interface DotCMSContainer {
49
55
  identifier: string;
50
56
  uuid: string;
@@ -87,6 +93,7 @@ export interface DotCMSContainer {
87
93
  contentlets: DotCMSContentlet[];
88
94
  parentPermissionable: DotCMSSiteParentPermissionable;
89
95
  }
96
+
90
97
  export interface DotCMSContentlet {
91
98
  archived: boolean;
92
99
  baseType: string;
@@ -124,8 +131,9 @@ export interface DotCMSContentlet {
124
131
  contentTypeIcon?: string;
125
132
  variant?: string;
126
133
  __icon__?: string;
127
- [key: string]: any;
134
+ [key: string]: any; // This is a catch-all for any other custom properties that might be on the contentlet.
128
135
  }
136
+
129
137
  export interface DotcmsNavigationItem {
130
138
  code?: any;
131
139
  folder: string;
@@ -139,6 +147,7 @@ export interface DotcmsNavigationItem {
139
147
  target: string;
140
148
  order: number;
141
149
  }
150
+
142
151
  interface DotCMSTemplate {
143
152
  iDate: number;
144
153
  type: string;
@@ -173,6 +182,7 @@ interface DotCMSTemplate {
173
182
  new: boolean;
174
183
  canEdit: boolean;
175
184
  }
185
+
176
186
  interface DotCMSPage {
177
187
  template: string;
178
188
  modDate: number;
@@ -218,6 +228,7 @@ interface DotCMSPage {
218
228
  liveInode: string;
219
229
  shortyLive: string;
220
230
  }
231
+
221
232
  interface DotCMSViewAs {
222
233
  language: {
223
234
  id: number;
@@ -228,6 +239,7 @@ interface DotCMSViewAs {
228
239
  };
229
240
  mode: string;
230
241
  }
242
+
231
243
  interface DotCMSLayout {
232
244
  pageWidth: string;
233
245
  width: string;
@@ -238,6 +250,7 @@ interface DotCMSLayout {
238
250
  body: DotPageAssetLayoutBody;
239
251
  sidebar: DotPageAssetLayoutSidebar;
240
252
  }
253
+
241
254
  interface DotCMSContainerStructure {
242
255
  id: string;
243
256
  structureId: string;
@@ -246,6 +259,7 @@ interface DotCMSContainerStructure {
246
259
  code: string;
247
260
  contentTypeVar: string;
248
261
  }
262
+
249
263
  interface DotPageAssetLayoutSidebar {
250
264
  preview: boolean;
251
265
  containers: DotCMSContainer[];
@@ -253,9 +267,11 @@ interface DotPageAssetLayoutSidebar {
253
267
  widthPercent: number;
254
268
  width: string;
255
269
  }
270
+
256
271
  interface DotPageAssetLayoutBody {
257
272
  rows: DotPageAssetLayoutRow[];
258
273
  }
274
+
259
275
  interface DotCMSSite {
260
276
  lowIndexPriority: boolean;
261
277
  name: string;
@@ -306,12 +322,14 @@ interface DotCMSSite {
306
322
  sortOrder: number;
307
323
  contentType: DotCMSSiteContentType;
308
324
  }
325
+
309
326
  interface DotCMSSiteContentType {
310
327
  owner?: any;
311
328
  parentPermissionable: DotCMSSiteParentPermissionable;
312
329
  permissionId: string;
313
330
  permissionType: string;
314
331
  }
332
+
315
333
  export interface DotCMSSiteParentPermissionable {
316
334
  Inode: string;
317
335
  Identifier: string;
@@ -326,6 +344,7 @@ export interface DotCMSSiteParentPermissionable {
326
344
  childrenPermissionable?: any;
327
345
  variantId?: string;
328
346
  }
347
+
329
348
  interface DotCMSSiteStructure {
330
349
  iDate: number;
331
350
  type: string;
@@ -371,6 +390,7 @@ interface DotCMSSiteStructure {
371
390
  versionId: string;
372
391
  versionType: string;
373
392
  }
393
+
374
394
  interface DotCMSSiteField {
375
395
  iDate: number;
376
396
  type: string;
@@ -412,5 +432,3 @@ interface DotCMSSiteField {
412
432
  versionId: string;
413
433
  versionType: string;
414
434
  }
415
- export {};
416
- //# sourceMappingURL=dotcms.model.d.ts.map