@dotcms/angular 0.0.1-alpha.38 → 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 (78) hide show
  1. package/.eslintrc.json +18 -0
  2. package/jest.config.ts +22 -0
  3. package/ng-package.json +7 -0
  4. package/package.json +4 -21
  5. package/project.json +33 -0
  6. package/{index.d.ts → src/index.ts} +0 -1
  7. package/src/lib/components/dot-editable-text/dot-editable-text.component.css +4 -0
  8. package/src/lib/components/dot-editable-text/dot-editable-text.component.html +8 -0
  9. package/src/lib/components/dot-editable-text/dot-editable-text.component.spec.ts +424 -0
  10. package/src/lib/components/dot-editable-text/dot-editable-text.component.ts +269 -0
  11. package/src/lib/components/dot-editable-text/utils.ts +51 -0
  12. package/src/lib/components/no-component/no-component.component.css +3 -0
  13. package/src/lib/components/no-component/no-component.component.spec.ts +24 -0
  14. package/src/lib/components/no-component/no-component.component.ts +31 -0
  15. package/src/lib/layout/column/column.component.css +99 -0
  16. package/src/lib/layout/column/column.component.spec.ts +33 -0
  17. package/src/lib/layout/column/column.component.ts +49 -0
  18. package/src/lib/layout/container/container.component.css +9 -0
  19. package/src/lib/layout/container/container.component.html +26 -0
  20. package/src/lib/layout/container/container.component.spec.ts +205 -0
  21. package/src/lib/layout/container/container.component.ts +140 -0
  22. package/src/lib/layout/contentlet/contentlet.component.spec.ts +22 -0
  23. package/{lib/layout/contentlet/contentlet.component.d.ts → src/lib/layout/contentlet/contentlet.component.ts} +32 -17
  24. package/src/lib/layout/dotcms-layout/dotcms-layout.component.css +3 -0
  25. package/src/lib/layout/dotcms-layout/dotcms-layout.component.spec.ts +195 -0
  26. package/src/lib/layout/dotcms-layout/dotcms-layout.component.ts +150 -0
  27. package/src/lib/layout/row/row.component.css +6 -0
  28. package/src/lib/layout/row/row.component.spec.ts +28 -0
  29. package/src/lib/layout/row/row.component.ts +32 -0
  30. package/{lib/models/dotcms.model.d.ts → src/lib/models/dotcms.model.ts} +21 -3
  31. package/{lib/models/index.d.ts → src/lib/models/index.ts} +8 -1
  32. package/{lib/services/dotcms-context/page-context.service.d.ts → src/lib/services/dotcms-context/page-context.service.ts} +41 -12
  33. package/src/lib/services/dotcms-context/page-context.spec.ts +80 -0
  34. package/src/lib/utils/index.ts +92 -0
  35. package/src/lib/utils/testing.utils.ts +1019 -0
  36. package/src/test-setup.ts +8 -0
  37. package/tsconfig.json +29 -0
  38. package/tsconfig.lib.json +12 -0
  39. package/tsconfig.lib.prod.json +9 -0
  40. package/tsconfig.spec.json +11 -0
  41. package/dotcms-angular.d.ts.map +0 -1
  42. package/esm2022/dotcms-angular.mjs +0 -5
  43. package/esm2022/index.mjs +0 -5
  44. package/esm2022/lib/components/dot-editable-text/dot-editable-text.component.mjs +0 -225
  45. package/esm2022/lib/components/dot-editable-text/utils.mjs +0 -43
  46. package/esm2022/lib/components/no-component/no-component.component.mjs +0 -32
  47. package/esm2022/lib/layout/column/column.component.mjs +0 -45
  48. package/esm2022/lib/layout/container/container.component.mjs +0 -126
  49. package/esm2022/lib/layout/contentlet/contentlet.component.mjs +0 -120
  50. package/esm2022/lib/layout/dotcms-layout/dotcms-layout.component.mjs +0 -100
  51. package/esm2022/lib/layout/row/row.component.mjs +0 -29
  52. package/esm2022/lib/models/dotcms.model.mjs +0 -3
  53. package/esm2022/lib/models/index.mjs +0 -3
  54. package/esm2022/lib/services/dotcms-context/page-context.service.mjs +0 -75
  55. package/esm2022/lib/utils/index.mjs +0 -79
  56. package/fesm2022/dotcms-angular.mjs +0 -858
  57. package/fesm2022/dotcms-angular.mjs.map +0 -1
  58. package/index.d.ts.map +0 -1
  59. package/lib/components/dot-editable-text/dot-editable-text.component.d.ts +0 -129
  60. package/lib/components/dot-editable-text/dot-editable-text.component.d.ts.map +0 -1
  61. package/lib/components/dot-editable-text/utils.d.ts +0 -7
  62. package/lib/components/dot-editable-text/utils.d.ts.map +0 -1
  63. package/lib/components/no-component/no-component.component.d.ts +0 -22
  64. package/lib/components/no-component/no-component.component.d.ts.map +0 -1
  65. package/lib/layout/column/column.component.d.ts +0 -29
  66. package/lib/layout/column/column.component.d.ts.map +0 -1
  67. package/lib/layout/container/container.component.d.ts +0 -88
  68. package/lib/layout/container/container.component.d.ts.map +0 -1
  69. package/lib/layout/contentlet/contentlet.component.d.ts.map +0 -1
  70. package/lib/layout/dotcms-layout/dotcms-layout.component.d.ts +0 -67
  71. package/lib/layout/dotcms-layout/dotcms-layout.component.d.ts.map +0 -1
  72. package/lib/layout/row/row.component.d.ts +0 -20
  73. package/lib/layout/row/row.component.d.ts.map +0 -1
  74. package/lib/models/dotcms.model.d.ts.map +0 -1
  75. package/lib/models/index.d.ts.map +0 -1
  76. package/lib/services/dotcms-context/page-context.service.d.ts.map +0 -1
  77. package/lib/utils/index.d.ts +0 -63
  78. package/lib/utils/index.d.ts.map +0 -1
