@dotcms/angular 0.0.1-alpha.40 → 0.0.1-alpha.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/dotcms-angular.d.ts.map +1 -0
- package/esm2022/dotcms-angular.mjs +5 -0
- package/esm2022/index.mjs +5 -0
- package/esm2022/lib/components/dot-editable-text/dot-editable-text.component.mjs +225 -0
- package/esm2022/lib/components/dot-editable-text/utils.mjs +43 -0
- package/esm2022/lib/components/no-component/no-component.component.mjs +32 -0
- package/esm2022/lib/layout/column/column.component.mjs +45 -0
- package/esm2022/lib/layout/container/container.component.mjs +126 -0
- package/esm2022/lib/layout/contentlet/contentlet.component.mjs +120 -0
- package/esm2022/lib/layout/dotcms-layout/dotcms-layout.component.mjs +100 -0
- package/esm2022/lib/layout/row/row.component.mjs +29 -0
- package/esm2022/lib/models/dotcms.model.mjs +3 -0
- package/esm2022/lib/models/index.mjs +3 -0
- package/esm2022/lib/services/dotcms-context/page-context.service.mjs +75 -0
- package/esm2022/lib/utils/index.mjs +79 -0
- package/fesm2022/dotcms-angular.mjs +858 -0
- package/fesm2022/dotcms-angular.mjs.map +1 -0
- package/{src/index.ts → index.d.ts} +1 -0
- package/index.d.ts.map +1 -0
- package/lib/components/dot-editable-text/dot-editable-text.component.d.ts +129 -0
- package/lib/components/dot-editable-text/dot-editable-text.component.d.ts.map +1 -0
- package/lib/components/dot-editable-text/utils.d.ts +7 -0
- package/lib/components/dot-editable-text/utils.d.ts.map +1 -0
- package/lib/components/no-component/no-component.component.d.ts +22 -0
- package/lib/components/no-component/no-component.component.d.ts.map +1 -0
- package/lib/layout/column/column.component.d.ts +29 -0
- package/lib/layout/column/column.component.d.ts.map +1 -0
- package/lib/layout/container/container.component.d.ts +88 -0
- package/lib/layout/container/container.component.d.ts.map +1 -0
- package/{src/lib/layout/contentlet/contentlet.component.ts → lib/layout/contentlet/contentlet.component.d.ts} +17 -32
- package/lib/layout/contentlet/contentlet.component.d.ts.map +1 -0
- package/lib/layout/dotcms-layout/dotcms-layout.component.d.ts +67 -0
- package/lib/layout/dotcms-layout/dotcms-layout.component.d.ts.map +1 -0
- package/lib/layout/row/row.component.d.ts +20 -0
- package/lib/layout/row/row.component.d.ts.map +1 -0
- package/{src/lib/models/dotcms.model.ts → lib/models/dotcms.model.d.ts} +3 -21
- package/lib/models/dotcms.model.d.ts.map +1 -0
- package/{src/lib/models/index.ts → lib/models/index.d.ts} +1 -8
- package/lib/models/index.d.ts.map +1 -0
- package/{src/lib/services/dotcms-context/page-context.service.ts → lib/services/dotcms-context/page-context.service.d.ts} +12 -41
- package/lib/services/dotcms-context/page-context.service.d.ts.map +1 -0
- package/lib/utils/index.d.ts +63 -0
- package/lib/utils/index.d.ts.map +1 -0
- package/package.json +22 -5
- package/.eslintrc.json +0 -18
- package/jest.config.ts +0 -22
- package/ng-package.json +0 -7
- package/project.json +0 -33
- package/src/lib/components/dot-editable-text/dot-editable-text.component.css +0 -4
- package/src/lib/components/dot-editable-text/dot-editable-text.component.html +0 -8
- package/src/lib/components/dot-editable-text/dot-editable-text.component.spec.ts +0 -424
- package/src/lib/components/dot-editable-text/dot-editable-text.component.ts +0 -269
- package/src/lib/components/dot-editable-text/utils.ts +0 -51
- package/src/lib/components/no-component/no-component.component.css +0 -3
- package/src/lib/components/no-component/no-component.component.spec.ts +0 -24
- package/src/lib/components/no-component/no-component.component.ts +0 -31
- package/src/lib/layout/column/column.component.css +0 -99
- package/src/lib/layout/column/column.component.spec.ts +0 -33
- package/src/lib/layout/column/column.component.ts +0 -49
- package/src/lib/layout/container/container.component.css +0 -9
- package/src/lib/layout/container/container.component.html +0 -26
- package/src/lib/layout/container/container.component.spec.ts +0 -205
- package/src/lib/layout/container/container.component.ts +0 -140
- package/src/lib/layout/contentlet/contentlet.component.spec.ts +0 -22
- package/src/lib/layout/dotcms-layout/dotcms-layout.component.css +0 -3
- package/src/lib/layout/dotcms-layout/dotcms-layout.component.spec.ts +0 -195
- package/src/lib/layout/dotcms-layout/dotcms-layout.component.ts +0 -150
- package/src/lib/layout/row/row.component.css +0 -6
- package/src/lib/layout/row/row.component.spec.ts +0 -28
- package/src/lib/layout/row/row.component.ts +0 -32
- package/src/lib/services/dotcms-context/page-context.spec.ts +0 -80
- package/src/lib/utils/index.ts +0 -92
- package/src/lib/utils/testing.utils.ts +0 -1019
- package/src/test-setup.ts +0 -8
- package/tsconfig.json +0 -29
- package/tsconfig.lib.json +0 -12
- package/tsconfig.lib.prod.json +0 -9
- package/tsconfig.spec.json +0 -11
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { EditorComponent } from '@tinymce/tinymce-angular';
|
|
2
|
-
|
|
3
|
-
export type DOT_EDITABLE_TEXT_MODE = 'minimal' | 'full' | 'plain';
|
|
4
|
-
|
|
5
|
-
export type DOT_EDITABLE_TEXT_FORMAT = 'html' | 'text';
|
|
6
|
-
|
|
7
|
-
const DEFAULT_TINYMCE_CONFIG: EditorComponent['init'] = {
|
|
8
|
-
menubar: false,
|
|
9
|
-
inline: true,
|
|
10
|
-
valid_styles: {
|
|
11
|
-
'*': 'font-size,font-family,color,text-decoration,text-align'
|
|
12
|
-
},
|
|
13
|
-
powerpaste_word_import: 'clean',
|
|
14
|
-
powerpaste_html_import: 'clean',
|
|
15
|
-
suffix: '.min', // Suffix to use when loading resources
|
|
16
|
-
license_key: 'gpl'
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export const TINYMCE_CONFIG: {
|
|
20
|
-
[key in DOT_EDITABLE_TEXT_MODE]: EditorComponent['init'];
|
|
21
|
-
} = {
|
|
22
|
-
minimal: {
|
|
23
|
-
...DEFAULT_TINYMCE_CONFIG,
|
|
24
|
-
plugins: 'link autolink',
|
|
25
|
-
toolbar: 'bold italic underline | link',
|
|
26
|
-
valid_elements: 'strong,em,span[style],a[href]'
|
|
27
|
-
},
|
|
28
|
-
full: {
|
|
29
|
-
...DEFAULT_TINYMCE_CONFIG,
|
|
30
|
-
plugins: 'link lists autolink charmap',
|
|
31
|
-
style_formats: [
|
|
32
|
-
{ title: 'Paragraph', format: 'p' },
|
|
33
|
-
{ title: 'Header 1', format: 'h1' },
|
|
34
|
-
{ title: 'Header 2', format: 'h2' },
|
|
35
|
-
{ title: 'Header 3', format: 'h3' },
|
|
36
|
-
{ title: 'Header 4', format: 'h4' },
|
|
37
|
-
{ title: 'Header 5', format: 'h5' },
|
|
38
|
-
{ title: 'Header 6', format: 'h6' },
|
|
39
|
-
{ title: 'Pre', format: 'pre' },
|
|
40
|
-
{ title: 'Code', format: 'code' }
|
|
41
|
-
],
|
|
42
|
-
toolbar: [
|
|
43
|
-
'styleselect undo redo | bold italic underline | forecolor backcolor | alignleft aligncenter alignright alignfull | numlist bullist outdent indent | hr charmap removeformat | link'
|
|
44
|
-
]
|
|
45
|
-
},
|
|
46
|
-
plain: {
|
|
47
|
-
...DEFAULT_TINYMCE_CONFIG,
|
|
48
|
-
plugins: '',
|
|
49
|
-
toolbar: ''
|
|
50
|
-
}
|
|
51
|
-
};
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Spectator, createComponentFactory } from '@ngneat/spectator';
|
|
2
|
-
|
|
3
|
-
import { NoComponent } from './no-component.component';
|
|
4
|
-
|
|
5
|
-
import { DotCMSContentlet } from '../../models';
|
|
6
|
-
|
|
7
|
-
describe('NoComponentComponent', () => {
|
|
8
|
-
let spectator: Spectator<NoComponent>;
|
|
9
|
-
|
|
10
|
-
const createComponent = createComponentFactory(NoComponent);
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
spectator = createComponent({
|
|
14
|
-
props: {
|
|
15
|
-
contentlet: { contentType: 'exampleContentType' } as DotCMSContentlet
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it('should display the content type', () => {
|
|
21
|
-
const noComponent = spectator.debugElement.nativeElement;
|
|
22
|
-
expect(noComponent?.innerHTML).toContain('No Component for exampleContentType');
|
|
23
|
-
});
|
|
24
|
-
});
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, HostBinding, Input } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
import { DotCMSContentlet } from '../../models';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* This component is responsible to display a message when there is no component for a contentlet.
|
|
7
|
-
*
|
|
8
|
-
* @export
|
|
9
|
-
* @class NoComponent
|
|
10
|
-
*/
|
|
11
|
-
@Component({
|
|
12
|
-
selector: 'dotcms-no-component',
|
|
13
|
-
standalone: true,
|
|
14
|
-
template: `
|
|
15
|
-
No Component for {{ contentlet.contentType }}
|
|
16
|
-
`,
|
|
17
|
-
styleUrl: './no-component.component.css',
|
|
18
|
-
changeDetection: ChangeDetectionStrategy.OnPush
|
|
19
|
-
})
|
|
20
|
-
export class NoComponent {
|
|
21
|
-
/**
|
|
22
|
-
* The contentlet object containing content data.
|
|
23
|
-
* The component displays a message based on the content type of this contentlet.
|
|
24
|
-
*/
|
|
25
|
-
@Input() contentlet!: DotCMSContentlet;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* The data-testid attribute used for identifying the component during testing.
|
|
29
|
-
*/
|
|
30
|
-
@HostBinding('attr.data-testid') testId = 'no-component';
|
|
31
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
:host.col-start-1 {
|
|
2
|
-
grid-column-start: 1;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
:host.col-start-2 {
|
|
6
|
-
grid-column-start: 2;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
:host.col-start-3 {
|
|
10
|
-
grid-column-start: 3;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
:host.col-start-4 {
|
|
14
|
-
grid-column-start: 4;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
:host.col-start-5 {
|
|
18
|
-
grid-column-start: 5;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
:host.col-start-6 {
|
|
22
|
-
grid-column-start: 6;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
:host.col-start-7 {
|
|
26
|
-
grid-column-start: 7;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
:host.col-start-8 {
|
|
30
|
-
grid-column-start: 8;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
:host.col-start-9 {
|
|
34
|
-
grid-column-start: 9;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
:host.col-start-10 {
|
|
38
|
-
grid-column-start: 10;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
:host.col-start-11 {
|
|
42
|
-
grid-column-start: 11;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
:host.col-start-12 {
|
|
46
|
-
grid-column-start: 12;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
:host.col-end-1 {
|
|
50
|
-
grid-column-end: 1;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
:host.col-end-2 {
|
|
54
|
-
grid-column-end: 2;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
:host.col-end-3 {
|
|
58
|
-
grid-column-end: 3;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
:host.col-end-4 {
|
|
62
|
-
grid-column-end: 4;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
:host.col-end-5 {
|
|
66
|
-
grid-column-end: 5;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
:host.col-end-6 {
|
|
70
|
-
grid-column-end: 6;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
:host.col-end-7 {
|
|
74
|
-
grid-column-end: 7;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
:host.col-end-8 {
|
|
78
|
-
grid-column-end: 8;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
:host.col-end-9 {
|
|
82
|
-
grid-column-end: 9;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
:host.col-end-10 {
|
|
86
|
-
grid-column-end: 10;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
:host.col-end-11 {
|
|
90
|
-
grid-column-end: 11;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
:host.col-end-12 {
|
|
94
|
-
grid-column-end: 12;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
:host.col-end-13 {
|
|
98
|
-
grid-column-end: 13;
|
|
99
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { Spectator, createComponentFactory } from '@ngneat/spectator';
|
|
2
|
-
import { MockComponent } from 'ng-mocks';
|
|
3
|
-
|
|
4
|
-
import { ColumnComponent } from './column.component';
|
|
5
|
-
|
|
6
|
-
import { DotPageAssetLayoutColumn } from '../../models';
|
|
7
|
-
import { PageResponseMock } from '../../utils/testing.utils';
|
|
8
|
-
import { ContainerComponent } from '../container/container.component';
|
|
9
|
-
|
|
10
|
-
describe('ColumnComponent', () => {
|
|
11
|
-
let spectator: Spectator<ColumnComponent>;
|
|
12
|
-
|
|
13
|
-
const createComponent = createComponentFactory({
|
|
14
|
-
component: ColumnComponent,
|
|
15
|
-
imports: [MockComponent(ContainerComponent)]
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
spectator = createComponent({
|
|
20
|
-
props: {
|
|
21
|
-
column: PageResponseMock.layout.body.rows[0].columns[0] as DotPageAssetLayoutColumn
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('should render one container', () => {
|
|
27
|
-
expect(spectator.queryAll(ContainerComponent)?.length).toBe(1);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('should set correct containerClasses', () => {
|
|
31
|
-
expect(spectator.component.containerClasses).toBe('col-start-1 col-end-13');
|
|
32
|
-
});
|
|
33
|
-
});
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, HostBinding, Input, OnInit } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
import { DotPageAssetLayoutColumn } from '../../models';
|
|
4
|
-
import { getPositionStyleClasses } from '../../utils';
|
|
5
|
-
import { ContainerComponent } from '../container/container.component';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* This component is responsible to display a column with containers.
|
|
9
|
-
*
|
|
10
|
-
* @export
|
|
11
|
-
* @class ColumnComponent
|
|
12
|
-
* @implements {OnInit}
|
|
13
|
-
*/
|
|
14
|
-
@Component({
|
|
15
|
-
selector: 'dotcms-column',
|
|
16
|
-
standalone: true,
|
|
17
|
-
imports: [ContainerComponent],
|
|
18
|
-
template: `
|
|
19
|
-
@for (container of column.containers; track $index) {
|
|
20
|
-
<dotcms-container [container]="container" />
|
|
21
|
-
}
|
|
22
|
-
`,
|
|
23
|
-
styleUrl: './column.component.css',
|
|
24
|
-
changeDetection: ChangeDetectionStrategy.OnPush
|
|
25
|
-
})
|
|
26
|
-
export class ColumnComponent implements OnInit {
|
|
27
|
-
/**
|
|
28
|
-
* The column object containing the containers.
|
|
29
|
-
*
|
|
30
|
-
* @type {DotPageAssetLayoutColumn}
|
|
31
|
-
* @memberof ColumnComponent
|
|
32
|
-
*/
|
|
33
|
-
@Input() column!: DotPageAssetLayoutColumn;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* The data-testid attribute used for identifying the component during testing.
|
|
37
|
-
*
|
|
38
|
-
* @memberof ColumnComponent
|
|
39
|
-
*/
|
|
40
|
-
@HostBinding('class') containerClasses = '';
|
|
41
|
-
|
|
42
|
-
ngOnInit() {
|
|
43
|
-
const { startClass, endClass } = getPositionStyleClasses(
|
|
44
|
-
this.column.leftOffset,
|
|
45
|
-
this.column.width + this.column.leftOffset
|
|
46
|
-
);
|
|
47
|
-
this.containerClasses = `${startClass} ${endClass}`;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
@if ($isInsideEditor()) {
|
|
2
|
-
@if ($contentlets().length) {
|
|
3
|
-
@for (contentlet of $contentlets(); track $index) {
|
|
4
|
-
<dotcms-contentlet-wrapper
|
|
5
|
-
[contentlet]="contentlet"
|
|
6
|
-
[container]="$dotContainerAsString()">
|
|
7
|
-
<ng-container
|
|
8
|
-
*ngComponentOutlet="
|
|
9
|
-
(componentsMap[contentlet.contentType] || componentsMap['CustomNoComponent']
|
|
10
|
-
| async) || NoComponent;
|
|
11
|
-
inputs: { contentlet }
|
|
12
|
-
" />
|
|
13
|
-
</dotcms-contentlet-wrapper>
|
|
14
|
-
}
|
|
15
|
-
} @else {
|
|
16
|
-
This container is empty.
|
|
17
|
-
}
|
|
18
|
-
} @else {
|
|
19
|
-
@for (contentlet of $contentlets(); track $index) {
|
|
20
|
-
<ng-container
|
|
21
|
-
*ngComponentOutlet="
|
|
22
|
-
componentsMap[contentlet.contentType] | async;
|
|
23
|
-
inputs: { contentlet }
|
|
24
|
-
" />
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import { Spectator, byTestId, byText, createComponentFactory } from '@ngneat/spectator';
|
|
2
|
-
import { of } from 'rxjs';
|
|
3
|
-
|
|
4
|
-
import { Component, Input } from '@angular/core';
|
|
5
|
-
|
|
6
|
-
import { ContainerComponent } from './container.component';
|
|
7
|
-
|
|
8
|
-
import { NoComponent } from '../../components/no-component/no-component.component';
|
|
9
|
-
import { DotCMSContainer, DotCMSContentlet } from '../../models';
|
|
10
|
-
import { PageContextService } from '../../services/dotcms-context/page-context.service';
|
|
11
|
-
import { PageResponseMock } from '../../utils/testing.utils';
|
|
12
|
-
|
|
13
|
-
@Component({
|
|
14
|
-
selector: 'dotcms-mock-component',
|
|
15
|
-
standalone: true,
|
|
16
|
-
template: 'Hello world'
|
|
17
|
-
})
|
|
18
|
-
class DotcmsSDKMockComponent {
|
|
19
|
-
@Input() contentlet!: DotCMSContentlet;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
@Component({
|
|
23
|
-
selector: 'dot-no-component',
|
|
24
|
-
template: 'no component yet - Custom'
|
|
25
|
-
})
|
|
26
|
-
class CustomNoComponent {
|
|
27
|
-
@Input() contentlet!: DotCMSContentlet;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
describe('ContainerComponent', () => {
|
|
31
|
-
let spectator: Spectator<ContainerComponent>;
|
|
32
|
-
|
|
33
|
-
describe('inside editor', () => {
|
|
34
|
-
const createComponent = createComponentFactory({
|
|
35
|
-
component: ContainerComponent,
|
|
36
|
-
detectChanges: false,
|
|
37
|
-
providers: [
|
|
38
|
-
{
|
|
39
|
-
provide: PageContextService,
|
|
40
|
-
useValue: {
|
|
41
|
-
context: {
|
|
42
|
-
pageAsset: {
|
|
43
|
-
containers: PageResponseMock.containers
|
|
44
|
-
},
|
|
45
|
-
components: {
|
|
46
|
-
Banner: of(DotcmsSDKMockComponent)
|
|
47
|
-
},
|
|
48
|
-
isInsideEditor: true
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
]
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
beforeEach(() => {
|
|
56
|
-
spectator = createComponent({
|
|
57
|
-
props: {
|
|
58
|
-
container: PageResponseMock.layout.body.rows[0].columns[0]
|
|
59
|
-
.containers[0] as DotCMSContainer
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should render MockContainerComponent', () => {
|
|
65
|
-
spectator.detectChanges();
|
|
66
|
-
expect(spectator.query(DotcmsSDKMockComponent)).toBeTruthy();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('should container have data attributes', () => {
|
|
70
|
-
spectator.detectChanges();
|
|
71
|
-
const container = spectator.debugElement.nativeElement;
|
|
72
|
-
expect(container?.getAttribute('data-dot-accept-types')).toBeDefined();
|
|
73
|
-
expect(container?.getAttribute('data-dot-identifier')).toBeDefined();
|
|
74
|
-
expect(container?.getAttribute('data-max-contentlets')).toBeDefined();
|
|
75
|
-
expect(container?.getAttribute('ata-dot-uuid')).toBeDefined();
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('should contentlets have data attributes', () => {
|
|
79
|
-
spectator.detectChanges();
|
|
80
|
-
const contentlets = spectator.queryAll(byTestId('dot-contentlet'));
|
|
81
|
-
contentlets.forEach((contentlet) => {
|
|
82
|
-
expect(contentlet.getAttribute('data-dot-identifier')).toBeDefined();
|
|
83
|
-
expect(contentlet.getAttribute('data-dot-basetype')).toBeDefined();
|
|
84
|
-
expect(contentlet.getAttribute('data-dot-title')).toBeDefined();
|
|
85
|
-
expect(contentlet.getAttribute('data-dot-inode')).toBeDefined();
|
|
86
|
-
expect(contentlet.getAttribute('data-dot-type')).toBeDefined();
|
|
87
|
-
expect(contentlet.getAttribute('data-dot-container')).toBeDefined();
|
|
88
|
-
expect(contentlet.getAttribute('data-dot-on-number-of-pages')).toBeDefined();
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('should render NoComponent component for unsetted content types', () => {
|
|
93
|
-
spectator.setInput(
|
|
94
|
-
'container',
|
|
95
|
-
PageResponseMock.layout.body.rows[1].columns[0].containers[0] as DotCMSContainer
|
|
96
|
-
);
|
|
97
|
-
spectator.detectChanges();
|
|
98
|
-
expect(spectator.query(NoComponent)).toBeTruthy();
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('should render message when container is empty', () => {
|
|
102
|
-
spectator.setInput(
|
|
103
|
-
'container',
|
|
104
|
-
PageResponseMock.layout.body.rows[2].columns[0].containers[0] as DotCMSContainer
|
|
105
|
-
);
|
|
106
|
-
spectator.detectChanges();
|
|
107
|
-
expect(spectator.query(byText('This container is empty.'))).toBeTruthy();
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
describe('with custom NoComponent component', () => {
|
|
112
|
-
const createComponent = createComponentFactory({
|
|
113
|
-
component: ContainerComponent,
|
|
114
|
-
detectChanges: false,
|
|
115
|
-
providers: [
|
|
116
|
-
{
|
|
117
|
-
provide: PageContextService,
|
|
118
|
-
useValue: {
|
|
119
|
-
context: {
|
|
120
|
-
pageAsset: {
|
|
121
|
-
containers: PageResponseMock.containers
|
|
122
|
-
},
|
|
123
|
-
components: {
|
|
124
|
-
Banner: of(DotcmsSDKMockComponent)
|
|
125
|
-
},
|
|
126
|
-
isInsideEditor: true
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
]
|
|
131
|
-
});
|
|
132
|
-
beforeEach(() => {
|
|
133
|
-
spectator = createComponent({
|
|
134
|
-
props: {
|
|
135
|
-
container: PageResponseMock.layout.body.rows[1].columns[0]
|
|
136
|
-
.containers[0] as DotCMSContainer
|
|
137
|
-
},
|
|
138
|
-
providers: [
|
|
139
|
-
{
|
|
140
|
-
provide: PageContextService,
|
|
141
|
-
useValue: {
|
|
142
|
-
context: {
|
|
143
|
-
pageAsset: {
|
|
144
|
-
containers: PageResponseMock.containers
|
|
145
|
-
},
|
|
146
|
-
components: {
|
|
147
|
-
CustomNoComponent: of(CustomNoComponent)
|
|
148
|
-
},
|
|
149
|
-
isInsideEditor: true
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
]
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it('should render custom NoComponent component for unsetted content types', () => {
|
|
158
|
-
spectator.detectChanges();
|
|
159
|
-
expect(spectator.query(CustomNoComponent)).toBeTruthy();
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
describe('outside editor', () => {
|
|
164
|
-
const createComponent = createComponentFactory({
|
|
165
|
-
component: ContainerComponent,
|
|
166
|
-
detectChanges: false,
|
|
167
|
-
providers: [
|
|
168
|
-
{
|
|
169
|
-
provide: PageContextService,
|
|
170
|
-
useValue: {
|
|
171
|
-
context: {
|
|
172
|
-
pageAsset: {
|
|
173
|
-
containers: PageResponseMock.containers
|
|
174
|
-
},
|
|
175
|
-
components: {
|
|
176
|
-
Banner: of(DotcmsSDKMockComponent)
|
|
177
|
-
},
|
|
178
|
-
isInsideEditor: false
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
]
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
beforeEach(() => {
|
|
186
|
-
spectator = createComponent({
|
|
187
|
-
props: {
|
|
188
|
-
container: PageResponseMock.layout.body.rows[0].columns[0]
|
|
189
|
-
.containers[0] as DotCMSContainer
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it('should not have data attributes', () => {
|
|
195
|
-
spectator.detectChanges();
|
|
196
|
-
const container = spectator.query(byTestId('dot-container'));
|
|
197
|
-
expect(container?.getAttribute('data-dot-accept-types')).toBeUndefined();
|
|
198
|
-
|
|
199
|
-
const contentlets = spectator.queryAll(byTestId('dot-contentlet'));
|
|
200
|
-
contentlets.forEach((contentlet) => {
|
|
201
|
-
expect(contentlet.getAttribute('data-dot-identifier')).toBeUndefined();
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
});
|
|
205
|
-
});
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { AsyncPipe, NgComponentOutlet } from '@angular/common';
|
|
2
|
-
import {
|
|
3
|
-
ChangeDetectionStrategy,
|
|
4
|
-
Component,
|
|
5
|
-
HostBinding,
|
|
6
|
-
Input,
|
|
7
|
-
OnChanges,
|
|
8
|
-
computed,
|
|
9
|
-
inject,
|
|
10
|
-
signal
|
|
11
|
-
} from '@angular/core';
|
|
12
|
-
|
|
13
|
-
import { NoComponent } from '../../components/no-component/no-component.component';
|
|
14
|
-
import { DynamicComponentEntity } from '../../models';
|
|
15
|
-
import { DotCMSContainer, DotCMSContentlet } from '../../models/dotcms.model';
|
|
16
|
-
import { PageContextService } from '../../services/dotcms-context/page-context.service';
|
|
17
|
-
import { getContainersData } from '../../utils';
|
|
18
|
-
import { ContentletComponent } from '../contentlet/contentlet.component';
|
|
19
|
-
|
|
20
|
-
interface DotContainer {
|
|
21
|
-
acceptTypes: string;
|
|
22
|
-
identifier: string;
|
|
23
|
-
maxContentlets: number;
|
|
24
|
-
uuid: string;
|
|
25
|
-
variantId?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* This component is responsible to display a container with contentlets.
|
|
30
|
-
*
|
|
31
|
-
* @export
|
|
32
|
-
* @class ContainerComponent
|
|
33
|
-
* @implements {OnChanges}
|
|
34
|
-
*/
|
|
35
|
-
@Component({
|
|
36
|
-
selector: 'dotcms-container',
|
|
37
|
-
standalone: true,
|
|
38
|
-
imports: [AsyncPipe, NgComponentOutlet, NoComponent, ContentletComponent],
|
|
39
|
-
templateUrl: './container.component.html',
|
|
40
|
-
styleUrl: './container.component.css',
|
|
41
|
-
changeDetection: ChangeDetectionStrategy.OnPush
|
|
42
|
-
})
|
|
43
|
-
export class ContainerComponent implements OnChanges {
|
|
44
|
-
/**
|
|
45
|
-
* The container object containing the contentlets.
|
|
46
|
-
*
|
|
47
|
-
* @type {DotCMSContainer}
|
|
48
|
-
* @memberof ContainerComponent
|
|
49
|
-
*/
|
|
50
|
-
@Input({ required: true }) container!: DotCMSContainer;
|
|
51
|
-
|
|
52
|
-
private readonly pageContextService: PageContextService = inject(PageContextService);
|
|
53
|
-
protected readonly NoComponent = NoComponent;
|
|
54
|
-
protected readonly $isInsideEditor = signal<boolean>(false);
|
|
55
|
-
|
|
56
|
-
protected componentsMap!: Record<string, DynamicComponentEntity>;
|
|
57
|
-
protected $contentlets = signal<DotCMSContentlet[]>([]);
|
|
58
|
-
protected $dotContainer = signal<DotContainer | null>(null);
|
|
59
|
-
protected $dotContainerAsString = computed(() => JSON.stringify(this.$dotContainer()));
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* The accept types for the container component.
|
|
63
|
-
*
|
|
64
|
-
* @type {(string | null)}
|
|
65
|
-
* @memberof ContainerComponent
|
|
66
|
-
*/
|
|
67
|
-
@HostBinding('attr.data-dot-accept-types') acceptTypes: string | null = null;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* The identifier for the container component.
|
|
71
|
-
*
|
|
72
|
-
* @type {(string | null)}
|
|
73
|
-
* @memberof ContainerComponent
|
|
74
|
-
*/
|
|
75
|
-
@HostBinding('attr.data-dot-identifier') identifier: string | null = null;
|
|
76
|
-
/**
|
|
77
|
-
* The max contentlets for the container component.
|
|
78
|
-
*
|
|
79
|
-
* @type {(number | null)}
|
|
80
|
-
* @memberof ContainerComponent
|
|
81
|
-
*/
|
|
82
|
-
@HostBinding('attr.data-max-contentlets') maxContentlets: number | null = null;
|
|
83
|
-
/**
|
|
84
|
-
* The uuid for the container component.
|
|
85
|
-
*
|
|
86
|
-
* @type {(string | null)}
|
|
87
|
-
* @memberof ContainerComponent
|
|
88
|
-
*/
|
|
89
|
-
@HostBinding('attr.data-dot-uuid') uuid: string | null = null;
|
|
90
|
-
/**
|
|
91
|
-
* The class for the container component.
|
|
92
|
-
*
|
|
93
|
-
* @type {(string | null)}
|
|
94
|
-
* @memberof ContainerComponent
|
|
95
|
-
*/
|
|
96
|
-
@HostBinding('class') class: string | null = null;
|
|
97
|
-
/**
|
|
98
|
-
* The dot object for the container component.
|
|
99
|
-
*
|
|
100
|
-
* @type {(string | null)}
|
|
101
|
-
* @memberof ContainerComponent
|
|
102
|
-
*/
|
|
103
|
-
@HostBinding('attr.data-dot-object') dotObject: string | null = null;
|
|
104
|
-
/**
|
|
105
|
-
* The data-testid attribute used for identifying the component during testing.
|
|
106
|
-
*
|
|
107
|
-
* @memberof ContainerComponent
|
|
108
|
-
*/
|
|
109
|
-
@HostBinding('attr.data-testid') testId = 'dot-container';
|
|
110
|
-
|
|
111
|
-
ngOnChanges() {
|
|
112
|
-
const { pageAsset, components, isInsideEditor } = this.pageContextService.context;
|
|
113
|
-
const { acceptTypes, maxContentlets, variantId, path, contentlets } = getContainersData(
|
|
114
|
-
pageAsset.containers,
|
|
115
|
-
this.container
|
|
116
|
-
);
|
|
117
|
-
const { identifier, uuid } = this.container;
|
|
118
|
-
|
|
119
|
-
this.componentsMap = components;
|
|
120
|
-
|
|
121
|
-
this.$isInsideEditor.set(isInsideEditor);
|
|
122
|
-
this.$contentlets.set(contentlets);
|
|
123
|
-
this.$dotContainer.set({
|
|
124
|
-
identifier: path ?? identifier,
|
|
125
|
-
acceptTypes,
|
|
126
|
-
maxContentlets,
|
|
127
|
-
variantId,
|
|
128
|
-
uuid
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
if (this.$isInsideEditor()) {
|
|
132
|
-
this.acceptTypes = acceptTypes;
|
|
133
|
-
this.identifier = identifier;
|
|
134
|
-
this.maxContentlets = maxContentlets;
|
|
135
|
-
this.uuid = uuid;
|
|
136
|
-
this.class = this.$contentlets().length ? null : 'empty-container';
|
|
137
|
-
this.dotObject = 'container';
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|