Skip to content

Commit 3799996

Browse files
fix(core): components aren't loaded from static config during component refresh (#1865)
Whenever components are refreshed (for example after login), static components cannot be found at the backend (since their UDI is made up). We need to load them from static configuration. fixes #1863
1 parent 90dcbbd commit 3799996

19 files changed

+500
-243
lines changed

projects/core/src/cms/config/cms-structure.config.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { CmsConfig } from './cms-config';
21
import { ContentSlotComponentData } from '../model/content-slot-component-data.model';
2+
import { CmsConfig } from './cms-config';
33

44
/**
55
* The `CmsPageConfig` is used to build pages by configuration.
@@ -54,7 +54,7 @@ export interface CmsPageSlotsConfig {
5454
*/
5555
export interface CmsPageSlotConfig {
5656
uid?: string;
57-
components?: (ContentSlotComponentData | any)[];
57+
componentIds?: string[];
5858
}
5959

6060
/**
@@ -66,6 +66,7 @@ export interface CmsPageSlotConfig {
6666
*/
6767
export abstract class CmsStructureConfig extends CmsConfig {
6868
cmsStructure: {
69+
components?: { [key: string]: ContentSlotComponentData | any };
6970
pages?: CmsPageConfig[];
7071
slots?: CmsPageSlotsConfig;
7172
};

projects/core/src/cms/occ/cms-occ.module.ts

+6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { CommonModule } from '@angular/common';
22
import { HttpClientModule } from '@angular/common/http';
33
import { NgModule } from '@angular/core';
4+
import { CmsComponentLoader } from '../services/cms-component.loader';
45
import { CmsPageAdapter } from '../services/cms-page.adapter';
56
import { CmsPageLoader } from '../services/cms-page.loader';
67
import { ComponentMapperService } from '../services/component-mapper.service';
8+
import { OccCmsComponentLoader } from './occ-cms-component.loader';
79
import { OccCmsPageAdapter } from './occ-cms-page.adapter';
810
import { OccCmsPageLoader } from './occ-cms-page.loader';
911

@@ -20,6 +22,10 @@ import { OccCmsPageLoader } from './occ-cms-page.loader';
2022
provide: CmsPageAdapter,
2123
useClass: OccCmsPageAdapter,
2224
},
25+
{
26+
provide: CmsComponentLoader,
27+
useClass: OccCmsComponentLoader,
28+
},
2329
],
2430
})
2531
export class CmsOccModule {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import {
2+
HttpClientTestingModule,
3+
HttpTestingController,
4+
} from '@angular/common/http/testing';
5+
import { TestBed } from '@angular/core/testing';
6+
import { CmsComponent, PageType } from '../../occ/occ-models/index';
7+
import { OccEndpointsService } from '../../occ/services/occ-endpoints.service';
8+
import { PageContext } from '../../routing/index';
9+
import { CmsStructureConfig } from '../config';
10+
import { CmsStructureConfigService } from '../services';
11+
import { OccCmsComponentLoader } from './occ-cms-component.loader';
12+
13+
const components: CmsComponent[] = [
14+
{ uid: 'comp1', typeCode: 'SimpleBannerComponent' },
15+
{ uid: 'comp2', typeCode: 'CMSLinkComponent' },
16+
{ uid: 'comp3', typeCode: 'NavigationComponent' },
17+
];
18+
19+
const component: CmsComponent = components[1];
20+
21+
const CmsStructureConfigMock: CmsStructureConfig = {
22+
server: {
23+
baseUrl: '',
24+
occPrefix: '',
25+
},
26+
27+
site: {
28+
baseSite: '',
29+
language: '',
30+
currency: '',
31+
},
32+
cmsStructure: {
33+
pages: [],
34+
slots: {},
35+
},
36+
};
37+
38+
class CmsStructureConfigServiceMock {}
39+
40+
const endpoint = '/cms';
41+
42+
class OccEndpointsServiceMock {
43+
getEndpoint(): string {
44+
return endpoint;
45+
}
46+
}
47+
48+
describe('OccCmsComponentLoader', () => {
49+
let service: OccCmsComponentLoader;
50+
let httpMock: HttpTestingController;
51+
52+
beforeEach(() => {
53+
TestBed.configureTestingModule({
54+
imports: [HttpClientTestingModule],
55+
providers: [
56+
OccCmsComponentLoader,
57+
{ provide: OccEndpointsService, useClass: OccEndpointsServiceMock },
58+
{
59+
provide: CmsStructureConfig,
60+
useValue: CmsStructureConfigMock,
61+
},
62+
{
63+
provide: CmsStructureConfigService,
64+
useClass: CmsStructureConfigServiceMock,
65+
},
66+
],
67+
});
68+
69+
service = TestBed.get(OccCmsComponentLoader);
70+
httpMock = TestBed.get(HttpTestingController);
71+
});
72+
73+
afterEach(() => {
74+
httpMock.verify();
75+
});
76+
77+
it('Should get cms component data', () => {
78+
const context: PageContext = {
79+
id: 'testProductCode',
80+
type: PageType.PRODUCT_PAGE,
81+
};
82+
83+
service.load('comp1', context).subscribe(result => {
84+
expect(result).toEqual(component);
85+
});
86+
87+
const testRequest = httpMock.expectOne(req => {
88+
return req.method === 'GET' && req.url === endpoint + '/components/comp1';
89+
});
90+
91+
expect(testRequest.request.params.get('productCode')).toEqual(
92+
'testProductCode'
93+
);
94+
expect(testRequest.cancelled).toBeFalsy();
95+
expect(testRequest.request.responseType).toEqual('json');
96+
testRequest.flush(component);
97+
});
98+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
2+
import { Injectable, Optional } from '@angular/core';
3+
import { Observable, throwError } from 'rxjs';
4+
import { catchError } from 'rxjs/operators';
5+
import { CmsComponent, PageType } from '../../occ/occ-models/index';
6+
import { OccEndpointsService } from '../../occ/services/occ-endpoints.service';
7+
import { PageContext } from '../../routing/index';
8+
import { CmsStructureConfig } from '../config/cms-structure.config';
9+
import { CmsComponentAdapter } from '../services/cms-component.adapter';
10+
import { CmsComponentLoader } from '../services/cms-component.loader';
11+
import { CmsStructureConfigService } from '../services/cms-structure-config.service';
12+
13+
@Injectable()
14+
export class OccCmsComponentLoader extends CmsComponentLoader<any> {
15+
protected headers = new HttpHeaders().set('Content-Type', 'application/json');
16+
17+
constructor(
18+
private http: HttpClient,
19+
protected config: CmsStructureConfig,
20+
protected cmsStructureConfigService: CmsStructureConfigService,
21+
@Optional() protected adapter: CmsComponentAdapter<CmsComponent>,
22+
private occEndpoints: OccEndpointsService
23+
) {
24+
super(cmsStructureConfigService, adapter);
25+
}
26+
27+
protected getBaseEndPoint(): string {
28+
return this.occEndpoints.getEndpoint('cms');
29+
}
30+
31+
load<T extends CmsComponent>(
32+
id: string,
33+
pageContext: PageContext
34+
): Observable<T> {
35+
return this.http
36+
.get<T>(this.getBaseEndPoint() + `/components/${id}`, {
37+
headers: this.headers,
38+
params: new HttpParams({
39+
fromString: this.getRequestParams(pageContext),
40+
}),
41+
})
42+
.pipe(catchError((error: any) => throwError(error.json())));
43+
}
44+
45+
private getRequestParams(pageContext: PageContext): string {
46+
let requestParams = '';
47+
switch (pageContext.type) {
48+
case PageType.PRODUCT_PAGE: {
49+
requestParams = 'productCode=' + pageContext.id;
50+
break;
51+
}
52+
case PageType.CATEGORY_PAGE: {
53+
requestParams = 'categoryCode=' + pageContext.id;
54+
break;
55+
}
56+
case PageType.CATALOG_PAGE: {
57+
requestParams = 'catalogCode=' + pageContext.id;
58+
break;
59+
}
60+
}
61+
62+
return requestParams;
63+
}
64+
}

projects/core/src/cms/occ/occ-cms-page.loader.spec.ts

+7-59
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,28 @@
1-
import { TestBed } from '@angular/core/testing';
1+
import { HttpRequest } from '@angular/common/http';
22
import {
33
HttpClientTestingModule,
44
HttpTestingController,
55
} from '@angular/common/http/testing';
6-
7-
import { OccCmsPageLoader } from './occ-cms-page.loader';
8-
import { IdList } from '../model/idList.model';
9-
6+
import { TestBed } from '@angular/core/testing';
107
import {
118
CmsComponent,
9+
CmsComponentList,
1210
CMSPage,
1311
PageType,
14-
CmsComponentList,
1512
} from '../../occ/occ-models/index';
13+
import { OccEndpointsService } from '../../occ/services/occ-endpoints.service';
1614
import { PageContext } from '../../routing/index';
17-
import { HttpRequest } from '@angular/common/http';
18-
import { CmsStructureConfigService, CmsPageAdapter } from '../services';
1915
import { CmsStructureConfig } from '../config';
20-
import { OccEndpointsService } from '../../occ/services/occ-endpoints.service';
16+
import { IdList } from '../model/idList.model';
17+
import { CmsPageAdapter, CmsStructureConfigService } from '../services';
18+
import { OccCmsPageLoader } from './occ-cms-page.loader';
2119

2220
const components: CmsComponent[] = [
2321
{ uid: 'comp1', typeCode: 'SimpleBannerComponent' },
2422
{ uid: 'comp2', typeCode: 'CMSLinkComponent' },
2523
{ uid: 'comp3', typeCode: 'NavigationComponent' },
2624
];
2725

28-
const component: CmsComponent = components[1];
29-
3026
const cmsPageData: CMSPage = {
3127
uid: 'testPageId',
3228
name: 'testPage',
@@ -102,54 +98,6 @@ describe('OccCmsPageLoader', () => {
10298
httpMock.verify();
10399
});
104100

105-
describe('Load cms component', () => {
106-
it('Should get cms component data without parameter fields', () => {
107-
const context: PageContext = {
108-
id: 'testProductCode',
109-
type: PageType.PRODUCT_PAGE,
110-
};
111-
112-
service.loadComponent('comp1', context).subscribe(result => {
113-
expect(result).toEqual(component);
114-
});
115-
116-
const testRequest = httpMock.expectOne(req => {
117-
return (
118-
req.method === 'GET' && req.url === endpoint + '/components/comp1'
119-
);
120-
});
121-
122-
expect(testRequest.request.params.get('productCode')).toEqual(
123-
'testProductCode'
124-
);
125-
expect(testRequest.cancelled).toBeFalsy();
126-
expect(testRequest.request.responseType).toEqual('json');
127-
testRequest.flush(component);
128-
});
129-
130-
it('Should get cms component data with parameter fields', () => {
131-
const context: PageContext = {
132-
id: 'testPagId',
133-
type: PageType.CONTENT_PAGE,
134-
};
135-
136-
service.loadComponent('comp1', context, 'FULL').subscribe(result => {
137-
expect(result).toEqual(component);
138-
});
139-
140-
const testRequest = httpMock.expectOne(req => {
141-
return (
142-
req.method === 'GET' && req.url === endpoint + '/components/comp1'
143-
);
144-
});
145-
expect(testRequest.request.params.get('fields')).toEqual('FULL');
146-
147-
expect(testRequest.cancelled).toBeFalsy();
148-
expect(testRequest.request.responseType).toEqual('json');
149-
testRequest.flush(component);
150-
});
151-
});
152-
153101
describe('Load cms page data', () => {
154102
it('Should get cms content page data without parameter fields', () => {
155103
const context: PageContext = {

projects/core/src/cms/occ/occ-cms-page.loader.ts

+4-20
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
2-
import { Injectable } from '@angular/core';
2+
import { Injectable, Optional } from '@angular/core';
33
import { Observable, throwError } from 'rxjs';
44
import { catchError } from 'rxjs/operators';
5-
import { IdList } from './../model/idList.model';
65
import {
7-
CmsComponent,
86
CmsComponentList,
97
CMSPage,
108
PageType,
119
} from '../../occ/occ-models/index';
10+
import { OccEndpointsService } from '../../occ/services/occ-endpoints.service';
1211
import { PageContext } from '../../routing/index';
1312
import { CmsStructureConfig } from '../config/cms-structure.config';
13+
import { IdList } from '../model/idList.model';
1414
import { CmsPageAdapter } from '../services/cms-page.adapter';
1515
import { CmsPageLoader } from '../services/cms-page.loader';
1616
import { CmsStructureConfigService } from '../services/cms-structure-config.service';
17-
import { OccEndpointsService } from '../../occ/services/occ-endpoints.service';
1817

1918
@Injectable()
2019
export class OccCmsPageLoader extends CmsPageLoader<CMSPage> {
@@ -24,7 +23,7 @@ export class OccCmsPageLoader extends CmsPageLoader<CMSPage> {
2423
private http: HttpClient,
2524
protected config: CmsStructureConfig,
2625
protected cmsStructureConfigService: CmsStructureConfigService,
27-
protected adapter: CmsPageAdapter<CMSPage>,
26+
@Optional() protected adapter: CmsPageAdapter<CMSPage>,
2827
private occEndpoints: OccEndpointsService
2928
) {
3029
super(cmsStructureConfigService, adapter);
@@ -60,21 +59,6 @@ export class OccCmsPageLoader extends CmsPageLoader<CMSPage> {
6059
});
6160
}
6261

63-
loadComponent<T extends CmsComponent>(
64-
id: string,
65-
pageContext: PageContext,
66-
fields?: string
67-
): Observable<T> {
68-
return this.http
69-
.get<T>(this.getBaseEndPoint() + `/components/${id}`, {
70-
headers: this.headers,
71-
params: new HttpParams({
72-
fromString: this.getRequestParams(pageContext, fields),
73-
}),
74-
})
75-
.pipe(catchError((error: any) => throwError(error.json())));
76-
}
77-
7862
loadListComponents(
7963
idList: IdList,
8064
pageContext: PageContext,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Injectable } from '@angular/core';
2+
import { CmsComponent } from '../../occ/occ-models/cms-component.models';
3+
4+
@Injectable()
5+
export abstract class CmsComponentAdapter<T> {
6+
abstract adapt(source: T): CmsComponent;
7+
}

0 commit comments

Comments
 (0)