@@ -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
@@ -1,12 +1,17 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1
2
  export * from './dotcms.model';
3
+
2
4
  import { Type } from '@angular/core';
5
+
3
6
  import { DotCMSPageAsset } from './dotcms.model';
7
+
4
8
  /**
5
9
  * Represents a dynamic component entity.
6
10
  * @typedef {Promise<Type<any>>} DynamicComponentEntity
7
11
  * @memberof @dotcms/angular
8
12
  */
9
13
  export type DynamicComponentEntity = Promise<Type<any>>;
14
+
10
15
  /**
11
16
  * Represents the context of a DotCMS page.
12
17
  */
@@ -17,12 +22,14 @@ export interface DotCMSPageContext {
17
22
  * @memberof DotCMSPageContext
18
23
  */
19
24
  pageAsset: DotCMSPageAsset;
25
+
20
26
  /**
21
27
  * Represents the dynamic components of the page for each Content Type.
22
28
  * @type {DotCMSPageComponent}
23
29
  * @memberof DotCMSPageContext
24
30
  */
25
31
  components: DotCMSPageComponent;
32
+
26
33
  /**
27
34
  * Indicates whether the page is being viewed inside the editor.
28
35
  * @type {boolean}
@@ -30,6 +37,7 @@ export interface DotCMSPageContext {
30
37
  */
31
38
  isInsideEditor: boolean;
32
39
  }
40
+
33
41
  /**
34
42
  * Represents a DotCMS page component.
35
43
  * Used to store the dynamic components of a DotCMS page.
@@ -37,4 +45,3 @@ export interface DotCMSPageContext {
37
45
  * @memberof @dotcms/angular
38
46
  */
39
47
  export type DotCMSPageComponent = Record<string, DynamicComponentEntity>;
40
- //# sourceMappingURL=index.d.ts.map
@@ -1,49 +1,78 @@
1
- import { Observable } from 'rxjs';
1
+ import { BehaviorSubject, Observable } from 'rxjs';
2
+
3
+ import { Injectable } from '@angular/core';
4
+
5
+ import { map } from 'rxjs/operators';
6
+
7
+ import { isInsideEditor } from '@dotcms/client';
8
+
2
9
  import { DotCMSPageComponent, DotCMSPageContext } from '../../models';
3
10
  import { DotCMSPageAsset } from '../../models/dotcms.model';
4
- import * as i0 from "@angular/core";
11
+
5
12
  /**
6
13
  * @author dotCMS
7
14
  * @description This service is responsible for managing the page context.
8
15
  * @export
9
16
  * @class PageContextService
10
17
  */
