@enonic/nextjs-adapter 2.0.1 → 2.0.2
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/ComponentRegistry.d.ts +64 -0
- package/ComponentRegistry.js +121 -0
- package/UrlProcessor.d.ts +25 -0
- package/{src/UrlProcessor.ts → UrlProcessor.js} +35 -53
- package/baseMappings.d.ts +1 -0
- package/{src/baseMappings.ts → baseMappings.js} +3 -13
- package/guillotine/fetchContent.d.ts +49 -0
- package/{src/guillotine/fetchContent.ts → guillotine/fetchContent.js} +243 -493
- package/guillotine/getMetaData.d.ts +94 -0
- package/guillotine/getMetaData.js +128 -0
- package/{src/index.ts → index.d.ts} +1 -1
- package/index.js +5 -0
- package/package.json +2 -2
- package/query/Shortcut.d.ts +1 -0
- package/server/ClearableFileCache.d.ts +31 -0
- package/server/ClearableFileCache.js +472 -0
- package/server/cache.d.ts +2 -0
- package/server/cache.js +129 -0
- package/server/index.d.ts +5 -0
- package/server/index.js +132 -0
- package/utils.d.ts +114 -0
- package/{src/utils.ts → utils.js} +69 -148
- package/views/BaseComponent.d.ts +25 -0
- package/{src/views/BaseComponent.tsx → views/BaseComponent.jsx} +39 -73
- package/views/BaseContent.d.ts +4 -0
- package/{src/views/BaseContent.tsx → views/BaseContent.jsx} +17 -24
- package/views/BaseLayout.d.ts +17 -0
- package/views/BaseLayout.jsx +24 -0
- package/views/BaseMacro.d.ts +16 -0
- package/{src/views/BaseMacro.tsx → views/BaseMacro.jsx} +29 -45
- package/views/BasePage.d.ts +19 -0
- package/views/BasePage.jsx +34 -0
- package/views/BasePart.d.ts +19 -0
- package/views/BasePart.jsx +24 -0
- package/views/Empty.d.ts +3 -0
- package/{src/views/Empty.tsx → views/Empty.jsx} +0 -2
- package/views/Fragment.d.ts +10 -0
- package/views/Fragment.jsx +30 -0
- package/views/MainView.d.ts +4 -0
- package/views/MainView.jsx +14 -0
- package/views/Region.d.ts +20 -0
- package/views/Region.jsx +52 -0
- package/views/RichTextView.d.ts +16 -0
- package/{src/views/RichTextView.tsx → views/RichTextView.jsx} +10 -31
- package/views/SingleComponent.d.ts +5 -0
- package/{src/views/SingleComponent.tsx → views/SingleComponent.jsx} +2 -8
- package/views/StaticContent.d.ts +15 -0
- package/views/StaticContent.jsx +36 -0
- package/views/Text.d.ts +9 -0
- package/views/Text.jsx +4 -0
- package/views/macros/DefaultMacro.d.ts +4 -0
- package/views/macros/DefaultMacro.jsx +3 -0
- package/views/macros/DisableMacro.d.ts +3 -0
- package/views/macros/DisableMacro.jsx +2 -0
- package/.eslint-childrc.js +0 -17
- package/.eslintrc.js +0 -15
- package/.github/dependabot.yml +0 -20
- package/.github/pull-merger.yml +0 -1
- package/.github/workflows/release.yml +0 -39
- package/LICENSE +0 -201
- package/RELEASE.md +0 -75
- package/server/.eslintrc.js +0 -11
- package/server/ClearableFileCache.ts +0 -410
- package/server/cache.ts +0 -50
- package/server/index.ts +0 -74
- package/server/tsconfig.json +0 -23
- package/src/.eslintrc.js +0 -11
- package/src/ComponentRegistry.ts +0 -189
- package/src/guillotine/getMetaData.ts +0 -246
- package/src/tsconfig.json +0 -20
- package/src/views/BaseLayout.tsx +0 -45
- package/src/views/BasePage.tsx +0 -56
- package/src/views/BasePart.tsx +0 -50
- package/src/views/Fragment.tsx +0 -45
- package/src/views/MainView.tsx +0 -21
- package/src/views/Region.tsx +0 -89
- package/src/views/StaticContent.tsx +0 -40
- package/src/views/Text.tsx +0 -15
- package/src/views/macros/DefaultMacro.tsx +0 -9
- package/src/views/macros/DisableMacro.tsx +0 -8
- /package/{src/query/Shortcut.ts → query/Shortcut.js} +0 -0
|
@@ -1,45 +1,31 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {MetaData, PageComponent} from '../guillotine/getMetaData';
|
|
5
|
-
import {ComponentRegistry} from '../ComponentRegistry';
|
|
2
|
+
import { IS_DEV_MODE, PORTAL_COMPONENT_ATTRIBUTE, RENDER_MODE, XP_COMPONENT_TYPE } from '../utils';
|
|
3
|
+
import { ComponentRegistry } from '../ComponentRegistry';
|
|
6
4
|
import Empty from './Empty';
|
|
7
5
|
import * as ReactDOMServer from 'react-dom/server';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
component: PageComponent;
|
|
12
|
-
meta: MetaData;
|
|
13
|
-
common?: any; // Content is passed down for optional consumption in componentviews.
|
|
14
|
-
// TODO: Use a react contextprovider instead of "manually" passing everything down
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const BaseComponent = ({component, meta, common}: BaseComponentProps) => {
|
|
18
|
-
const {type, error} = component;
|
|
6
|
+
const BaseComponent = ({ component, meta, common }) => {
|
|
7
|
+
var _a;
|
|
8
|
+
const { type, error } = component;
|
|
19
9
|
const cmpData = component[type];
|
|
20
10
|
const descriptor = cmpData && 'descriptor' in cmpData ? cmpData.descriptor : undefined;
|
|
21
|
-
|
|
22
|
-
let ComponentView: JSX.Element | null;
|
|
23
|
-
|
|
11
|
+
let ComponentView;
|
|
24
12
|
if (error) {
|
|
25
13
|
// renders error component when rendering whole page
|
|
26
14
|
console.warn(`BaseComponent: ${type} '${descriptor}' error: ${error}`);
|
|
27
|
-
ComponentView = shouldShowErrorView(meta) ? <ErrorComponent type={type} reason={error} descriptor={descriptor}/> : <Empty/>;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const ViewFn = ComponentRegistry.getComponent(type)?.view;
|
|
15
|
+
ComponentView = shouldShowErrorView(meta) ? <ErrorComponent type={type} reason={error} descriptor={descriptor}/> : <Empty />;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
const ViewFn = (_a = ComponentRegistry.getComponent(type)) === null || _a === void 0 ? void 0 : _a.view;
|
|
32
19
|
if (!ViewFn) {
|
|
33
20
|
// show missing component kind, i.e. 'part', 'layout', 'text'
|
|
34
21
|
console.warn(`BaseComponent: can not render component '${type}': no next view or catch-all defined`);
|
|
35
|
-
ComponentView = shouldShowMissingView(meta) ? <MissingComponent type={type} descriptor={descriptor}/> : <Empty/>;
|
|
36
|
-
|
|
37
|
-
|
|
22
|
+
ComponentView = shouldShowMissingView(meta) ? <MissingComponent type={type} descriptor={descriptor}/> : <Empty />;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
38
25
|
const cmpAttrs = createComponentAttrs(component, meta, common);
|
|
39
26
|
ComponentView = <ViewFn {...cmpAttrs}/>;
|
|
40
27
|
}
|
|
41
28
|
}
|
|
42
|
-
|
|
43
29
|
// need to display a placeholder if descriptor is empty as component is not initialized yet
|
|
44
30
|
if (descriptor && shouldShowPlaceholderView(meta)) {
|
|
45
31
|
const outputHTML = ReactDOMServer.renderToString(ComponentView);
|
|
@@ -48,101 +34,81 @@ const BaseComponent = ({component, meta, common}: BaseComponentProps) => {
|
|
|
48
34
|
ComponentView = <PlaceholderComponent type={type} descriptor={descriptor}/>;
|
|
49
35
|
}
|
|
50
36
|
}
|
|
51
|
-
|
|
52
37
|
if (meta.renderMode === RENDER_MODE.EDIT) {
|
|
53
|
-
return (
|
|
54
|
-
<div {...createEditorAttrs(type)}>
|
|
38
|
+
return (<div {...createEditorAttrs(type)}>
|
|
55
39
|
{ComponentView}
|
|
56
|
-
</div>
|
|
57
|
-
|
|
58
|
-
|
|
40
|
+
</div>);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
59
43
|
// do not make component wrappers in live mode
|
|
60
44
|
return ComponentView;
|
|
61
45
|
}
|
|
62
46
|
};
|
|
63
47
|
export default BaseComponent;
|
|
64
|
-
|
|
65
48
|
/*
|
|
66
49
|
* Used for displaying components with missing implementations on the page, while rendering whole page
|
|
67
50
|
*/
|
|
68
|
-
export const MissingComponent = ({
|
|
69
|
-
return (
|
|
70
|
-
<div style={{
|
|
51
|
+
export const MissingComponent = ({ descriptor, type }) => {
|
|
52
|
+
return (<div style={{
|
|
71
53
|
border: '2px dashed lightgrey',
|
|
72
54
|
padding: '16px',
|
|
73
55
|
}}>
|
|
74
|
-
<h3 style={{margin: 0}}>Missing component</h3>
|
|
75
|
-
<p style={{marginBottom: 0, color: 'grey'}}>{`Missing ${type} with descriptor: ${descriptor}`}</p>
|
|
76
|
-
</div>
|
|
77
|
-
);
|
|
56
|
+
<h3 style={{ margin: 0 }}>Missing component</h3>
|
|
57
|
+
<p style={{ marginBottom: 0, color: 'grey' }}>{`Missing ${type} with descriptor: ${descriptor}`}</p>
|
|
58
|
+
</div>);
|
|
78
59
|
};
|
|
79
|
-
|
|
80
|
-
export function shouldShowMissingView(meta: MetaData): boolean {
|
|
60
|
+
export function shouldShowMissingView(meta) {
|
|
81
61
|
return IS_DEV_MODE || meta.renderMode !== RENDER_MODE.NEXT;
|
|
82
62
|
}
|
|
83
|
-
|
|
84
63
|
/*
|
|
85
64
|
* Used for displaying components with errors on the page, while rendering whole page
|
|
86
65
|
*/
|
|
87
|
-
export const ErrorComponent = ({
|
|
88
|
-
return (
|
|
89
|
-
<div style={{
|
|
66
|
+
export const ErrorComponent = ({ type, descriptor, reason }) => {
|
|
67
|
+
return (<div style={{
|
|
90
68
|
border: '2px solid red',
|
|
91
69
|
padding: '16px',
|
|
92
70
|
}}>
|
|
93
|
-
<h3 style={{margin: 0, textTransform: 'capitalize'}}>{reason ? reason : 'Unknown error'}</h3>
|
|
94
|
-
{descriptor && <p style={{color: 'grey'}}>{`${type}: ${descriptor}`}</p>}
|
|
95
|
-
</div>
|
|
96
|
-
);
|
|
71
|
+
<h3 style={{ margin: 0, textTransform: 'capitalize' }}>{reason ? reason : 'Unknown error'}</h3>
|
|
72
|
+
{descriptor && <p style={{ color: 'grey' }}>{`${type}: ${descriptor}`}</p>}
|
|
73
|
+
</div>);
|
|
97
74
|
};
|
|
98
|
-
|
|
99
|
-
export function shouldShowErrorView(meta: MetaData): boolean {
|
|
75
|
+
export function shouldShowErrorView(meta) {
|
|
100
76
|
return meta.renderMode === RENDER_MODE.EDIT;
|
|
101
77
|
}
|
|
102
|
-
|
|
103
|
-
function createEditorAttrs(type: XP_COMPONENT_TYPE): { [key: string]: string } {
|
|
78
|
+
function createEditorAttrs(type) {
|
|
104
79
|
return {
|
|
105
80
|
[PORTAL_COMPONENT_ATTRIBUTE]: type,
|
|
106
81
|
};
|
|
107
82
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
const cmpAttrs: { [key: string]: any } = {
|
|
83
|
+
function createComponentAttrs(component, meta, common) {
|
|
84
|
+
const { type, data, error } = component;
|
|
85
|
+
const cmpAttrs = {
|
|
112
86
|
component: component[type],
|
|
113
87
|
path: component.path,
|
|
114
88
|
meta,
|
|
115
89
|
common,
|
|
116
90
|
};
|
|
117
|
-
|
|
118
91
|
if (data) {
|
|
119
92
|
cmpAttrs.data = data;
|
|
120
93
|
}
|
|
121
|
-
|
|
122
94
|
if (error) {
|
|
123
95
|
cmpAttrs.error = error;
|
|
124
96
|
}
|
|
125
|
-
|
|
126
97
|
if (component.type === XP_COMPONENT_TYPE.LAYOUT) {
|
|
127
98
|
// add regions to layout because they are not present in component[component.type] above
|
|
128
99
|
cmpAttrs.regions = component.regions;
|
|
129
100
|
}
|
|
130
101
|
return cmpAttrs;
|
|
131
102
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return (
|
|
135
|
-
<div style={{
|
|
103
|
+
export const PlaceholderComponent = ({ type, descriptor }) => {
|
|
104
|
+
return (<div style={{
|
|
136
105
|
border: '2px solid lightgrey',
|
|
137
106
|
padding: '16px',
|
|
138
107
|
}}>
|
|
139
|
-
<h3 style={{margin: 0, textTransform: 'capitalize'}}>Empty output</h3>
|
|
140
|
-
{descriptor && <p style={{color: 'grey'}}>{`${type} '${descriptor}' output is empty`}</p>}
|
|
141
|
-
</div>
|
|
142
|
-
);
|
|
108
|
+
<h3 style={{ margin: 0, textTransform: 'capitalize' }}>Empty output</h3>
|
|
109
|
+
{descriptor && <p style={{ color: 'grey' }}>{`${type} '${descriptor}' output is empty`}</p>}
|
|
110
|
+
</div>);
|
|
143
111
|
};
|
|
144
|
-
|
|
145
|
-
export function shouldShowPlaceholderView(meta: MetaData): boolean {
|
|
112
|
+
export function shouldShowPlaceholderView(meta) {
|
|
146
113
|
return meta.renderMode === RENDER_MODE.EDIT;
|
|
147
114
|
}
|
|
148
|
-
|
|
@@ -1,48 +1,41 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const BaseContent = (props: FetchContentResult) => {
|
|
8
|
-
const {common, meta, page} = props;
|
|
9
|
-
|
|
10
|
-
if (!meta?.type) {
|
|
2
|
+
import { ComponentRegistry } from '../ComponentRegistry';
|
|
3
|
+
import BasePage from './BasePage';
|
|
4
|
+
const BaseContent = (props) => {
|
|
5
|
+
const { common, meta, page } = props;
|
|
6
|
+
if (!(meta === null || meta === void 0 ? void 0 : meta.type)) {
|
|
11
7
|
console.warn("BaseContent props are missing 'meta.type'");
|
|
12
8
|
return null;
|
|
13
9
|
}
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const pageDesc = pageData?.descriptor;
|
|
10
|
+
const pageData = page === null || page === void 0 ? void 0 : page.page;
|
|
11
|
+
const pageDesc = pageData === null || pageData === void 0 ? void 0 : pageData.descriptor;
|
|
17
12
|
const typeDef = ComponentRegistry.getContentType(meta.type);
|
|
18
|
-
const ContentTypeView = typeDef
|
|
19
|
-
|
|
20
|
-
if (ContentTypeView && !typeDef?.catchAll) {
|
|
13
|
+
const ContentTypeView = typeDef === null || typeDef === void 0 ? void 0 : typeDef.view;
|
|
14
|
+
if (ContentTypeView && !(typeDef === null || typeDef === void 0 ? void 0 : typeDef.catchAll)) {
|
|
21
15
|
// console.info(`BaseContent: rendering '${meta.type}' with content type: ${ContentTypeView.name}`);
|
|
22
16
|
return <ContentTypeView {...props}/>;
|
|
23
|
-
}
|
|
17
|
+
}
|
|
18
|
+
else if (pageDesc) {
|
|
24
19
|
// console.info(`BaseContent: rendering '${meta.type}' with page: ${BasePage.name}`);
|
|
25
|
-
const pageAttrs
|
|
20
|
+
const pageAttrs = {
|
|
26
21
|
component: pageData,
|
|
27
|
-
path: page
|
|
22
|
+
path: page === null || page === void 0 ? void 0 : page.path,
|
|
28
23
|
meta,
|
|
29
24
|
common,
|
|
30
25
|
};
|
|
31
|
-
if (page
|
|
26
|
+
if (page === null || page === void 0 ? void 0 : page.data) {
|
|
32
27
|
pageAttrs.data = page.data;
|
|
33
28
|
}
|
|
34
|
-
if (page
|
|
29
|
+
if (page === null || page === void 0 ? void 0 : page.error) {
|
|
35
30
|
pageAttrs.error = page.error;
|
|
36
31
|
}
|
|
37
|
-
|
|
38
32
|
return <BasePage {...pageAttrs}/>;
|
|
39
|
-
}
|
|
33
|
+
}
|
|
34
|
+
else if (ContentTypeView) {
|
|
40
35
|
// console.info(`BaseContent: rendering '${meta.type}' with content type catch-all: ${ContentTypeView.name}`);
|
|
41
36
|
return <ContentTypeView {...props}/>;
|
|
42
37
|
}
|
|
43
|
-
|
|
44
38
|
console.log(`BaseContent: can not render ${meta.type}: no content type or page view defined`);
|
|
45
39
|
return null;
|
|
46
40
|
};
|
|
47
|
-
|
|
48
41
|
export default BaseContent;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { LayoutData, MetaData, RegionTree } from '../guillotine/getMetaData';
|
|
3
|
+
export interface LayoutProps {
|
|
4
|
+
layout: LayoutData;
|
|
5
|
+
path: string;
|
|
6
|
+
common: any;
|
|
7
|
+
meta: MetaData;
|
|
8
|
+
}
|
|
9
|
+
interface BaseLayoutProps {
|
|
10
|
+
component?: LayoutData;
|
|
11
|
+
path: string;
|
|
12
|
+
regions?: RegionTree;
|
|
13
|
+
common?: any;
|
|
14
|
+
meta: MetaData;
|
|
15
|
+
}
|
|
16
|
+
declare const BaseLayout: (props: BaseLayoutProps) => React.JSX.Element;
|
|
17
|
+
export default BaseLayout;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ComponentRegistry } from '../ComponentRegistry';
|
|
3
|
+
import { XP_COMPONENT_TYPE } from '../utils';
|
|
4
|
+
import { MissingComponent, shouldShowMissingView } from './BaseComponent';
|
|
5
|
+
const BaseLayout = (props) => {
|
|
6
|
+
const { component, common, regions, meta, path } = props;
|
|
7
|
+
let layoutSelection;
|
|
8
|
+
if (component) {
|
|
9
|
+
layoutSelection = ComponentRegistry.getLayout(component.descriptor);
|
|
10
|
+
}
|
|
11
|
+
const SelectedLayoutView = layoutSelection === null || layoutSelection === void 0 ? void 0 : layoutSelection.view;
|
|
12
|
+
if (SelectedLayoutView) {
|
|
13
|
+
return <SelectedLayoutView layout={{ descriptor: component === null || component === void 0 ? void 0 : component.descriptor, regions: regions || {}, config: component === null || component === void 0 ? void 0 : component.config }} path={path} common={common} meta={meta}/>;
|
|
14
|
+
}
|
|
15
|
+
else if (component === null || component === void 0 ? void 0 : component.descriptor) {
|
|
16
|
+
// empty descriptor usually means uninitialized layout
|
|
17
|
+
console.warn(`BaseLayout: can not render layout '${component === null || component === void 0 ? void 0 : component.descriptor}': no next view or catch-all defined`);
|
|
18
|
+
if (shouldShowMissingView(meta)) {
|
|
19
|
+
return <MissingComponent type={XP_COMPONENT_TYPE.LAYOUT} descriptor={component.descriptor}/>;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
};
|
|
24
|
+
export default BaseLayout;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { MacroConfig, MacroData, MetaData } from '../guillotine/getMetaData';
|
|
3
|
+
export declare const MACRO_DISABLE = "system:disable";
|
|
4
|
+
export declare const MACRO_EMBED = "system:embed";
|
|
5
|
+
interface BaseMacroProps {
|
|
6
|
+
data: MacroData;
|
|
7
|
+
meta: MetaData;
|
|
8
|
+
renderInEditMode?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface MacroProps {
|
|
11
|
+
name: string;
|
|
12
|
+
config: MacroConfig;
|
|
13
|
+
meta: MetaData;
|
|
14
|
+
}
|
|
15
|
+
declare const BaseMacro: (props: BaseMacroProps) => React.JSX.Element;
|
|
16
|
+
export default BaseMacro;
|
|
@@ -1,36 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {RENDER_MODE, sanitizeGraphqlName} from '../utils';
|
|
2
|
+
import { ComponentRegistry } from '../ComponentRegistry';
|
|
3
|
+
import { RENDER_MODE, sanitizeGraphqlName } from '../utils';
|
|
5
4
|
import HTMLReactParser from 'html-react-parser';
|
|
6
|
-
|
|
7
5
|
const unescape = require('unescape');
|
|
8
|
-
|
|
9
6
|
export const MACRO_DISABLE = 'system:disable';
|
|
10
7
|
export const MACRO_EMBED = 'system:embed';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
data: MacroData;
|
|
14
|
-
meta: MetaData;
|
|
15
|
-
renderInEditMode?: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface MacroProps {
|
|
19
|
-
name: string;
|
|
20
|
-
config: MacroConfig;
|
|
21
|
-
meta: MetaData;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const BaseMacro = (props: BaseMacroProps) => {
|
|
25
|
-
const {data, meta, renderInEditMode} = props;
|
|
26
|
-
|
|
8
|
+
const BaseMacro = (props) => {
|
|
9
|
+
const { data, meta, renderInEditMode } = props;
|
|
27
10
|
let config = data.config[sanitizeGraphqlName(data.name)] || {};
|
|
28
11
|
if (data.descriptor !== MACRO_DISABLE) {
|
|
29
12
|
// do not do any processing for disable macro
|
|
30
13
|
config = normalizeValue(config);
|
|
31
14
|
}
|
|
32
|
-
|
|
33
|
-
if (!renderInEditMode && meta?.renderMode === RENDER_MODE.EDIT) {
|
|
15
|
+
if (!renderInEditMode && (meta === null || meta === void 0 ? void 0 : meta.renderMode) === RENDER_MODE.EDIT) {
|
|
34
16
|
const attrs = formatAttributes(config);
|
|
35
17
|
if (config.body) {
|
|
36
18
|
// do not parse system macros (embed, disable) in edit mode
|
|
@@ -42,60 +24,62 @@ const BaseMacro = (props: BaseMacroProps) => {
|
|
|
42
24
|
{bodyString}
|
|
43
25
|
{`[/${data.name}]`}
|
|
44
26
|
</>;
|
|
45
|
-
}
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
46
29
|
return <>
|
|
47
30
|
{`[${data.name}${attrs}/]`}
|
|
48
31
|
</>;
|
|
49
32
|
}
|
|
50
33
|
}
|
|
51
|
-
|
|
52
34
|
const macro = ComponentRegistry.getMacro(data.descriptor);
|
|
53
|
-
const MacroView = macro
|
|
35
|
+
const MacroView = macro === null || macro === void 0 ? void 0 : macro.view;
|
|
54
36
|
if (MacroView) {
|
|
55
37
|
return <MacroView name={data.name} config={config} meta={meta}/>;
|
|
56
|
-
}
|
|
38
|
+
}
|
|
39
|
+
else if (data.descriptor) {
|
|
57
40
|
console.warn(`BaseMacro: can not render macro '${data.descriptor}': no next view or catch-all defined`);
|
|
58
41
|
}
|
|
59
42
|
return null;
|
|
60
43
|
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
let parsedVal: any;
|
|
44
|
+
function normalizeValue(value) {
|
|
45
|
+
let parsedVal;
|
|
64
46
|
if (value instanceof Array) {
|
|
65
47
|
parsedVal = value.map(normalizeValue);
|
|
66
|
-
}
|
|
48
|
+
}
|
|
49
|
+
else if (value instanceof Object) {
|
|
67
50
|
parsedVal = {};
|
|
68
51
|
Object.entries(value).forEach(entry => parsedVal[entry[0]] = normalizeValue(entry[1]));
|
|
69
|
-
}
|
|
52
|
+
}
|
|
53
|
+
else if (typeof value === 'string') {
|
|
70
54
|
const unescapedValue = unescape(value);
|
|
71
55
|
if (unescapedValue.startsWith('[') && unescapedValue.endsWith(']')) {
|
|
72
56
|
// Wicked array notation: "[Value 1, Value 2]"
|
|
73
57
|
parsedVal = unescapedValue.substring(1, unescapedValue.length - 1).split(/,\s*/);
|
|
74
|
-
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
75
60
|
try {
|
|
76
61
|
parsedVal = JSON.parse(unescapedValue);
|
|
77
|
-
}
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
78
64
|
// simple string or wrongly formatted JSON
|
|
79
65
|
parsedVal = unescapedValue;
|
|
80
66
|
}
|
|
81
67
|
}
|
|
82
|
-
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
83
70
|
// most likely a number or unknown type
|
|
84
71
|
parsedVal = value;
|
|
85
72
|
}
|
|
86
73
|
return parsedVal;
|
|
87
74
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const attrs: string[] = Object.entries(config)
|
|
75
|
+
function formatAttributes(config) {
|
|
76
|
+
const attrs = Object.entries(config)
|
|
91
77
|
.filter(entry => entry[0] !== 'body')
|
|
92
|
-
.reduce
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
78
|
+
.reduce((accum, entry) => {
|
|
79
|
+
// concat to make sure we account for arrays
|
|
80
|
+
[].concat(normalizeValue(entry[1])).forEach(val => accum.push(`${entry[0]}="${val}"`));
|
|
81
|
+
return accum;
|
|
82
|
+
}, []);
|
|
98
83
|
return attrs.length ? ` ${attrs.join(' ')}` : '';
|
|
99
84
|
}
|
|
100
|
-
|
|
101
85
|
export default BaseMacro;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { MetaData, PageData } from '../guillotine/getMetaData';
|
|
3
|
+
export interface PageProps {
|
|
4
|
+
page: PageData;
|
|
5
|
+
path: string;
|
|
6
|
+
data?: any;
|
|
7
|
+
common?: any;
|
|
8
|
+
meta: MetaData;
|
|
9
|
+
}
|
|
10
|
+
export interface BasePageProps {
|
|
11
|
+
component?: PageData;
|
|
12
|
+
path?: string;
|
|
13
|
+
common?: any;
|
|
14
|
+
data?: any;
|
|
15
|
+
error?: string;
|
|
16
|
+
meta: MetaData;
|
|
17
|
+
}
|
|
18
|
+
declare const BasePage: (props: BasePageProps) => React.JSX.Element;
|
|
19
|
+
export default BasePage;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ComponentRegistry } from '../ComponentRegistry';
|
|
3
|
+
import { XP_COMPONENT_TYPE } from '../utils';
|
|
4
|
+
import { ErrorComponent, MissingComponent, shouldShowErrorView, shouldShowMissingView } from './BaseComponent';
|
|
5
|
+
const BasePage = (props) => {
|
|
6
|
+
const { component, data, common, error, meta, path } = props;
|
|
7
|
+
const desc = component === null || component === void 0 ? void 0 : component.descriptor;
|
|
8
|
+
if (error) {
|
|
9
|
+
console.warn(`BasePage: '${desc}' error: ${error}`);
|
|
10
|
+
if (shouldShowErrorView(meta)) {
|
|
11
|
+
return <ErrorComponent reason={error} descriptor={desc} type={XP_COMPONENT_TYPE.PAGE}/>;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
let pageDef;
|
|
18
|
+
if (desc) {
|
|
19
|
+
pageDef = ComponentRegistry.getPage(desc);
|
|
20
|
+
}
|
|
21
|
+
const PageView = pageDef === null || pageDef === void 0 ? void 0 : pageDef.view;
|
|
22
|
+
if (PageView) {
|
|
23
|
+
return <PageView page={component} path={path} data={data} common={common} meta={meta}/>;
|
|
24
|
+
}
|
|
25
|
+
else if (component === null || component === void 0 ? void 0 : component.descriptor) {
|
|
26
|
+
// empty descriptor usually means uninitialized page
|
|
27
|
+
console.warn(`BasePage: can not render page '${desc}': no next view or catch-all defined`);
|
|
28
|
+
if (shouldShowMissingView(meta)) {
|
|
29
|
+
return <MissingComponent type={XP_COMPONENT_TYPE.PAGE} descriptor={component.descriptor}/>;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
};
|
|
34
|
+
export default BasePage;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { MetaData, PartData } from '../guillotine/getMetaData';
|
|
3
|
+
export interface PartProps {
|
|
4
|
+
part: PartData;
|
|
5
|
+
path: string;
|
|
6
|
+
data?: any;
|
|
7
|
+
common?: any;
|
|
8
|
+
meta: MetaData;
|
|
9
|
+
}
|
|
10
|
+
interface BasePartProps {
|
|
11
|
+
component?: PartData;
|
|
12
|
+
path: string;
|
|
13
|
+
common?: any;
|
|
14
|
+
data?: any;
|
|
15
|
+
error?: string;
|
|
16
|
+
meta: MetaData;
|
|
17
|
+
}
|
|
18
|
+
declare const BasePart: (props: BasePartProps) => React.JSX.Element;
|
|
19
|
+
export default BasePart;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ComponentRegistry } from '../ComponentRegistry';
|
|
3
|
+
import { XP_COMPONENT_TYPE } from '../utils';
|
|
4
|
+
import { MissingComponent, shouldShowMissingView } from './BaseComponent';
|
|
5
|
+
const BasePart = (props) => {
|
|
6
|
+
const { component, data, common, meta, path } = props;
|
|
7
|
+
let partSelection;
|
|
8
|
+
if (component) {
|
|
9
|
+
partSelection = ComponentRegistry.getPart(component.descriptor);
|
|
10
|
+
}
|
|
11
|
+
const SelectedPartView = partSelection === null || partSelection === void 0 ? void 0 : partSelection.view;
|
|
12
|
+
if (SelectedPartView) {
|
|
13
|
+
return <SelectedPartView part={component} path={path} data={data} common={common} meta={meta}/>;
|
|
14
|
+
}
|
|
15
|
+
else if (component === null || component === void 0 ? void 0 : component.descriptor) {
|
|
16
|
+
// empty descriptor usually means uninitialized part
|
|
17
|
+
console.warn(`BasePart: can not render part '${component.descriptor}': no next view or catch-all defined`);
|
|
18
|
+
if (shouldShowMissingView(meta)) {
|
|
19
|
+
return <MissingComponent type={XP_COMPONENT_TYPE.PART} descriptor={component.descriptor}/>;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
};
|
|
24
|
+
export default BasePart;
|
package/views/Empty.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FragmentData, MetaData, PageData } from '../guillotine/getMetaData';
|
|
3
|
+
interface FragmentProps {
|
|
4
|
+
page?: PageData;
|
|
5
|
+
component?: FragmentData;
|
|
6
|
+
common?: any;
|
|
7
|
+
meta: MetaData;
|
|
8
|
+
}
|
|
9
|
+
declare const FragmentView: (props: FragmentProps) => React.JSX.Element;
|
|
10
|
+
export default FragmentView;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import BaseComponent, { MissingComponent, shouldShowMissingView } from './BaseComponent';
|
|
3
|
+
import { FRAGMENT_DEFAULT_REGION_NAME, XP_COMPONENT_TYPE } from '../utils';
|
|
4
|
+
const FragmentView = (props) => {
|
|
5
|
+
var _a;
|
|
6
|
+
const { component, page } = props;
|
|
7
|
+
const comps = [];
|
|
8
|
+
if (page) {
|
|
9
|
+
// rendering whole page
|
|
10
|
+
const regions = page.regions || {};
|
|
11
|
+
const regionComps = (_a = regions[FRAGMENT_DEFAULT_REGION_NAME]) === null || _a === void 0 ? void 0 : _a.components;
|
|
12
|
+
if (regionComps) {
|
|
13
|
+
comps.push(...regionComps);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
else if (component === null || component === void 0 ? void 0 : component.fragment) {
|
|
17
|
+
// rendering a part of a page
|
|
18
|
+
comps.push(...component.fragment.components);
|
|
19
|
+
}
|
|
20
|
+
if (!comps.length && shouldShowMissingView(props.meta)) {
|
|
21
|
+
return <MissingComponent type={XP_COMPONENT_TYPE.FRAGMENT} descriptor={(page === null || page === void 0 ? void 0 : page.descriptor) || (component === null || component === void 0 ? void 0 : component.id)}/>;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
const { common, meta } = props;
|
|
25
|
+
return (<>
|
|
26
|
+
{comps.map((comp, i) => (<BaseComponent key={i} component={comp} common={common} meta={meta}/>))}
|
|
27
|
+
</>);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export default FragmentView;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import SingleComponent from './SingleComponent';
|
|
3
|
+
import BaseContent from './BaseContent';
|
|
4
|
+
import { XP_REQUEST_TYPE } from '../utils';
|
|
5
|
+
const _MainView = (props) => {
|
|
6
|
+
const { meta } = props;
|
|
7
|
+
// Single-component render:
|
|
8
|
+
if ((meta === null || meta === void 0 ? void 0 : meta.requestType) === XP_REQUEST_TYPE.COMPONENT) {
|
|
9
|
+
return <SingleComponent {...props}/>;
|
|
10
|
+
}
|
|
11
|
+
// meta.requestType="type", and hence content-type based, is standard view for now.
|
|
12
|
+
return <BaseContent {...props}/>;
|
|
13
|
+
};
|
|
14
|
+
export default _MainView;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { MetaData, PageComponent, PageData } from '../guillotine/getMetaData';
|
|
3
|
+
export interface RegionProps {
|
|
4
|
+
name: string;
|
|
5
|
+
components?: PageComponent[];
|
|
6
|
+
className?: string;
|
|
7
|
+
common?: any;
|
|
8
|
+
meta: MetaData;
|
|
9
|
+
}
|
|
10
|
+
export interface RegionsProps {
|
|
11
|
+
page: PageData | null;
|
|
12
|
+
name?: string;
|
|
13
|
+
common?: any;
|
|
14
|
+
meta: MetaData;
|
|
15
|
+
}
|
|
16
|
+
/** Single region */
|
|
17
|
+
export declare const RegionView: (props: RegionProps) => React.JSX.Element;
|
|
18
|
+
/** Multiple regions, or only one if named in props.selected */
|
|
19
|
+
declare const RegionsView: (props: RegionsProps) => React.JSX.Element;
|
|
20
|
+
export default RegionsView;
|