create-sitecore-jss 22.2.0-canary.7 → 22.2.0-canary.71
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/dist/bin.js +17 -43
- package/dist/common/processes/next.js +4 -1
- package/dist/common/processes/transform.js +2 -12
- package/dist/common/prompts/base.js +0 -13
- package/dist/common/prompts/proxy.js +35 -0
- package/dist/common/prompts/sxp.js +16 -2
- package/dist/common/utils/helpers.js +27 -2
- package/dist/init-runner.js +1 -1
- package/dist/initializers/angular/prompts.js +4 -4
- package/dist/initializers/angular-xmcloud/index.js +21 -7
- package/dist/initializers/node-xmcloud-proxy/index.js +2 -1
- package/dist/templates/angular/.env +4 -5
- package/dist/templates/angular/.eslintrc +1 -0
- package/dist/templates/angular/gitignore +5 -0
- package/dist/templates/angular/package.json +0 -2
- package/dist/templates/angular/scripts/config/plugins/fallback.ts +0 -1
- package/dist/templates/angular/scripts/generate-component-factory.ts +8 -0
- package/dist/templates/angular/scripts/generate-config.ts +25 -6
- package/dist/templates/angular/scripts/update-graphql-fragment-data.ts +21 -30
- package/dist/templates/angular/server.bundle.ts +3 -23
- package/dist/templates/angular/server.exports.ts +13 -0
- package/dist/templates/angular/src/app/JssState.ts +2 -9
- package/dist/templates/angular/src/app/app.module.ts +5 -4
- package/dist/templates/angular/src/app/app.server.module.ts +9 -6
- package/dist/templates/angular/src/app/i18n/jss-translation-client-loader.service.ts +15 -7
- package/dist/templates/angular/src/app/i18n/jss-translation-server-loader.service.ts +14 -2
- package/dist/templates/angular/src/app/jss-context.server-side.service.ts +4 -2
- package/dist/templates/angular/src/app/jss-context.service.ts +14 -11
- package/dist/templates/angular/src/app/jss-graphql.service.ts +7 -7
- package/dist/templates/angular/src/app/layout/jss-layout.service.ts +2 -2
- package/dist/templates/angular/src/app/lib/dictionary-service-factory.ts +4 -1
- package/dist/templates/angular/src/app/lib/graphql-client-factory/config.ts +21 -0
- package/dist/templates/angular/src/app/lib/graphql-client-factory/index.ts +16 -0
- package/dist/templates/angular/src/app/lib/layout-service-factory.ts +1 -1
- package/dist/templates/angular/src/app/routing/layout/layout.component.ts +10 -9
- package/dist/templates/angular/src/environments/gitignore +2 -1
- package/dist/templates/angular-sxp/.env +2 -0
- package/dist/templates/angular-sxp/scripts/config/plugins/disconnected.ts +4 -2
- package/dist/templates/angular-sxp/src/app/components/graph-ql-layout/graph-ql-layout.component.ts +1 -1
- package/dist/templates/angular-xmcloud/.env +8 -2
- package/dist/templates/angular-xmcloud/angular.json +0 -1
- package/dist/templates/angular-xmcloud/scripts/bootstrap.ts +28 -0
- package/dist/templates/angular-xmcloud/scripts/config/plugins/xmcloud.ts +16 -0
- package/dist/templates/angular-xmcloud/scripts/generate-metadata.ts +25 -0
- package/dist/templates/angular-xmcloud/server.exports.ts +24 -0
- package/dist/templates/angular-xmcloud/src/app/components/app-components.shared.module.ts +21 -0
- package/dist/templates/angular-xmcloud/src/app/components/column-splitter/column-splitter.component.html +5 -0
- package/dist/templates/angular-xmcloud/src/app/components/column-splitter/column-splitter.component.ts +40 -0
- package/dist/templates/angular-xmcloud/src/app/components/container/container.component.html +14 -0
- package/dist/templates/angular-xmcloud/src/app/components/container/container.component.ts +30 -0
- package/dist/templates/angular-xmcloud/src/app/components/image/image.component.html +36 -0
- package/dist/templates/angular-xmcloud/src/app/components/image/image.component.ts +67 -0
- package/dist/templates/angular-xmcloud/src/app/components/link-list/link-list.component.html +15 -0
- package/dist/templates/angular-xmcloud/src/app/components/link-list/link-list.component.ts +41 -0
- package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation-item.component.html +23 -0
- package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation-item.component.ts +65 -0
- package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation.component.html +21 -0
- package/dist/templates/angular-xmcloud/src/app/components/navigation/navigation.component.ts +49 -0
- package/dist/templates/angular-xmcloud/src/app/components/page-content/page-content.component.html +5 -0
- package/dist/templates/angular-xmcloud/src/app/components/page-content/page-content.component.ts +39 -0
- package/dist/templates/angular-xmcloud/src/app/components/partial-design-dynamic-placeholder/partial-design-dynamic-placeholder.component.html +1 -0
- package/dist/templates/angular-xmcloud/src/app/components/partial-design-dynamic-placeholder/partial-design-dynamic-placeholder.component.ts +15 -0
- package/dist/templates/angular-xmcloud/src/app/components/promo/promo.component.html +21 -0
- package/dist/templates/angular-xmcloud/src/app/components/promo/promo.component.ts +13 -0
- package/dist/templates/angular-xmcloud/src/app/components/richtext/richtext.component.html +7 -12
- package/dist/templates/angular-xmcloud/src/app/components/richtext/richtext.component.ts +6 -1
- package/dist/templates/angular-xmcloud/src/app/components/row-splitter/row-splitter.component.html +11 -0
- package/dist/templates/angular-xmcloud/src/app/components/row-splitter/row-splitter.component.ts +35 -0
- package/dist/templates/angular-xmcloud/src/app/components/sxa.component.ts +4 -4
- package/dist/templates/angular-xmcloud/src/app/components/title/title.component.html +10 -0
- package/dist/templates/angular-xmcloud/src/app/components/title/title.component.ts +56 -0
- package/dist/templates/angular-xmcloud/src/app/jss-link.service.ts +55 -0
- package/dist/templates/angular-xmcloud/src/app/lib/config.ts +2 -0
- package/dist/templates/angular-xmcloud/src/app/lib/graphql-client-factory/config.ts +58 -0
- package/dist/templates/angular-xmcloud/src/app/routing/layout/layout.component.html +38 -0
- package/dist/templates/angular-xmcloud/src/app/routing/layout/layout.component.ts +104 -0
- package/dist/templates/angular-xmcloud/src/app/routing/scripts/scripts.component.html +3 -0
- package/dist/templates/angular-xmcloud/src/app/routing/scripts/scripts.module.ts +10 -0
- package/dist/templates/angular-xmcloud/src/assets/styles/basic/_header.scss +3 -1
- package/dist/templates/angular-xmcloud/src/assets/styles/main.scss +10 -0
- package/dist/templates/angular-xmcloud/src/assets/styles/sass/components/_component-image.scss +1 -1
- package/dist/templates/nextjs/package.json +1 -1
- package/dist/templates/nextjs/scripts/config/plugins/fallback.ts +0 -1
- package/dist/templates/nextjs/scripts/generate-config.ts +8 -1
- package/dist/templates/nextjs/src/lib/page-props-factory/plugins/component-props.ts +2 -1
- package/dist/templates/nextjs-styleguide/scripts/config/plugins/disconnected.ts +1 -0
- package/dist/templates/nextjs-sxa/src/assets/sass/components/_component-image.scss +1 -1
- package/dist/templates/nextjs-sxa/src/assets/sass/components/common/_alignment.scss +66 -7
- package/dist/templates/nextjs-sxa/src/components/Container.tsx +6 -14
- package/dist/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/component-themes.ts +2 -1
- package/dist/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/preview-mode.ts +2 -1
- package/dist/templates/node-headless-ssr-experience-edge/gitignore +19 -0
- package/dist/templates/node-headless-ssr-proxy/gitignore +19 -0
- package/dist/templates/node-headless-ssr-proxy/src/config.ts +3 -3
- package/dist/templates/node-headless-ssr-proxy/src/httpAgents.ts +2 -2
- package/dist/templates/node-headless-ssr-proxy/src/index.ts +9 -2
- package/dist/templates/node-xmcloud-proxy/.env +7 -1
- package/dist/templates/node-xmcloud-proxy/README.md +1 -1
- package/dist/templates/node-xmcloud-proxy/gitignore +33 -0
- package/dist/templates/node-xmcloud-proxy/package.json +3 -2
- package/dist/templates/node-xmcloud-proxy/src/config.ts +9 -3
- package/dist/templates/node-xmcloud-proxy/src/index.ts +54 -5
- package/dist/templates/node-xmcloud-proxy/src/types.ts +10 -42
- package/dist/templates/react/scripts/generate-config.js +10 -3
- package/dist/templates/vue/scripts/generate-config.js +5 -0
- package/package.json +2 -2
- package/dist/templates/angular/src/app/lib/graphql-client-factory.ts +0 -28
- package/dist/templates/angular-xmcloud/src/app/lib/graphql-client-factory.ts +0 -44
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Component, OnDestroy, OnInit } from '@angular/core';
|
|
2
|
+
import { LinkField, SxaTitleFields, TextField } from '@sitecore-jss/sitecore-jss-angular';
|
|
3
|
+
import { SxaComponent } from '../sxa.component';
|
|
4
|
+
import { Subscription } from 'rxjs';
|
|
5
|
+
import { JssContextService } from '../../jss-context.service';
|
|
6
|
+
|
|
7
|
+
@Component({
|
|
8
|
+
selector: 'app-title',
|
|
9
|
+
templateUrl: './title.component.html',
|
|
10
|
+
host: {
|
|
11
|
+
'class': 'component title',
|
|
12
|
+
'[class]': 'styles',
|
|
13
|
+
'[id]': 'id',
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
export class TitleComponent extends SxaComponent<SxaTitleFields> implements OnInit, OnDestroy {
|
|
17
|
+
text: TextField;
|
|
18
|
+
link: LinkField;
|
|
19
|
+
pageEditing?: boolean;
|
|
20
|
+
|
|
21
|
+
private contextSubscription: Subscription;
|
|
22
|
+
|
|
23
|
+
constructor(private jssContext: JssContextService) {
|
|
24
|
+
super();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
ngOnInit() {
|
|
28
|
+
super.ngOnInit();
|
|
29
|
+
const datasource =
|
|
30
|
+
this.rendering.fields?.data?.datasource || this.rendering.fields?.data?.contextItem;
|
|
31
|
+
this.text = datasource.field?.jsonValue;
|
|
32
|
+
this.link = {
|
|
33
|
+
value: {
|
|
34
|
+
href: datasource?.url?.path,
|
|
35
|
+
title: datasource?.field?.jsonValue?.value,
|
|
36
|
+
text: datasource?.field?.jsonValue?.value,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
this.contextSubscription = this.jssContext.state.subscribe(({ sitecore }) => {
|
|
40
|
+
this.pageEditing = sitecore.context.pageEditing;
|
|
41
|
+
if (sitecore.context.pageState !== 'normal') {
|
|
42
|
+
this.link.value.querystring = `sc_site=${datasource?.url?.siteName}`;
|
|
43
|
+
if (!this.text?.value) {
|
|
44
|
+
this.text.value = 'Title field';
|
|
45
|
+
this.link.value.href = '#';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
ngOnDestroy() {
|
|
52
|
+
if (this.contextSubscription) {
|
|
53
|
+
this.contextSubscription.unsubscribe();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Inject, Injectable } from '@angular/core';
|
|
2
|
+
import { DOCUMENT } from '@angular/common';
|
|
3
|
+
import { HTMLLink } from '@sitecore-jss/sitecore-jss-angular';
|
|
4
|
+
|
|
5
|
+
@Injectable({
|
|
6
|
+
providedIn: 'root',
|
|
7
|
+
})
|
|
8
|
+
export class JssLinkService {
|
|
9
|
+
constructor(@Inject(DOCUMENT) private document: Document) {}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Adds link element in the document head.
|
|
13
|
+
* @param headLinks - An array of HTMLLink objects to add to the head.
|
|
14
|
+
*/
|
|
15
|
+
addHeadLinks(headLink: HTMLLink) {
|
|
16
|
+
if (!headLink) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Check if a link with the same rel and href already exists
|
|
21
|
+
if (this.isDuplicateLink(headLink)) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
this.createLink(headLink);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Creates a new link element and appends it to the head.
|
|
30
|
+
* @param headLink - An HTMLLink object to be added.
|
|
31
|
+
*/
|
|
32
|
+
private createLink(headLink: HTMLLink) {
|
|
33
|
+
if (!headLink.rel || !headLink.href) {
|
|
34
|
+
console.log('Invalid link object:', headLink);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const link: HTMLLinkElement = this.document.createElement('link');
|
|
39
|
+
link.setAttribute('rel', headLink.rel);
|
|
40
|
+
link.setAttribute('href', headLink.href);
|
|
41
|
+
this.document.head.appendChild(link);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Checks for an existing link element with the same rel and href attributes.
|
|
46
|
+
* @param headLink - An HTMLLink object to be checked.
|
|
47
|
+
* @returns {boolean} - True if a matching link exists, false otherwise.
|
|
48
|
+
*/
|
|
49
|
+
private isDuplicateLink(headLink: HTMLLink): boolean {
|
|
50
|
+
const existingLink = this.document.head.querySelector(
|
|
51
|
+
`link[rel='${headLink.rel}'][href='${headLink.href}']`
|
|
52
|
+
);
|
|
53
|
+
return !!existingLink;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GraphQLRequestClientFactoryConfig,
|
|
3
|
+
getEdgeProxyContentUrl,
|
|
4
|
+
} from '@sitecore-jss/sitecore-jss-angular/cjs';
|
|
5
|
+
import { environment as env } from '../../../environments/environment';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Gets the configuration for the GraphQLRequestClientFactory
|
|
9
|
+
* @returns GraphQLRequestClientFactoryConfig
|
|
10
|
+
*/
|
|
11
|
+
export const getGraphQLClientFactoryConfig = () => {
|
|
12
|
+
let clientConfig: GraphQLRequestClientFactoryConfig;
|
|
13
|
+
|
|
14
|
+
// Server side requests should go directly to the Sitecore, browser requests should go through the proxy.
|
|
15
|
+
const isServer = typeof window === 'undefined';
|
|
16
|
+
// If we are in a production environment we are going to use Node XM Cloud proxy
|
|
17
|
+
const isProduction = env.production === 'true';
|
|
18
|
+
|
|
19
|
+
if (isProduction) {
|
|
20
|
+
if (!env.proxyHost) {
|
|
21
|
+
throw new Error('Please configure your proxyHost.');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (env.sitecoreEdgeContextId) {
|
|
25
|
+
clientConfig = {
|
|
26
|
+
endpoint: isServer
|
|
27
|
+
? getEdgeProxyContentUrl(env.sitecoreEdgeContextId, env.sitecoreEdgeUrl)
|
|
28
|
+
: getEdgeProxyContentUrl(env.sitecoreEdgeContextId, env.proxyHost),
|
|
29
|
+
};
|
|
30
|
+
} else if (env.graphQLEndpoint && env.sitecoreApiKey) {
|
|
31
|
+
const graphQLEndpointPath = new URL(env.graphQLEndpoint).pathname;
|
|
32
|
+
|
|
33
|
+
clientConfig = {
|
|
34
|
+
endpoint: isServer ? env.graphQLEndpoint : `${env.proxyHost}${graphQLEndpointPath}`,
|
|
35
|
+
apiKey: env.sitecoreApiKey,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
if (env.sitecoreEdgeContextId) {
|
|
40
|
+
clientConfig = {
|
|
41
|
+
endpoint: getEdgeProxyContentUrl(env.sitecoreEdgeContextId, env.sitecoreEdgeUrl),
|
|
42
|
+
};
|
|
43
|
+
} else if (env.graphQLEndpoint && env.sitecoreApiKey) {
|
|
44
|
+
clientConfig = {
|
|
45
|
+
endpoint: env.graphQLEndpoint,
|
|
46
|
+
apiKey: env.sitecoreApiKey,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!clientConfig?.endpoint) {
|
|
52
|
+
throw new Error(
|
|
53
|
+
'Please configure either your sitecoreEdgeContextId, or your graphQLEndpoint and sitecoreApiKey.'
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return clientConfig;
|
|
58
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<div class="{{ mainClassPageEditing }}">
|
|
2
|
+
<ng-container *ngIf="state === LayoutState.Layout">
|
|
3
|
+
<app-scripts></app-scripts>
|
|
4
|
+
<header>
|
|
5
|
+
<div id="header">
|
|
6
|
+
<sc-placeholder
|
|
7
|
+
name="headless-header"
|
|
8
|
+
[rendering]="route"
|
|
9
|
+
(loaded)="onPlaceholderLoaded($event)"
|
|
10
|
+
></sc-placeholder>
|
|
11
|
+
</div>
|
|
12
|
+
</header>
|
|
13
|
+
<main>
|
|
14
|
+
<div id="content">
|
|
15
|
+
<sc-placeholder
|
|
16
|
+
name="headless-main"
|
|
17
|
+
[rendering]="route"
|
|
18
|
+
(loaded)="onPlaceholderLoaded($event)"
|
|
19
|
+
></sc-placeholder>
|
|
20
|
+
</div>
|
|
21
|
+
</main>
|
|
22
|
+
<footer>
|
|
23
|
+
<div id="footer">
|
|
24
|
+
<sc-placeholder
|
|
25
|
+
name="headless-footer"
|
|
26
|
+
[rendering]="route"
|
|
27
|
+
(loaded)="onPlaceholderLoaded($event)"
|
|
28
|
+
></sc-placeholder>
|
|
29
|
+
</div>
|
|
30
|
+
</footer>
|
|
31
|
+
</ng-container>
|
|
32
|
+
|
|
33
|
+
<app-not-found
|
|
34
|
+
*ngIf="state === LayoutState.NotFound"
|
|
35
|
+
[errorContextData]="errorContextData"
|
|
36
|
+
></app-not-found>
|
|
37
|
+
<app-server-error *ngIf="state === LayoutState.Error"></app-server-error>
|
|
38
|
+
</div>
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/* eslint-disable no-shadow, no-console */
|
|
2
|
+
import { Component, OnInit, OnDestroy } from '@angular/core';
|
|
3
|
+
import {
|
|
4
|
+
RouteData,
|
|
5
|
+
Field,
|
|
6
|
+
LayoutServiceContextData,
|
|
7
|
+
getContentStylesheetLink,
|
|
8
|
+
} from '@sitecore-jss/sitecore-jss-angular';
|
|
9
|
+
import { ActivatedRoute } from '@angular/router';
|
|
10
|
+
import { Subscription } from 'rxjs';
|
|
11
|
+
import { JssState } from '../../JssState';
|
|
12
|
+
import { JssMetaService } from '../../jss-meta.service';
|
|
13
|
+
import { JssLinkService } from '../../jss-link.service';
|
|
14
|
+
import { environment as env } from '../../../environments/environment';
|
|
15
|
+
|
|
16
|
+
enum LayoutState {
|
|
17
|
+
Layout,
|
|
18
|
+
NotFound,
|
|
19
|
+
Error,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface RouteFields {
|
|
23
|
+
[name: string]: unknown;
|
|
24
|
+
pageTitle?: Field<string>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@Component({
|
|
28
|
+
selector: 'app-layout',
|
|
29
|
+
templateUrl: './layout.component.html',
|
|
30
|
+
})
|
|
31
|
+
export class LayoutComponent implements OnInit, OnDestroy {
|
|
32
|
+
route: RouteData<RouteFields>;
|
|
33
|
+
state: LayoutState;
|
|
34
|
+
LayoutState = LayoutState;
|
|
35
|
+
subscription: Subscription;
|
|
36
|
+
errorContextData: LayoutServiceContextData;
|
|
37
|
+
mainClassPageEditing: string;
|
|
38
|
+
|
|
39
|
+
constructor(
|
|
40
|
+
private activatedRoute: ActivatedRoute,
|
|
41
|
+
private readonly meta: JssMetaService,
|
|
42
|
+
private linkService: JssLinkService
|
|
43
|
+
) {}
|
|
44
|
+
|
|
45
|
+
ngOnInit() {
|
|
46
|
+
// route data is populated by the JssRouteResolver
|
|
47
|
+
this.subscription = this.activatedRoute.data.subscribe((data: { jssState: JssState }) => {
|
|
48
|
+
if (!data.jssState) {
|
|
49
|
+
this.state = LayoutState.NotFound;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (data.jssState.sitecore && data.jssState.sitecore.route) {
|
|
54
|
+
this.route = data.jssState.sitecore.route;
|
|
55
|
+
this.setMetadata(this.route.fields);
|
|
56
|
+
this.state = LayoutState.Layout;
|
|
57
|
+
this.mainClassPageEditing = data.jssState.sitecore.context.pageEditing
|
|
58
|
+
? 'editing-mode'
|
|
59
|
+
: 'prod-mode';
|
|
60
|
+
|
|
61
|
+
const contentStyles = getContentStylesheetLink(
|
|
62
|
+
{ sitecore: data.jssState.sitecore },
|
|
63
|
+
env.sitecoreEdgeContextId,
|
|
64
|
+
env.sitecoreEdgeUrl
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
if (contentStyles) {
|
|
68
|
+
this.linkService.addHeadLinks(contentStyles);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (data.jssState.routeFetchError) {
|
|
73
|
+
if (
|
|
74
|
+
data.jssState.routeFetchError.status >= 400 &&
|
|
75
|
+
data.jssState.routeFetchError.status < 500
|
|
76
|
+
) {
|
|
77
|
+
this.state = LayoutState.NotFound;
|
|
78
|
+
} else {
|
|
79
|
+
this.state = LayoutState.Error;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
this.errorContextData =
|
|
83
|
+
data.jssState.routeFetchError.data && data.jssState.routeFetchError.data.sitecore;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
ngOnDestroy() {
|
|
89
|
+
// important to unsubscribe when the component is destroyed
|
|
90
|
+
this.subscription.unsubscribe();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
setMetadata(routeFields: RouteFields) {
|
|
94
|
+
// set page title, if it exists
|
|
95
|
+
if (routeFields && routeFields.pageTitle) {
|
|
96
|
+
this.meta.setTitle(routeFields.pageTitle.value || 'Page');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
onPlaceholderLoaded(_placeholderName: string) {
|
|
101
|
+
// you may optionally hook to the loaded event for a placeholder,
|
|
102
|
+
// which can be useful for analytics and other DOM-based things that need to know when a placeholder's content is available.
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { ScriptsComponent } from './scripts.component';
|
|
3
|
+
import { JssModule } from '@sitecore-jss/sitecore-jss-angular';
|
|
4
|
+
|
|
5
|
+
@NgModule({
|
|
6
|
+
exports: [ScriptsComponent],
|
|
7
|
+
imports: [JssModule],
|
|
8
|
+
declarations: [ScriptsComponent],
|
|
9
|
+
})
|
|
10
|
+
export class ScriptsModule {}
|
|
@@ -13,7 +13,6 @@ class FallbackPlugin implements ConfigPlugin {
|
|
|
13
13
|
async exec(config: JssConfig) {
|
|
14
14
|
return Object.assign({}, config, {
|
|
15
15
|
defaultLanguage: config.defaultLanguage || 'en',
|
|
16
|
-
sitecoreApiKey: config.sitecoreApiKey || 'no-api-key-set',
|
|
17
16
|
layoutServiceConfigurationName: config.layoutServiceConfigurationName || 'default',
|
|
18
17
|
publicUrl: config.publicUrl || getPublicUrl(),
|
|
19
18
|
});
|
|
@@ -29,6 +29,11 @@ generateConfig(defaultConfig);
|
|
|
29
29
|
* @param {JssConfig} defaultConfig Default configuration.
|
|
30
30
|
*/
|
|
31
31
|
function generateConfig(defaultConfig: JssConfig): void {
|
|
32
|
+
// Handle undefined values
|
|
33
|
+
Object.keys(defaultConfig).forEach(prop => {
|
|
34
|
+
defaultConfig[prop] = defaultConfig[prop] || '';
|
|
35
|
+
}, {});
|
|
36
|
+
|
|
32
37
|
jssConfigFactory
|
|
33
38
|
.create(defaultConfig)
|
|
34
39
|
.then(config => {
|
|
@@ -53,7 +58,9 @@ const config = {};\n`;
|
|
|
53
58
|
|
|
54
59
|
// Set configuration values, allowing override with environment variables
|
|
55
60
|
Object.keys(config).forEach(prop => {
|
|
56
|
-
|
|
61
|
+
// Handle undefined values
|
|
62
|
+
const value = config[prop] || '';
|
|
63
|
+
configText += `config.${prop} = process.env.${constantCase(prop)} || '${value.trim()}';\n`;
|
|
57
64
|
});
|
|
58
65
|
|
|
59
66
|
configText += `module.exports = config;`;
|
|
@@ -7,7 +7,8 @@ import { Plugin, isServerSidePropsContext } from '..';
|
|
|
7
7
|
class ComponentPropsPlugin implements Plugin {
|
|
8
8
|
private componentPropsService: ComponentPropsService;
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
// Make sure to run this plugin last to ensure that the updated layout data is used
|
|
11
|
+
order = 10;
|
|
11
12
|
|
|
12
13
|
constructor() {
|
|
13
14
|
this.componentPropsService = new ComponentPropsService();
|
|
@@ -1,26 +1,85 @@
|
|
|
1
|
+
@import '~bootstrap/scss/functions';
|
|
2
|
+
@import '~bootstrap/scss/variables';
|
|
3
|
+
@import '~bootstrap/scss/mixins';
|
|
4
|
+
|
|
1
5
|
.position-left,
|
|
2
6
|
.position-left * {
|
|
3
|
-
|
|
7
|
+
text-align: left !important;
|
|
4
8
|
}
|
|
5
9
|
|
|
6
10
|
.position-right,
|
|
7
11
|
.position-right * {
|
|
8
|
-
|
|
12
|
+
text-align: right !important;
|
|
9
13
|
}
|
|
10
14
|
|
|
11
15
|
.position-center,
|
|
12
16
|
.position-center * {
|
|
13
|
-
|
|
17
|
+
text-align: center !important;
|
|
14
18
|
}
|
|
15
19
|
|
|
16
20
|
.position-left select {
|
|
17
|
-
|
|
21
|
+
direction: ltr !important;
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
.position-right select {
|
|
21
|
-
|
|
25
|
+
direction: rtl !important;
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
.position-center select {
|
|
25
|
-
|
|
26
|
-
}
|
|
29
|
+
text-align-last: center !important;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@include media-breakpoint-up(sm) {
|
|
33
|
+
.ms-sm-auto {
|
|
34
|
+
margin-left: auto !important;
|
|
35
|
+
margin-right: 0 !important;
|
|
36
|
+
}
|
|
37
|
+
.me-sm-auto {
|
|
38
|
+
margin-right: auto !important;
|
|
39
|
+
margin-left: 0 !important;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@include media-breakpoint-up(md) {
|
|
44
|
+
.ms-md-auto {
|
|
45
|
+
margin-left: auto !important;
|
|
46
|
+
margin-right: 0 !important;
|
|
47
|
+
}
|
|
48
|
+
.me-md-auto {
|
|
49
|
+
margin-right: auto !important;
|
|
50
|
+
margin-left: 0 !important;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@include media-breakpoint-up(lg) {
|
|
55
|
+
.ms-lg-auto {
|
|
56
|
+
margin-left: auto !important;
|
|
57
|
+
margin-right: 0 !important;
|
|
58
|
+
}
|
|
59
|
+
.me-lg-auto {
|
|
60
|
+
margin-right: auto !important;
|
|
61
|
+
margin-left: 0 !important;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@include media-breakpoint-up(xl) {
|
|
66
|
+
.ms-xl-auto {
|
|
67
|
+
margin-left: auto !important;
|
|
68
|
+
margin-right: 0 !important;
|
|
69
|
+
}
|
|
70
|
+
.me-xl-auto {
|
|
71
|
+
margin-right: auto !important;
|
|
72
|
+
margin-left: 0 !important;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@include media-breakpoint-up(xxl) {
|
|
77
|
+
.ms-xxl-auto {
|
|
78
|
+
margin-left: auto !important;
|
|
79
|
+
margin-right: 0 !important;
|
|
80
|
+
}
|
|
81
|
+
.me-xxl-auto {
|
|
82
|
+
margin-right: auto !important;
|
|
83
|
+
margin-left: 0 !important;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
1
|
import {
|
|
3
2
|
ComponentParams,
|
|
4
3
|
ComponentRendering,
|
|
5
4
|
Placeholder,
|
|
6
|
-
useSitecoreContext,
|
|
7
5
|
} from '@sitecore-jss/sitecore-jss-nextjs';
|
|
8
|
-
|
|
9
|
-
const BACKGROUND_REG_EXP = new RegExp(
|
|
10
|
-
/[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/gi
|
|
11
|
-
);
|
|
6
|
+
import React from 'react';
|
|
12
7
|
|
|
13
8
|
interface ComponentProps {
|
|
14
9
|
rendering: ComponentRendering & { params: ComponentParams };
|
|
@@ -16,22 +11,19 @@ interface ComponentProps {
|
|
|
16
11
|
}
|
|
17
12
|
|
|
18
13
|
const DefaultContainer = (props: ComponentProps): JSX.Element => {
|
|
19
|
-
const { sitecoreContext } = useSitecoreContext();
|
|
20
14
|
const containerStyles = props.params && props.params.Styles ? props.params.Styles : '';
|
|
21
15
|
const styles = `${props.params.GridParameters} ${containerStyles}`.trimEnd();
|
|
22
16
|
const phKey = `container-${props.params.DynamicPlaceholderId}`;
|
|
23
17
|
const id = props.params.RenderingIdentifier;
|
|
18
|
+
const mediaUrlPattern = new RegExp(/mediaurl=\"([^"]*)\"/, 'i');
|
|
24
19
|
let backgroundImage = props.params.BackgroundImage as string;
|
|
25
20
|
let backgroundStyle: { [key: string]: string } = {};
|
|
26
21
|
|
|
27
|
-
if (backgroundImage) {
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
?.match(BACKGROUND_REG_EXP)
|
|
31
|
-
?.pop()
|
|
32
|
-
?.replace(/-/gi, '')}`;
|
|
22
|
+
if (backgroundImage && backgroundImage.match(mediaUrlPattern)) {
|
|
23
|
+
const mediaUrl = backgroundImage.match(mediaUrlPattern)?.[1] || '';
|
|
24
|
+
|
|
33
25
|
backgroundStyle = {
|
|
34
|
-
backgroundImage: `url('${
|
|
26
|
+
backgroundImage: `url('${mediaUrl}')`,
|
|
35
27
|
};
|
|
36
28
|
}
|
|
37
29
|
|
package/dist/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/component-themes.ts
CHANGED
|
@@ -4,7 +4,8 @@ import { Plugin } from '..';
|
|
|
4
4
|
import config from 'temp/config';
|
|
5
5
|
|
|
6
6
|
class ComponentThemesPlugin implements Plugin {
|
|
7
|
-
|
|
7
|
+
// Make sure to run this plugin after the personalization plugin, since it relies on the layout data
|
|
8
|
+
order = 10;
|
|
8
9
|
|
|
9
10
|
async exec(props: SitecorePageProps) {
|
|
10
11
|
// Collect FEAAS, BYOC, SXA component themes
|
|
@@ -20,13 +20,14 @@ class PreviewModePlugin implements Plugin {
|
|
|
20
20
|
|
|
21
21
|
// If we're in Pages preview (editing) Metadata Edit Mode, prefetch the editing data
|
|
22
22
|
if (isEditingMetadataPreviewData(context.previewData)) {
|
|
23
|
-
const { site, itemId, language, version, variantIds } = context.previewData;
|
|
23
|
+
const { site, itemId, language, version, variantIds, layoutKind } = context.previewData;
|
|
24
24
|
|
|
25
25
|
const data = await graphQLEditingService.fetchEditingData({
|
|
26
26
|
siteName: site,
|
|
27
27
|
itemId,
|
|
28
28
|
language,
|
|
29
29
|
version,
|
|
30
|
+
layoutKind,
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
if (!data) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
|
2
|
+
|
|
3
|
+
# dependencies
|
|
4
|
+
/node_modules
|
|
5
|
+
|
|
6
|
+
# local env files
|
|
7
|
+
.env.local
|
|
8
|
+
.env.*.local
|
|
9
|
+
|
|
10
|
+
# IDE - VSCode
|
|
11
|
+
.vscode/*
|
|
12
|
+
!.vscode/settings.json
|
|
13
|
+
!.vscode/tasks.json
|
|
14
|
+
!.vscode/launch.json
|
|
15
|
+
!.vscode/extensions.json
|
|
16
|
+
|
|
17
|
+
# System Files
|
|
18
|
+
.DS_Store
|
|
19
|
+
Thumbs.db
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
|
2
|
+
|
|
3
|
+
# dependencies
|
|
4
|
+
/node_modules
|
|
5
|
+
|
|
6
|
+
# local env files
|
|
7
|
+
.env.local
|
|
8
|
+
.env.*.local
|
|
9
|
+
|
|
10
|
+
# IDE - VSCode
|
|
11
|
+
.vscode/*
|
|
12
|
+
!.vscode/settings.json
|
|
13
|
+
!.vscode/tasks.json
|
|
14
|
+
!.vscode/launch.json
|
|
15
|
+
!.vscode/extensions.json
|
|
16
|
+
|
|
17
|
+
# System Files
|
|
18
|
+
.DS_Store
|
|
19
|
+
Thumbs.db
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { headlessProxy } from '@sitecore-jss/sitecore-jss-proxy';
|
|
2
2
|
import fs from 'fs';
|
|
3
3
|
import { RestDictionaryService } from '@sitecore-jss/sitecore-jss/i18n';
|
|
4
4
|
import { httpAgentsConfig } from './httpAgents';
|
|
@@ -13,7 +13,7 @@ let siteName = process.env.SITECORE_SITE_NAME || appName;
|
|
|
13
13
|
|
|
14
14
|
const bundlePath = process.env.SITECORE_JSS_SERVER_BUNDLE || `../dist/${appName}/server.bundle`;
|
|
15
15
|
|
|
16
|
-
const serverBundle = require(bundlePath) as ServerBundle;
|
|
16
|
+
const serverBundle = require(bundlePath) as headlessProxy.ServerBundle;
|
|
17
17
|
|
|
18
18
|
httpAgentsConfig.setUpDefaultAgents(serverBundle);
|
|
19
19
|
|
|
@@ -33,7 +33,7 @@ const dictionaryService = new RestDictionaryService({
|
|
|
33
33
|
/**
|
|
34
34
|
* @type {ProxyConfig}
|
|
35
35
|
*/
|
|
36
|
-
export const config: ProxyConfig = {
|
|
36
|
+
export const config: headlessProxy.ProxyConfig = {
|
|
37
37
|
/**
|
|
38
38
|
* The require'd server.bundle.js file from your pre-built JSS app
|
|
39
39
|
*/
|