11
- export declare class PageContextService {
12
- private context$;
18
+ @Injectable({
19
+ providedIn: 'root'
20
+ })
21
+ export class PageContextService {
22
+ private context$ = new BehaviorSubject<DotCMSPageContext | null>(null);
23
+
13
24
  /**
14
25
  * @description Get the context
15
26
  * @readonly
16
27
  * @type {DotCMSPageContext}
17
28
  * @memberof PageContextService
18
29
  */
19
- get context(): DotCMSPageContext;
30
+ get context(): DotCMSPageContext {
31
+ return this.context$.getValue() as DotCMSPageContext;
32
+ }
33
+
20
34
  /**
21
35
  * @description Get the context as an observable
22
36
  * @readonly
23
37
  * @memberof PageContextService
24
38
  */
25
- get contextObs$(): Observable<DotCMSPageContext | null>;
39
+ get contextObs$() {
40
+ return this.context$.asObservable();
41
+ }
42
+
26
43
  /**
27
44
  * @description Get the current page asset
28
45
  * @readonly
29
46
  * @type {(Observable<DotCMSPageAsset | null>)}
30
47
  * @memberof PageContextService
31
48
  */
32
- get currentPage$(): Observable<DotCMSPageAsset | null>;
49
+ get currentPage$(): Observable<DotCMSPageAsset | null> {
50
+ return this.contextObs$.pipe(map((context) => context?.pageAsset || null));
51
+ }
52
+
33
53
  /**
34
54
  *
35
55
  * @description Set the context
36
56
  * @param {DotCMSPageAsset} value
37
57
  * @memberof DotcmsContextService
38
58
  */
39
- setContext(pageAsset: DotCMSPageAsset, components: DotCMSPageComponent): void;
59
+ setContext(pageAsset: DotCMSPageAsset, components: DotCMSPageComponent) {
60
+ this.context$.next({
61
+ pageAsset,
62
+ components,
63
+ isInsideEditor: isInsideEditor()
64
+ });
65
+ }
66
+
40
67
  /**
41
68
  * @description Set the page asset in the context
42
69
  * @param {DotCMSPageAsset} pageAsset
43
70
  * @memberof PageContextService
44
71
  */
45
- setPageAsset(pageAsset: DotCMSPageAsset): void;
46
- static ɵfac: i0.ɵɵFactoryDeclaration<PageContextService, never>;
47
- static ɵprov: i0.ɵɵInjectableDeclaration<PageContextService>;
72
+ setPageAsset(pageAsset: DotCMSPageAsset) {
73
+ this.context$.next({
74
+ ...this.context,
75
+ pageAsset
76
+ });
77
+ }
48
78
  }
49
- //# sourceMappingURL=page-context.service.d.ts.map
@@ -0,0 +1,80 @@
1
+ import { SpectatorService, createServiceFactory } from '@ngneat/spectator';
2
+
3
+ import { TestBed } from '@angular/core/testing';
4
+
5
+ import { PageContextService } from './page-context.service';
6
+
7
+ import { DotCMSPageAsset, DotCMSPageComponent } from '../../models';
8
+ import { PageResponseMock } from '../../utils/testing.utils';
9
+
10
+ const initialPageAssetMock = {} as DotCMSPageAsset;
11
+ const initialComponentsMock = {} as DotCMSPageComponent;
12
+
13
+ describe('PageContextService', () => {
14
+ let spectator: SpectatorService<PageContextService>;
15
+ let service: PageContextService;
16
+
17
+ const createService = createServiceFactory(PageContextService);
18
+
19
+ beforeEach(() => {
20
+ TestBed.configureTestingModule({});
21
+ spectator = createService();
22
+ service = spectator.service;
23
+ });
24
+
25
+ it('should set the context', () => {
26
+ service.setContext(initialPageAssetMock, initialComponentsMock);
27
+
28
+ expect(service.context).toEqual({
29
+ components: initialComponentsMock,
30
+ pageAsset: initialPageAssetMock,
31
+ isInsideEditor: false
32
+ });
33
+ });
34
+
35
+ it('should set the page asset in the context', () => {
36
+ service.setContext(initialPageAssetMock, initialComponentsMock);
37
+
38
+ const newPageAssetMock = PageResponseMock as unknown as DotCMSPageAsset;
39
+
40
+ service.setPageAsset(newPageAssetMock);
41
+
42
+ expect(service.context).toEqual({
43
+ components: initialComponentsMock,
44
+ pageAsset: newPageAssetMock,
45
+ isInsideEditor: false
46
+ });
47
+ });
48
+
49
+ it('should return the context', () => {
50
+ service.setContext(initialPageAssetMock, initialComponentsMock);
51
+
52
+ expect(service.context).toEqual({
53
+ components: initialComponentsMock,
54
+ pageAsset: initialPageAssetMock,
55
+ isInsideEditor: false
56
+ });
57
+ });
58
+
59
+ it('should return the context as an observable', (done) => {
60
+ service.setContext(initialPageAssetMock, initialComponentsMock);
61
+
62
+ service.contextObs$.subscribe((context) => {
63
+ expect(context).toEqual({
64
+ components: initialComponentsMock,
65
+ pageAsset: initialPageAssetMock,
66
+ isInsideEditor: false
67
+ });
68
+ done();
69
+ });
70
+ });
71
+
72
+ it('should return the page asset as an observable', (done) => {
73
+ service.setContext(initialPageAssetMock, initialComponentsMock);
74
+
75
+ service.currentPage$.subscribe((pageAsset) => {
76
+ expect(pageAsset).toEqual(initialPageAssetMock);
77
+ done();
78
+ });
79
+ });
80
+ });
@@ -0,0 +1,92 @@
1
+ import { DotCMSContainer, DotCMSPageAssetContainer } from '../models/dotcms.model';
2
+
3
+ //Changed the type, to avoid SQ issue.
4
+ //This should be put inside a lib
5
+ /**
6
+ * Represents a mapping of numbers to corresponding CSS class names for column end values.
7
+ * @typedef {Record<number, string | null>} EndClassMap
8
+ */
9
+ const endClassMap: Record<number, string | null> = {
10
+ 1: 'col-end-1',
11
+ 2: 'col-end-2',
12
+ 3: 'col-end-3',
13
+ 4: 'col-end-4',
14
+ 5: 'col-end-5',
15
+ 6: 'col-end-6',
16
+ 7: 'col-end-7',
17
+ 8: 'col-end-8',
18
+ 9: 'col-end-9',
19
+ 10: 'col-end-10',
20
+ 11: 'col-end-11',
21
+ 12: 'col-end-12',
22
+ 13: 'col-end-13'
23
+ };
24
+
25
+ //Changed the type, to avoid SQ issue.
26
+ //This should be put inside a lib
27
+ /**
28
+ * Represents a mapping of numbers to CSS class names for starting columns.
29
+ * @typedef {Record<number, string | null>} StartClassMap
30
+ */
31
+ const startClassMap: Record<number, string | null> = {
32
+ 1: 'col-start-1',
33
+ 2: 'col-start-2',
34
+ 3: 'col-start-3',
35
+ 4: 'col-start-4',
36
+ 5: 'col-start-5',
37
+ 6: 'col-start-6',
38
+ 7: 'col-start-7',
39
+ 8: 'col-start-8',
40
+ 9: 'col-start-9',
41
+ 10: 'col-start-10',
42
+ 11: 'col-start-11',
43
+ 12: 'col-start-12'
44
+ };
45
+
46
+ /**
47
+ * Retrieves the data for a set of containers.
48
+ *
49
+ * @param containers - The DotCMSPageAssetContainer object containing the containers.
50
+ * @param containerRef - The DotCMSContainer object representing the container reference.
51
+ * @returns An object containing the container data, accept types, contentlets, and variant ID.
52
+ */
53
+ export const getContainersData = (
54
+ containers: DotCMSPageAssetContainer,
55
+ containerRef: DotCMSContainer
56
+ ) => {
57
+ const { identifier, uuid } = containerRef;
58
+
59
+ const { containerStructures, container } = containers[identifier];
60
+
61
+ const { variantId } = container?.parentPermissionable || {};
62
+
63
+ const acceptTypes: string = containerStructures
64
+ .map((structure) => structure.contentTypeVar)
65
+ .join(',');
66
+
67
+ const contentlets = containers[identifier].contentlets[`uuid-${uuid}`];
68
+
69
+ return {
70
+ ...containers[identifier].container,
71
+ acceptTypes,
72
+ contentlets,
73
+ variantId
74
+ };
75
+ };
76
+
77
+ /**
78
+ * Returns the position style classes based on the start and end values.
79
+ * Used to set the grid column start and end values.
80
+ * @param start - The start value.
81
+ * @param end - The end value.
82
+ * @returns An object containing the startClass and endClass.
83
+ */
84
+ export const getPositionStyleClasses = (start: number, end: number) => {
85
+ const startClass = startClassMap[start];
86
+ const endClass = endClassMap[end];
87
+
88
+ return {
89
+ startClass,
90
+ endClass
91
+ };
92
+ };