@merkle-open/magnolia-headless-frontend-nextjs 0.0.4 → 0.0.6
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/package.json +1 -1
- package/src/dynamic-page/AbstractDynamicErrorPage.tsx +3 -1
- package/src/dynamic-page/AbstractDynamicPage.tsx +5 -4
- package/src/dynamic-page/DynamicErrorPage.tsx +3 -1
- package/src/dynamic-page/DynamicErrorPageGlobal.tsx +3 -1
- package/src/dynamic-page/DynamicPage.tsx +3 -1
- package/src/helper/MagnoliaPageRestClient.ts +4 -10
- package/src/helper/MetadataProvider.ts +1 -1
- package/src/helper/_Index.ts +0 -1
- package/src/templates/_Dependencies.ts +2 -0
- package/src/templates/_Index.ts +5 -0
- package/src/templates/areas/BaseProps.ts +3 -5
- package/src/templates/areas/__magnolia-editable-area/EditableArea.tsx +42 -19
- package/src/templates/areas/__magnolia-editable-area/EditableAreaProps.ts +3 -1
- package/src/templates/components/BaseProps.ts +3 -3
- package/src/templates/components/__magnolia-editable-component/EditableComponent.tsx +20 -15
- package/src/templates/components/__magnolia-editable-component/EditableComponentProps.ts +4 -1
- package/src/templates/elements/_error/ErrorBoundary.tsx +5 -5
- package/src/templates/pages/BaseProps.ts +28 -3
- package/src/templates/pages/__magnolia-editable-page/EditablePage.tsx +12 -8
- package/src/templates/pages/__magnolia-editable-page/EditablePageProps.ts +3 -2
- package/src/helper/MetaProps.ts +0 -23
package/package.json
CHANGED
|
@@ -10,6 +10,7 @@ import type { FrontendApiEndpointsProvider, HeadlessConfigProviderI } from '../c
|
|
|
10
10
|
import { type StylesheetProviderI } from '../config/StylesheetProvider.ts';
|
|
11
11
|
import { type ComponentMappingsProviderI } from '../config/ComponentMappingsProvider.ts';
|
|
12
12
|
import { ThemeValidator } from '../helper/ThemeValidator.ts';
|
|
13
|
+
import { EditablePage } from '../templates/pages/__magnolia-editable-page/EditablePage.tsx';
|
|
13
14
|
|
|
14
15
|
export abstract class AbstractDynamicErrorPage extends AbstractDynamicPage {
|
|
15
16
|
private readonly frontendApisProvider: FrontendApiEndpointsProvider;
|
|
@@ -19,11 +20,12 @@ export abstract class AbstractDynamicErrorPage extends AbstractDynamicPage {
|
|
|
19
20
|
configProvider: HeadlessConfigProviderI,
|
|
20
21
|
StylesheetProviderI: StylesheetProviderI,
|
|
21
22
|
themeValidator: ThemeValidator,
|
|
23
|
+
editablePage: EditablePage,
|
|
22
24
|
private readonly restClient: RestClient,
|
|
23
25
|
private readonly staticErrorPage: StaticErrorPage,
|
|
24
26
|
protected readonly magnoliaContextProvider: MagnoliaContextProvider,
|
|
25
27
|
) {
|
|
26
|
-
super(componentMappingsProvider, StylesheetProviderI, themeValidator);
|
|
28
|
+
super(componentMappingsProvider, StylesheetProviderI, themeValidator, editablePage);
|
|
27
29
|
this.frontendApisProvider = configProvider.get().frontendApisProvider;
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ExtendedMagnoliaContext } from '../helper/MagnoliaContextProvider.ts';
|
|
2
|
-
import
|
|
2
|
+
import PageProps from '../templates/pages/BaseProps.ts';
|
|
3
3
|
import { MgnlTemplateAnnotations } from '@magnolia/frontend-helpers-base';
|
|
4
4
|
import React, { ReactNode } from 'react';
|
|
5
5
|
import { MagnoliaConfig, RefService } from '@magnolia/react-editor';
|
|
@@ -13,9 +13,10 @@ export abstract class AbstractDynamicPage {
|
|
|
13
13
|
private readonly componentMappingsProvider: ComponentMappingsProviderI,
|
|
14
14
|
private readonly StylesheetProviderI: StylesheetProviderI,
|
|
15
15
|
private readonly themeValidator: ThemeValidator,
|
|
16
|
+
private readonly editablePage: EditablePage,
|
|
16
17
|
) {}
|
|
17
18
|
|
|
18
|
-
protected renderBase(magnoliaContext: ExtendedMagnoliaContext, content:
|
|
19
|
+
protected renderBase(magnoliaContext: ExtendedMagnoliaContext, content: PageProps, templateAnnotations: MgnlTemplateAnnotations): ReactNode {
|
|
19
20
|
const config: MagnoliaConfig = {
|
|
20
21
|
componentMappings: this.componentMappingsProvider.getComponentMappings(),
|
|
21
22
|
};
|
|
@@ -29,12 +30,12 @@ export abstract class AbstractDynamicPage {
|
|
|
29
30
|
{this.getStylesheet(magnoliaContext, content).map((stylesheet) => (
|
|
30
31
|
<link rel="stylesheet" href={stylesheet} precedence="high" />
|
|
31
32
|
))}
|
|
32
|
-
|
|
33
|
+
{this.editablePage.render({ content, config, templateAnnotations, magnoliaContext })}
|
|
33
34
|
</div>
|
|
34
35
|
);
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
private getStylesheet(magnoliaContext: ExtendedMagnoliaContext, content:
|
|
38
|
+
private getStylesheet(magnoliaContext: ExtendedMagnoliaContext, content: PageProps): string[] {
|
|
38
39
|
return this.StylesheetProviderI.get(magnoliaContext, this.themeValidator.getValidatedTheme(content.theme));
|
|
39
40
|
}
|
|
40
41
|
}
|
|
@@ -13,6 +13,7 @@ import { type ComponentMappingsProviderI } from '../config/ComponentMappingsProv
|
|
|
13
13
|
import { StaticErrorPage } from '../templates/pages/_error-static/ErrorStatic.tsx';
|
|
14
14
|
import { CombinedComponentMappingsProvider } from '../templates/ComponentMappingsProvider.ts';
|
|
15
15
|
import { ThemeValidator } from '../helper/ThemeValidator.ts';
|
|
16
|
+
import { EditablePage } from '../templates/pages/__magnolia-editable-page/EditablePage.tsx';
|
|
16
17
|
|
|
17
18
|
@injectable()
|
|
18
19
|
export class DynamicErrorPage extends AbstractDynamicErrorPage {
|
|
@@ -21,11 +22,12 @@ export class DynamicErrorPage extends AbstractDynamicErrorPage {
|
|
|
21
22
|
@inject(HEADLESS_CONFIG_PROVIDER_TOKEN) configProvider: HeadlessConfigProviderI,
|
|
22
23
|
@inject(STYLESHEET_PROVIDER_TOKEN) StylesheetProviderI: StylesheetProviderI,
|
|
23
24
|
@inject(ThemeValidator) themeValidator: ThemeValidator,
|
|
25
|
+
@inject(EditablePage) editablePage: EditablePage,
|
|
24
26
|
@inject(RestClient) restClient: RestClient,
|
|
25
27
|
@inject(StaticErrorPage) staticErrorPage: StaticErrorPage,
|
|
26
28
|
@inject(MagnoliaContextProvider) magnoliaContextProvider: MagnoliaContextProvider,
|
|
27
29
|
) {
|
|
28
|
-
super(componentMappingsProvider, configProvider, StylesheetProviderI, themeValidator, restClient, staticErrorPage, magnoliaContextProvider);
|
|
30
|
+
super(componentMappingsProvider, configProvider, StylesheetProviderI, themeValidator, editablePage, restClient, staticErrorPage, magnoliaContextProvider);
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
public render(errorType: ErrorType): ReactNode {
|
|
@@ -14,6 +14,7 @@ import { type ComponentMappingsProviderI } from '../config/ComponentMappingsProv
|
|
|
14
14
|
import { StaticErrorPage } from '../templates/pages/_error-static/ErrorStatic.tsx';
|
|
15
15
|
import { CombinedComponentMappingsProvider } from '../templates/ComponentMappingsProvider.ts';
|
|
16
16
|
import { ThemeValidator } from '../helper/ThemeValidator.ts';
|
|
17
|
+
import { EditablePage } from '../templates/pages/__magnolia-editable-page/EditablePage.tsx';
|
|
17
18
|
|
|
18
19
|
@injectable()
|
|
19
20
|
export class DynamicErrorPageGlobal extends AbstractDynamicErrorPage {
|
|
@@ -22,12 +23,13 @@ export class DynamicErrorPageGlobal extends AbstractDynamicErrorPage {
|
|
|
22
23
|
@inject(HEADLESS_CONFIG_PROVIDER_TOKEN) configProvider: HeadlessConfigProviderI,
|
|
23
24
|
@inject(STYLESHEET_PROVIDER_TOKEN) StylesheetProviderI: StylesheetProviderI,
|
|
24
25
|
@inject(ThemeValidator) themeValidator: ThemeValidator,
|
|
26
|
+
@inject(EditablePage) editablePage: EditablePage,
|
|
25
27
|
@inject(RestClient) restClient: RestClient,
|
|
26
28
|
@inject(StaticErrorPage) staticErrorPage: StaticErrorPage,
|
|
27
29
|
@inject(MagnoliaContextProvider) magnoliaContextProvider: MagnoliaContextProvider,
|
|
28
30
|
@inject(DynamicPageLayout) private readonly dynamicPageLayout: DynamicPageLayout,
|
|
29
31
|
) {
|
|
30
|
-
super(componentMappingsProvider, configProvider, StylesheetProviderI, themeValidator, restClient, staticErrorPage, magnoliaContextProvider);
|
|
32
|
+
super(componentMappingsProvider, configProvider, StylesheetProviderI, themeValidator, editablePage, restClient, staticErrorPage, magnoliaContextProvider);
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
public render(errorType: ErrorType): ReactNode {
|
|
@@ -14,6 +14,7 @@ import { type StylesheetProviderI, STYLESHEET_PROVIDER_TOKEN } from '../config/S
|
|
|
14
14
|
import { type ComponentMappingsProviderI } from '../config/ComponentMappingsProvider.ts';
|
|
15
15
|
import { CombinedComponentMappingsProvider } from '../templates/ComponentMappingsProvider.ts';
|
|
16
16
|
import { ThemeValidator } from '../helper/ThemeValidator.ts';
|
|
17
|
+
import { EditablePage } from '../templates/pages/__magnolia-editable-page/EditablePage.tsx';
|
|
17
18
|
|
|
18
19
|
@injectable()
|
|
19
20
|
export class DynamicPage extends AbstractDynamicPage {
|
|
@@ -21,12 +22,13 @@ export class DynamicPage extends AbstractDynamicPage {
|
|
|
21
22
|
@inject(CombinedComponentMappingsProvider) componentMappingsProvider: ComponentMappingsProviderI,
|
|
22
23
|
@inject(STYLESHEET_PROVIDER_TOKEN) StylesheetProviderI: StylesheetProviderI,
|
|
23
24
|
@inject(ThemeValidator) themeValidator: ThemeValidator,
|
|
25
|
+
@inject(EditablePage) editablePage: EditablePage,
|
|
24
26
|
@inject(MagnoliaContextProvider) private readonly magnoliaContextProvider: MagnoliaContextProvider,
|
|
25
27
|
@inject(MagnoliaPageRestClient) private readonly magnoliaPageRestClient: MagnoliaPageRestClient,
|
|
26
28
|
@inject(MetadataProvider) private readonly metadataProvider: MetadataProvider,
|
|
27
29
|
@inject(UrlProvider) private readonly urlProvider: UrlProvider,
|
|
28
30
|
) {
|
|
29
|
-
super(componentMappingsProvider, StylesheetProviderI, themeValidator);
|
|
31
|
+
super(componentMappingsProvider, StylesheetProviderI, themeValidator, editablePage);
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
public async render(pageProps: PageProps): Promise<ReactNode> {
|
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import { IMagnoliaContext,
|
|
1
|
+
import { IMagnoliaContext, MgnlTemplateAnnotations } from '@magnolia/frontend-helpers-base';
|
|
2
2
|
import { RestClient } from './RestClient.ts';
|
|
3
3
|
import { MagnoliaContextProvider } from './MagnoliaContextProvider.ts';
|
|
4
|
-
import
|
|
4
|
+
import PageProps from '../templates/pages/BaseProps.ts';
|
|
5
5
|
import { inject, injectable } from 'tsyringe';
|
|
6
6
|
import { type HeadlessConfigProviderI, MagnoliaApiEndpointsProvider, HEADLESS_CONFIG_PROVIDER_TOKEN } from '../config/ConfigProvider.ts';
|
|
7
7
|
|
|
8
|
-
export interface Content extends MgnlContent {
|
|
9
|
-
cspHeader?: string;
|
|
10
|
-
meta: MetaProps;
|
|
11
|
-
theme?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
8
|
export enum ErrorType {
|
|
15
9
|
PAGE_NOT_FOUND = '404',
|
|
16
10
|
INTERNAL_SERVER_ERROR = '500',
|
|
@@ -28,7 +22,7 @@ export class MagnoliaPageRestClient {
|
|
|
28
22
|
this.apisProvider = configProvider.get().magnoliaApisProvider;
|
|
29
23
|
}
|
|
30
24
|
|
|
31
|
-
public async getErrorPageContent(url: URL, errorType: ErrorType): Promise<
|
|
25
|
+
public async getErrorPageContent(url: URL, errorType: ErrorType): Promise<PageProps> {
|
|
32
26
|
const magnoliaContext = this.magnoliaContextProvider.getMagnoliaContext(url);
|
|
33
27
|
const queryParams = new URLSearchParams();
|
|
34
28
|
queryParams.set('errorCode', errorType.toString());
|
|
@@ -37,7 +31,7 @@ export class MagnoliaPageRestClient {
|
|
|
37
31
|
return this.restClient.fetchMagnoliaBasicAuth(errorPagesApiUrl).then((response) => this.restClient.getJson(errorPagesApiUrl, response));
|
|
38
32
|
}
|
|
39
33
|
|
|
40
|
-
public async getPageContent(url: URL): Promise<
|
|
34
|
+
public async getPageContent(url: URL): Promise<PageProps> {
|
|
41
35
|
const magnoliaContext = this.magnoliaContextProvider.getMagnoliaContext(url);
|
|
42
36
|
const queryParams = new URLSearchParams(magnoliaContext.searchParams);
|
|
43
37
|
queryParams.delete('jwt');
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import type { OpenGraph } from 'next/dist/lib/metadata/types/opengraph-types';
|
|
3
3
|
// @ts-expect-error: Next.js missing exports prevents ESM resolution with 'nodenext'.
|
|
4
4
|
import type { Twitter } from 'next/dist/lib/metadata/types/twitter-types';
|
|
5
|
-
import MetaProps,
|
|
5
|
+
import { MetaProps, OpenGraph as HeadlessOpenGraph } from '../templates/pages/BaseProps.ts';
|
|
6
6
|
import { Metadata } from 'next';
|
|
7
7
|
import { injectable } from 'tsyringe';
|
|
8
8
|
|
package/src/helper/_Index.ts
CHANGED
|
@@ -2,8 +2,10 @@ import { DependencyContainer } from 'tsyringe';
|
|
|
2
2
|
|
|
3
3
|
import { CombinedComponentMappingsProvider } from './ComponentMappingsProvider.ts';
|
|
4
4
|
import { StaticErrorPage } from './pages/_error-static/ErrorStatic.tsx';
|
|
5
|
+
import { EditablePage } from './pages/__magnolia-editable-page/EditablePage.tsx';
|
|
5
6
|
|
|
6
7
|
export default function register(container: DependencyContainer) {
|
|
7
8
|
container.register(CombinedComponentMappingsProvider, { useClass: CombinedComponentMappingsProvider });
|
|
8
9
|
container.register(StaticErrorPage, { useClass: StaticErrorPage });
|
|
10
|
+
container.register(EditablePage, { useClass: EditablePage });
|
|
9
11
|
}
|
package/src/templates/_Index.ts
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
export * from './ComponentMappingsProvider.ts';
|
|
2
2
|
export type { default as PageBaseProps } from './pages/BaseProps.ts';
|
|
3
|
+
export * from './pages/__magnolia-editable-page/EditablePage.tsx';
|
|
4
|
+
export type { default as EditablePageProps } from './pages/__magnolia-editable-page/EditablePageProps.ts';
|
|
3
5
|
export type { default as AreaBaseProps } from './areas/BaseProps.ts';
|
|
4
6
|
export * from './areas/__magnolia-editable-area/EditableArea.tsx';
|
|
7
|
+
export type { default as EditableAreaProps } from './areas/__magnolia-editable-area/EditableAreaProps.ts';
|
|
5
8
|
export type { default as ComponentBaseProps } from './components/BaseProps.ts';
|
|
9
|
+
export * from './components/__magnolia-editable-component/EditableComponent.tsx';
|
|
10
|
+
export type { default as EditableComponentProps } from './components/__magnolia-editable-component/EditableComponentProps.ts';
|
|
6
11
|
export * from './pages/_error-static/ErrorStatic.tsx';
|
|
7
12
|
export type { default as StaticErrorPageProps } from './pages/_error-static/ErrorStaticProps.ts';
|
|
@@ -1,27 +1,50 @@
|
|
|
1
|
-
import { EditableArea as MagnoliaEditableArea } from '@magnolia/react-editor';
|
|
2
|
-
import React, { ReactNode } from 'react';
|
|
1
|
+
import { EditableArea as MagnoliaEditableArea, RefService } from '@magnolia/react-editor';
|
|
2
|
+
import React, { ReactElement, ReactNode } from 'react';
|
|
3
3
|
import EditableAreaProps from './EditableAreaProps.ts';
|
|
4
|
-
import { ContentRendererService, MgnlContent } from '@magnolia/frontend-helpers-base';
|
|
4
|
+
import { ContentRendererService, IMagnoliaContext, MgnlContent } from '@magnolia/frontend-helpers-base';
|
|
5
5
|
import { EditableComponent } from '../../components/__magnolia-editable-component/EditableComponent.tsx';
|
|
6
6
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
export class EditableAreaClass {
|
|
8
|
+
constructor(private readonly editableComponent: EditableComponent) {}
|
|
9
|
+
|
|
10
|
+
public render(props: EditableAreaProps): ReactNode {
|
|
11
|
+
const { content, additionalContent, additionalComponentContent } = props;
|
|
12
|
+
const mergedContent = this.merge(content, additionalContent);
|
|
13
|
+
const mergedComponentContents: MgnlContent[] = content?.['@nodes']?.map((nodeName: string): MgnlContent => this.merge(content[nodeName], additionalComponentContent)) || [];
|
|
14
|
+
const children: ReactElement[] = mergedComponentContents?.map((content: MgnlContent, index: number): ReactElement => this.renderComponent(content, index) as ReactElement);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
this.shouldRender(children.length > 0, props.renderEmpty) && (
|
|
18
|
+
<MagnoliaEditableArea {...props} content={mergedContent}>
|
|
19
|
+
{children}
|
|
20
|
+
</MagnoliaEditableArea>
|
|
21
|
+
)
|
|
22
|
+
);
|
|
23
|
+
}
|
|
11
24
|
|
|
12
|
-
|
|
13
|
-
|
|
25
|
+
protected renderComponent(content: any, index: number): ReactNode {
|
|
26
|
+
return this.editableComponent.render({ key: ContentRendererService.buildKey(content), content: content, index: index });
|
|
27
|
+
}
|
|
14
28
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
{
|
|
18
|
-
|
|
19
|
-
|
|
29
|
+
protected merge(...content: any[]): any {
|
|
30
|
+
return content.reduce((previousValue: any, currentValue: any): any => {
|
|
31
|
+
return {
|
|
32
|
+
...previousValue,
|
|
33
|
+
...currentValue,
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
protected shouldRender(hasChildren: boolean, renderEmpty?: boolean): boolean {
|
|
39
|
+
if (renderEmpty) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
const magnoliaContext = RefService.getMagnoliaContextRef<IMagnoliaContext>();
|
|
43
|
+
const isEditMode = magnoliaContext?.isMagnoliaEdit;
|
|
44
|
+
return isEditMode || hasChildren;
|
|
45
|
+
}
|
|
20
46
|
}
|
|
21
47
|
|
|
22
|
-
function
|
|
23
|
-
return
|
|
24
|
-
...first,
|
|
25
|
-
...second,
|
|
26
|
-
};
|
|
48
|
+
export function EditableArea(props: EditableAreaProps): ReactNode {
|
|
49
|
+
return new EditableAreaClass(new EditableComponent()).render(props);
|
|
27
50
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ReactComponentLike, ReactNodeLike } from 'prop-types';
|
|
2
|
+
import AreaProps from '../BaseProps.ts';
|
|
2
3
|
|
|
3
4
|
export default interface EditableAreaProps {
|
|
4
|
-
content:
|
|
5
|
+
content: AreaProps;
|
|
5
6
|
parentTemplateId?: string;
|
|
6
7
|
className?: any;
|
|
7
8
|
elementType?: any;
|
|
@@ -9,4 +10,5 @@ export default interface EditableAreaProps {
|
|
|
9
10
|
children?: ReactNodeLike;
|
|
10
11
|
additionalContent?: any;
|
|
11
12
|
additionalComponentContent?: any;
|
|
13
|
+
renderEmpty?: boolean;
|
|
12
14
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
}
|
|
1
|
+
import { MgnlContent } from '@magnolia/frontend-helpers-base';
|
|
2
|
+
|
|
3
|
+
export default interface Props extends MgnlContent {}
|
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
import { EditableComponent as MagnoliaEditableComponent, RefService } from '@magnolia/react-editor';
|
|
2
2
|
import React, { ReactNode } from 'react';
|
|
3
3
|
import EditableComponentProps from './EditableComponentProps.ts';
|
|
4
|
-
import { IMagnoliaContext } from '@magnolia/frontend-helpers-base';
|
|
4
|
+
import { IMagnoliaContext, MgnlContent } from '@magnolia/frontend-helpers-base';
|
|
5
5
|
import ErrorBoundary from '../../elements/_error/ErrorBoundary.tsx';
|
|
6
6
|
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export class EditableComponent {
|
|
8
|
+
public render(props: EditableComponentProps): ReactNode {
|
|
9
|
+
const { content, additionalContent } = props;
|
|
10
|
+
const magnoliaContext: IMagnoliaContext = RefService.getMagnoliaContextRef<IMagnoliaContext>();
|
|
11
|
+
const mergedContent: MgnlContent = this.merge(content, additionalContent);
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
13
|
+
return (
|
|
14
|
+
<ErrorBoundary isEditMode={magnoliaContext.isMagnoliaEdit} throwNotEditMode={false} path={content!['@path']}>
|
|
15
|
+
<MagnoliaEditableComponent {...props} content={mergedContent} />
|
|
16
|
+
</ErrorBoundary>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
protected merge(...content: any[]): any {
|
|
21
|
+
return content.reduce((previousValue: any, currentValue: any): any => {
|
|
22
|
+
return {
|
|
23
|
+
...previousValue,
|
|
24
|
+
...currentValue,
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
}
|
|
23
28
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import React, { ReactNode } from 'react';
|
|
4
|
-
import
|
|
3
|
+
import React, { ReactNode, Suspense } from 'react';
|
|
4
|
+
import ErrorElement from './ErrorElement.tsx';
|
|
5
5
|
|
|
6
6
|
interface ErrorState {
|
|
7
|
-
error: Error;
|
|
7
|
+
error: Error | null;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
interface ErrorProps {
|
|
@@ -26,8 +26,8 @@ export default class ErrorBoundary extends React.Component<ErrorProps, ErrorStat
|
|
|
26
26
|
|
|
27
27
|
render() {
|
|
28
28
|
if (this.state.error) {
|
|
29
|
-
return <
|
|
29
|
+
return <ErrorElement editMode={this.props.isEditMode} throwNotEditMode={this.props.throwNotEditMode} path={this.props.path} msg={this.state.error.message} />;
|
|
30
30
|
}
|
|
31
|
-
return this.props.children
|
|
31
|
+
return <Suspense fallback={null}>{this.props.children}</Suspense>;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -1,4 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { MgnlContent } from '@magnolia/frontend-helpers-base';
|
|
2
|
+
|
|
3
|
+
export interface HrefLangLink {
|
|
4
|
+
language: string;
|
|
5
|
+
href: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface OpenGraph {
|
|
9
|
+
siteName?: string;
|
|
10
|
+
title: string;
|
|
11
|
+
description: string;
|
|
12
|
+
url: string;
|
|
13
|
+
image?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface MetaProps {
|
|
17
|
+
seoTitle: string;
|
|
18
|
+
description: string;
|
|
19
|
+
keywords: string[];
|
|
20
|
+
robots?: string;
|
|
21
|
+
canonical: string;
|
|
22
|
+
openGraph: OpenGraph;
|
|
23
|
+
hrefLangLinks: HrefLangLink[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default interface Props extends MgnlContent {
|
|
27
|
+
meta: MetaProps;
|
|
28
|
+
theme?: string;
|
|
4
29
|
}
|
|
@@ -3,14 +3,18 @@ import React, { ReactNode } from 'react';
|
|
|
3
3
|
import EditablePageProps from './EditablePageProps.ts';
|
|
4
4
|
import { IMagnoliaContext } from '@magnolia/frontend-helpers-base';
|
|
5
5
|
import ErrorBoundary from '../../elements/_error/ErrorBoundary.tsx';
|
|
6
|
+
import { injectable } from 'tsyringe';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
@injectable()
|
|
9
|
+
export class EditablePage {
|
|
10
|
+
public render(props: EditablePageProps): ReactNode {
|
|
11
|
+
const { content } = props;
|
|
12
|
+
const magnoliaContext: IMagnoliaContext = RefService.getMagnoliaContextRef<IMagnoliaContext>();
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
return (
|
|
15
|
+
<ErrorBoundary isEditMode={magnoliaContext.isMagnoliaEdit} throwNotEditMode={true} path={content!['@path']}>
|
|
16
|
+
<MagnoliaEditablePage {...props} />
|
|
17
|
+
</ErrorBoundary>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
16
20
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { IMagnoliaContext,
|
|
1
|
+
import { IMagnoliaContext, MgnlTemplateAnnotations } from '@magnolia/frontend-helpers-base';
|
|
2
2
|
import { MagnoliaConfig } from '@magnolia/react-editor';
|
|
3
3
|
import React from 'react';
|
|
4
|
+
import PageProps from '../BaseProps.ts';
|
|
4
5
|
|
|
5
6
|
export default interface EditablePageProps {
|
|
6
7
|
children?: React.ReactElement | React.ReactElement[] | null;
|
|
7
|
-
content:
|
|
8
|
+
content: PageProps;
|
|
8
9
|
templateAnnotations: MgnlTemplateAnnotations;
|
|
9
10
|
config: MagnoliaConfig;
|
|
10
11
|
magnoliaContext: IMagnoliaContext;
|
package/src/helper/MetaProps.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export interface HrefLangLink {
|
|
2
|
-
language: string;
|
|
3
|
-
href: string;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export interface OpenGraph {
|
|
7
|
-
siteName?: string;
|
|
8
|
-
title: string;
|
|
9
|
-
description: string;
|
|
10
|
-
url: string;
|
|
11
|
-
image?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default interface MetaProps {
|
|
15
|
-
seoTitle: string;
|
|
16
|
-
description: string;
|
|
17
|
-
keywords: string[];
|
|
18
|
-
robots?: string;
|
|
19
|
-
canonical: string;
|
|
20
|
-
openGraph: OpenGraph;
|
|
21
|
-
hrefLangLinks: HrefLangLink[];
|
|
22
|
-
theme: string;
|
|
23
|
-
}
|