@plone/volto 18.0.0-alpha.31 → 18.0.0-alpha.33
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/CHANGELOG.md +55 -0
- package/locales/ca/LC_MESSAGES/volto.po +12 -0
- package/locales/ca.json +1 -1
- package/locales/de/LC_MESSAGES/volto.po +12 -0
- package/locales/de.json +1 -1
- package/locales/en/LC_MESSAGES/volto.po +12 -0
- package/locales/en.json +1 -1
- package/locales/es/LC_MESSAGES/volto.po +12 -0
- package/locales/es.json +1 -1
- package/locales/eu/LC_MESSAGES/volto.po +12 -0
- package/locales/eu.json +1 -1
- package/locales/fi/LC_MESSAGES/volto.po +12 -0
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +12 -0
- package/locales/fr.json +1 -1
- package/locales/hi/LC_MESSAGES/volto.po +4989 -0
- package/locales/hi.json +1 -0
- package/locales/it/LC_MESSAGES/volto.po +12 -0
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +12 -0
- package/locales/ja.json +1 -1
- package/locales/nl/LC_MESSAGES/volto.po +12 -0
- package/locales/nl.json +1 -1
- package/locales/pt/LC_MESSAGES/volto.po +12 -0
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +12 -0
- package/locales/pt_BR.json +1 -1
- package/locales/ro/LC_MESSAGES/volto.po +12 -0
- package/locales/ro.json +1 -1
- package/locales/volto.pot +13 -1
- package/locales/zh_CN/LC_MESSAGES/volto.po +12 -0
- package/locales/zh_CN.json +1 -1
- package/package.json +6 -4
- package/razzle.config.js +51 -0
- package/src/components/manage/BlockChooser/BlockChooserSearch.jsx +1 -0
- package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +2 -0
- package/src/components/manage/Form/Form.jsx +1 -1
- package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +158 -65
- package/src/components/manage/Sidebar/ObjectBrowserNav.jsx +125 -71
- package/src/components/manage/Widgets/IdWidget.jsx +138 -203
- package/src/components/manage/Widgets/TextWidget.jsx +92 -124
- package/src/components/manage/Widgets/TextWidget.stories.jsx +14 -3
- package/src/components/theme/App/App.jsx +5 -0
- package/src/components/theme/Footer/Footer.jsx +1 -0
- package/src/components/theme/Navigation/Navigation.jsx +1 -1
- package/src/components/theme/SlotRenderer/SlotRenderer.tsx +3 -4
- package/src/components/theme/View/View.jsx +5 -3
- package/src/components/theme/View/View.test.jsx +1 -0
- package/src/config/ControlPanels.js +7 -0
- package/src/config/config.test.js +232 -0
- package/src/config/server.js +0 -1
- package/src/constants/Languages.js +1 -0
- package/src/express-middleware/files.js +1 -0
- package/src/express-middleware/images.js +1 -0
- package/src/express-middleware/static.js +37 -19
- package/src/helpers/Api/Api.js +12 -0
- package/src/helpers/Api/Api.plone.rest.test.js +1 -0
- package/src/helpers/Api/Api.test.js +1 -0
- package/src/helpers/Html/Html.jsx +6 -8
- package/src/helpers/Slots/index.tsx +12 -5
- package/src/server.jsx +34 -36
- package/theme/themes/pastanaga/extras/blocks.less +10 -10
- package/theme/themes/pastanaga/extras/objectbrowser-widget.less +83 -0
- package/theme/themes/pastanaga/extras/widgets.less +19 -0
- package/types/components/manage/Sidebar/ObjectBrowserNav.d.ts +2 -1
- package/types/components/manage/Widgets/IdWidget.d.ts +54 -2
- package/types/components/manage/Widgets/TextWidget.d.ts +54 -5
- package/types/components/manage/Widgets/TextWidget.stories.d.ts +13 -1
- package/types/components/manage/Widgets/index.d.ts +2 -2
- package/types/config/Widgets.d.ts +1 -1
- package/types/config/config.test.d.ts +1 -0
- package/types/config/server.d.ts +0 -3
- package/types/constants/Languages.d.ts +1 -0
- package/types/helpers/Slots/index.d.ts +5 -3
- package/types/start-client.d.ts +1 -1
|
@@ -206,8 +206,10 @@ class View extends Component {
|
|
|
206
206
|
*/
|
|
207
207
|
render() {
|
|
208
208
|
const { views } = config;
|
|
209
|
-
if (
|
|
210
|
-
const redirect = flattenToAppURL(this.props.error.url)
|
|
209
|
+
if ([301, 302].includes(this.props.error?.code)) {
|
|
210
|
+
const redirect = flattenToAppURL(this.props.error.url)
|
|
211
|
+
.split('?')[0]
|
|
212
|
+
.replace('/++api++', '');
|
|
211
213
|
return <Redirect to={`${redirect}${this.props.location.search}`} />;
|
|
212
214
|
} else if (this.props.error && !this.props.connectionRefused) {
|
|
213
215
|
let FoundView;
|
|
@@ -235,7 +237,7 @@ class View extends Component {
|
|
|
235
237
|
this.getViewByLayout() || this.getViewByType() || this.getViewDefault();
|
|
236
238
|
|
|
237
239
|
return (
|
|
238
|
-
<div id="view">
|
|
240
|
+
<div id="view" tabIndex="-1">
|
|
239
241
|
<ContentMetadataTags content={this.props.content} />
|
|
240
242
|
{/* Body class if displayName in component is set */}
|
|
241
243
|
<BodyClass
|
|
@@ -90,6 +90,13 @@ export const filterControlPanelsSchema = (controlpanel) => {
|
|
|
90
90
|
'picture_variants',
|
|
91
91
|
'image_captioning',
|
|
92
92
|
],
|
|
93
|
+
navigation: [
|
|
94
|
+
'generate_tabs',
|
|
95
|
+
'navigation_depth',
|
|
96
|
+
'sort_tabs_on',
|
|
97
|
+
'sort_tabs_reversed',
|
|
98
|
+
'sitemap_depth',
|
|
99
|
+
],
|
|
93
100
|
};
|
|
94
101
|
|
|
95
102
|
// Creates modified version of properties object
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import config from '@plone/volto/registry';
|
|
2
|
+
|
|
3
|
+
const navigation_controlpanel = {
|
|
4
|
+
'@id': '/@controlpanels/navigation',
|
|
5
|
+
data: {
|
|
6
|
+
displayed_types: [
|
|
7
|
+
{
|
|
8
|
+
title: 'Link',
|
|
9
|
+
token: 'Link',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
title: 'News Item',
|
|
13
|
+
token: 'News Item',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
title: 'Folder',
|
|
17
|
+
token: 'Folder',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
title: 'Page',
|
|
21
|
+
token: 'Document',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
title: 'Event',
|
|
25
|
+
token: 'Event',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
title: 'Collection',
|
|
29
|
+
token: 'Collection',
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
filter_on_workflow: false,
|
|
33
|
+
generate_tabs: true,
|
|
34
|
+
navigation_depth: 3,
|
|
35
|
+
nonfolderish_tabs: true,
|
|
36
|
+
parent_types_not_to_query: ['TempFolder'],
|
|
37
|
+
root: '/',
|
|
38
|
+
show_excluded_items: false,
|
|
39
|
+
sitemap_depth: 3,
|
|
40
|
+
sort_tabs_on: {
|
|
41
|
+
title: 'Position in Parent',
|
|
42
|
+
token: 'getObjPositionInParent',
|
|
43
|
+
},
|
|
44
|
+
sort_tabs_reversed: false,
|
|
45
|
+
workflow_states_to_show: [],
|
|
46
|
+
},
|
|
47
|
+
group: 'General',
|
|
48
|
+
schema: {
|
|
49
|
+
fieldsets: [
|
|
50
|
+
{
|
|
51
|
+
behavior: 'plone',
|
|
52
|
+
fields: [
|
|
53
|
+
'navigation_depth',
|
|
54
|
+
'generate_tabs',
|
|
55
|
+
'nonfolderish_tabs',
|
|
56
|
+
'sort_tabs_on',
|
|
57
|
+
'sort_tabs_reversed',
|
|
58
|
+
'displayed_types',
|
|
59
|
+
'filter_on_workflow',
|
|
60
|
+
'workflow_states_to_show',
|
|
61
|
+
'show_excluded_items',
|
|
62
|
+
'root',
|
|
63
|
+
'sitemap_depth',
|
|
64
|
+
'parent_types_not_to_query',
|
|
65
|
+
],
|
|
66
|
+
id: 'default',
|
|
67
|
+
title: 'Default',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
properties: {
|
|
71
|
+
displayed_types: {
|
|
72
|
+
additionalItems: true,
|
|
73
|
+
default: [
|
|
74
|
+
'Link',
|
|
75
|
+
'News Item',
|
|
76
|
+
'Folder',
|
|
77
|
+
'Document',
|
|
78
|
+
'Event',
|
|
79
|
+
'Collection',
|
|
80
|
+
],
|
|
81
|
+
description:
|
|
82
|
+
'The content types that should be shown in the navigation and site map.',
|
|
83
|
+
factory: 'Tuple',
|
|
84
|
+
items: {
|
|
85
|
+
description: '',
|
|
86
|
+
factory: 'Choice',
|
|
87
|
+
title: '',
|
|
88
|
+
type: 'string',
|
|
89
|
+
vocabulary: {
|
|
90
|
+
'@id':
|
|
91
|
+
'http://localhost:3000/@vocabularies/plone.app.vocabularies.ReallyUserFriendlyTypes',
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
title: 'Displayed content types',
|
|
95
|
+
type: 'array',
|
|
96
|
+
uniqueItems: true,
|
|
97
|
+
},
|
|
98
|
+
filter_on_workflow: {
|
|
99
|
+
default: false,
|
|
100
|
+
description:
|
|
101
|
+
'The workflow states that should be shown in the navigation and the site map.',
|
|
102
|
+
factory: 'Yes/No',
|
|
103
|
+
title: 'Filter on workflow state',
|
|
104
|
+
type: 'boolean',
|
|
105
|
+
},
|
|
106
|
+
generate_tabs: {
|
|
107
|
+
default: true,
|
|
108
|
+
description:
|
|
109
|
+
'By default, all items created at the root level will appear as tabs. You can turn this off if you prefer manually constructing this part of the navigation.',
|
|
110
|
+
factory: 'Yes/No',
|
|
111
|
+
title: 'Automatically generate tabs',
|
|
112
|
+
type: 'boolean',
|
|
113
|
+
},
|
|
114
|
+
navigation_depth: {
|
|
115
|
+
default: 3,
|
|
116
|
+
description: 'Number of folder levels to show in the navigation.',
|
|
117
|
+
factory: 'Integer',
|
|
118
|
+
title: 'Navigation depth',
|
|
119
|
+
type: 'integer',
|
|
120
|
+
},
|
|
121
|
+
nonfolderish_tabs: {
|
|
122
|
+
default: true,
|
|
123
|
+
description:
|
|
124
|
+
"By default, any content item in the root of the portal will appear as a tab. If you turn this option off, only folders will be shown. This only has an effect if 'automatically generate tabs' is enabled.",
|
|
125
|
+
factory: 'Yes/No',
|
|
126
|
+
title: 'Generate tabs for items other than folders.',
|
|
127
|
+
type: 'boolean',
|
|
128
|
+
},
|
|
129
|
+
parent_types_not_to_query: {
|
|
130
|
+
additionalItems: true,
|
|
131
|
+
default: ['TempFolder'],
|
|
132
|
+
description: 'Hide content inside the following types in Navigation.',
|
|
133
|
+
factory: 'List',
|
|
134
|
+
items: {
|
|
135
|
+
description: '',
|
|
136
|
+
factory: 'Text line (String)',
|
|
137
|
+
title: '',
|
|
138
|
+
type: 'string',
|
|
139
|
+
},
|
|
140
|
+
title: 'Hide children of these types',
|
|
141
|
+
type: 'array',
|
|
142
|
+
uniqueItems: false,
|
|
143
|
+
},
|
|
144
|
+
root: {
|
|
145
|
+
default: '/',
|
|
146
|
+
description:
|
|
147
|
+
"Path to be used as navigation root, relative to Plone site root.Starts with '/'",
|
|
148
|
+
factory: 'Text line (String)',
|
|
149
|
+
title: 'Root',
|
|
150
|
+
type: 'string',
|
|
151
|
+
},
|
|
152
|
+
show_excluded_items: {
|
|
153
|
+
default: false,
|
|
154
|
+
description:
|
|
155
|
+
'If an item has been excluded from navigation should it be shown in navigation when viewing content contained within it or within a subfolder.',
|
|
156
|
+
factory: 'Yes/No',
|
|
157
|
+
title:
|
|
158
|
+
'Show items normally excluded from navigation if viewing their children.',
|
|
159
|
+
type: 'boolean',
|
|
160
|
+
},
|
|
161
|
+
sitemap_depth: {
|
|
162
|
+
default: 3,
|
|
163
|
+
description: 'Number of folder levels to show in the site map.',
|
|
164
|
+
factory: 'Integer',
|
|
165
|
+
title: 'Sitemap depth',
|
|
166
|
+
type: 'integer',
|
|
167
|
+
},
|
|
168
|
+
sort_tabs_on: {
|
|
169
|
+
choices: [
|
|
170
|
+
['getObjPositionInParent', 'Position in Parent'],
|
|
171
|
+
['sortable_title', 'Title'],
|
|
172
|
+
['getId', 'Short Name (ID)'],
|
|
173
|
+
],
|
|
174
|
+
default: 'getObjPositionInParent',
|
|
175
|
+
description: 'Index used to sort the tabs',
|
|
176
|
+
enum: ['getObjPositionInParent', 'sortable_title', 'getId'],
|
|
177
|
+
enumNames: ['Position in Parent', 'Title', 'Short Name (ID)'],
|
|
178
|
+
factory: 'Choice',
|
|
179
|
+
title: 'Sort tabs on',
|
|
180
|
+
type: 'string',
|
|
181
|
+
vocabulary: {
|
|
182
|
+
'@id': 'http://localhost:3000/@sources/sort_tabs_on',
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
sort_tabs_reversed: {
|
|
186
|
+
default: false,
|
|
187
|
+
description: 'Sort tabs in descending.',
|
|
188
|
+
factory: 'Yes/No',
|
|
189
|
+
title: 'Reversed sort order for tabs.',
|
|
190
|
+
type: 'boolean',
|
|
191
|
+
},
|
|
192
|
+
workflow_states_to_show: {
|
|
193
|
+
additionalItems: true,
|
|
194
|
+
default: [],
|
|
195
|
+
description: '',
|
|
196
|
+
factory: 'Tuple',
|
|
197
|
+
items: {
|
|
198
|
+
description: '',
|
|
199
|
+
factory: 'Choice',
|
|
200
|
+
title: '',
|
|
201
|
+
type: 'string',
|
|
202
|
+
vocabulary: {
|
|
203
|
+
'@id':
|
|
204
|
+
'http://localhost:3000/@vocabularies/plone.app.vocabularies.WorkflowStates',
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
title: '',
|
|
208
|
+
type: 'array',
|
|
209
|
+
uniqueItems: true,
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
required: ['navigation_depth', 'sort_tabs_on', 'root', 'sitemap_depth'],
|
|
213
|
+
type: 'object',
|
|
214
|
+
},
|
|
215
|
+
title: 'Navigation',
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
test('test navigation controlpanel fields', () => {
|
|
219
|
+
const { filterControlPanelsSchema } = config.settings;
|
|
220
|
+
const result = filterControlPanelsSchema(navigation_controlpanel);
|
|
221
|
+
const not_in_navigation = [
|
|
222
|
+
'generate_tabs',
|
|
223
|
+
'navigation_depth',
|
|
224
|
+
'sort_tabs_on',
|
|
225
|
+
'sort_tabs_reversed',
|
|
226
|
+
'sitemap_depth',
|
|
227
|
+
];
|
|
228
|
+
const hasField = result['fieldsets'][0]['fields'].some((field) =>
|
|
229
|
+
not_in_navigation.includes(field),
|
|
230
|
+
);
|
|
231
|
+
expect(hasField).toBe(false);
|
|
232
|
+
});
|
package/src/config/server.js
CHANGED
|
@@ -1,28 +1,46 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import AddonConfigurationRegistry from '@plone/registry/src/addon-registry';
|
|
3
4
|
import config from '@plone/volto/registry';
|
|
4
5
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
{
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
6
|
+
const projectRootPath = path.resolve('.');
|
|
7
|
+
const registry = new AddonConfigurationRegistry(projectRootPath);
|
|
8
|
+
|
|
9
|
+
const staticDirectory = () => {
|
|
10
|
+
if (process.env.BUILD_DIR) {
|
|
11
|
+
return path.join(process.env.BUILD_DIR, 'public');
|
|
12
|
+
}
|
|
13
|
+
// Only for development, when Volto detects that it's working on itself (not an
|
|
14
|
+
// old fashioned Volto project), there are add-ons (so it's the new setup) then
|
|
15
|
+
// point to the public folder in the root of the setup, instead of the inner Volto
|
|
16
|
+
// public folder.
|
|
17
|
+
if (
|
|
18
|
+
process.env.NODE_ENV !== 'production' &&
|
|
19
|
+
!registry.isVoltoProject &&
|
|
20
|
+
registry.addonNames.length > 0
|
|
21
|
+
) {
|
|
22
|
+
return path.join(projectRootPath, '../../../public');
|
|
23
|
+
}
|
|
24
|
+
// Is always set (Razzle does it)
|
|
25
|
+
return process.env.RAZZLE_PUBLIC_DIR;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const staticMiddlewareFn = express.static(staticDirectory(), {
|
|
29
|
+
setHeaders: function (res, path) {
|
|
30
|
+
const pathLib = require('path');
|
|
31
|
+
const base = pathLib.resolve(process.env.RAZZLE_PUBLIC_DIR);
|
|
32
|
+
const relpath = path.substr(base.length);
|
|
33
|
+
config.settings.serverConfig.staticFiles.some((elem) => {
|
|
34
|
+
if (relpath.match(elem.match)) {
|
|
35
|
+
for (const name in elem.headers) {
|
|
36
|
+
res.setHeader(name, elem.headers[name] || 'undefined');
|
|
20
37
|
}
|
|
21
|
-
return
|
|
22
|
-
}
|
|
23
|
-
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
return false;
|
|
41
|
+
});
|
|
24
42
|
},
|
|
25
|
-
);
|
|
43
|
+
});
|
|
26
44
|
|
|
27
45
|
export default function staticsMiddleware() {
|
|
28
46
|
const middleware = express.Router();
|
package/src/helpers/Api/Api.js
CHANGED
|
@@ -80,6 +80,10 @@ class Api {
|
|
|
80
80
|
|
|
81
81
|
Object.keys(headers).forEach((key) => request.set(key, headers[key]));
|
|
82
82
|
|
|
83
|
+
if (__SERVER__ && checkUrl && ['get', 'head'].includes(method)) {
|
|
84
|
+
request.redirects(0);
|
|
85
|
+
}
|
|
86
|
+
|
|
83
87
|
if (data) {
|
|
84
88
|
request.send(data);
|
|
85
89
|
}
|
|
@@ -104,6 +108,14 @@ class Api {
|
|
|
104
108
|
url: request.xhr.responseURL,
|
|
105
109
|
});
|
|
106
110
|
}
|
|
111
|
+
|
|
112
|
+
if ([301, 302].includes(err?.status)) {
|
|
113
|
+
return reject({
|
|
114
|
+
code: err.status,
|
|
115
|
+
url: err.response.headers.location,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
107
119
|
return err ? reject(err) : resolve(response.body || response.text);
|
|
108
120
|
});
|
|
109
121
|
});
|
|
@@ -187,14 +187,12 @@ class Html extends Component {
|
|
|
187
187
|
charSet="UTF-8"
|
|
188
188
|
/>
|
|
189
189
|
{/* Add the crossorigin while in development */}
|
|
190
|
-
{
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
)
|
|
197
|
-
: ''}
|
|
190
|
+
{extractor.getScriptElements().map((elem) =>
|
|
191
|
+
React.cloneElement(elem, {
|
|
192
|
+
crossOrigin:
|
|
193
|
+
process.env.NODE_ENV === 'production' ? undefined : 'true',
|
|
194
|
+
}),
|
|
195
|
+
)}
|
|
198
196
|
</body>
|
|
199
197
|
</html>
|
|
200
198
|
);
|
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import type { Content } from '@plone/types';
|
|
2
1
|
import { matchPath } from 'react-router-dom';
|
|
2
|
+
import type { Content } from '@plone/types';
|
|
3
|
+
import type { Location } from 'history';
|
|
3
4
|
|
|
4
5
|
export function RouteCondition(path: string, exact?: boolean) {
|
|
5
|
-
return ({
|
|
6
|
-
Boolean(matchPath(pathname, { path, exact }));
|
|
6
|
+
return ({ location }: { location: Location }) =>
|
|
7
|
+
Boolean(matchPath(location.pathname, { path, exact }));
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
export function ContentTypeCondition(contentType: string[]) {
|
|
10
|
-
return ({ content }: { content: Content }) =>
|
|
11
|
-
|
|
11
|
+
return ({ content, location }: { content: Content; location: Location }) => {
|
|
12
|
+
return (
|
|
13
|
+
contentType.includes(content?.['@type']) ||
|
|
14
|
+
contentType.some((type) => {
|
|
15
|
+
return location.search.includes(`type=${encodeURIComponent(type)}`);
|
|
16
|
+
})
|
|
17
|
+
);
|
|
18
|
+
};
|
|
12
19
|
}
|
package/src/server.jsx
CHANGED
|
@@ -272,50 +272,48 @@ server.get('/*', (req, res) => {
|
|
|
272
272
|
});
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
const sendHtmlResponse = (
|
|
276
|
+
res,
|
|
277
|
+
statusCode,
|
|
278
|
+
extractor,
|
|
279
|
+
markup,
|
|
280
|
+
store,
|
|
281
|
+
req,
|
|
282
|
+
config,
|
|
283
|
+
) => {
|
|
284
|
+
res.status(statusCode).send(
|
|
285
|
+
`<!doctype html>
|
|
286
|
+
${renderToString(
|
|
287
|
+
<Html
|
|
288
|
+
extractor={extractor}
|
|
289
|
+
markup={markup}
|
|
290
|
+
store={store}
|
|
291
|
+
criticalCss={readCriticalCss(req)}
|
|
292
|
+
apiPath={res.locals.detectedHost || config.settings.apiPath}
|
|
293
|
+
publicURL={res.locals.detectedHost || config.settings.publicURL}
|
|
294
|
+
/>,
|
|
295
|
+
)}
|
|
296
|
+
`,
|
|
297
|
+
);
|
|
298
|
+
};
|
|
299
|
+
|
|
275
300
|
if (context.url) {
|
|
276
301
|
res.redirect(flattenToAppURL(context.url));
|
|
277
302
|
} else if (context.error_code) {
|
|
278
303
|
res.set({
|
|
279
304
|
'Cache-Control': 'no-cache',
|
|
280
305
|
});
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
extractScripts={
|
|
290
|
-
config.settings.serverConfig.extractScripts?.errorPages ||
|
|
291
|
-
process.env.NODE_ENV !== 'production'
|
|
292
|
-
}
|
|
293
|
-
criticalCss={readCriticalCss(req)}
|
|
294
|
-
apiPath={res.locals.detectedHost || config.settings.apiPath}
|
|
295
|
-
publicURL={
|
|
296
|
-
res.locals.detectedHost || config.settings.publicURL
|
|
297
|
-
}
|
|
298
|
-
/>,
|
|
299
|
-
)}
|
|
300
|
-
`,
|
|
306
|
+
sendHtmlResponse(
|
|
307
|
+
res,
|
|
308
|
+
context.error_code,
|
|
309
|
+
extractor,
|
|
310
|
+
markup,
|
|
311
|
+
store,
|
|
312
|
+
req,
|
|
313
|
+
config,
|
|
301
314
|
);
|
|
302
315
|
} else {
|
|
303
|
-
res
|
|
304
|
-
`<!doctype html>
|
|
305
|
-
${renderToString(
|
|
306
|
-
<Html
|
|
307
|
-
extractor={extractor}
|
|
308
|
-
markup={markup}
|
|
309
|
-
store={store}
|
|
310
|
-
criticalCss={readCriticalCss(req)}
|
|
311
|
-
apiPath={res.locals.detectedHost || config.settings.apiPath}
|
|
312
|
-
publicURL={
|
|
313
|
-
res.locals.detectedHost || config.settings.publicURL
|
|
314
|
-
}
|
|
315
|
-
/>,
|
|
316
|
-
)}
|
|
317
|
-
`,
|
|
318
|
-
);
|
|
316
|
+
sendHtmlResponse(res, 200, extractor, markup, store, req, config);
|
|
319
317
|
}
|
|
320
318
|
}, errorHandler)
|
|
321
319
|
.catch(errorHandler);
|
|
@@ -318,6 +318,16 @@ body.has-toolbar.has-sidebar-collapsed .ui.wrapper > .ui.inner.block.full {
|
|
|
318
318
|
0 2px 4px rgba(0, 0, 0, 0.05);
|
|
319
319
|
transform: translate(-50%, 0);
|
|
320
320
|
|
|
321
|
+
.separator {
|
|
322
|
+
position: relative;
|
|
323
|
+
top: 5px;
|
|
324
|
+
display: inline-block;
|
|
325
|
+
height: 24px;
|
|
326
|
+
border-right: 1px solid #ddd;
|
|
327
|
+
margin: 0 0 4px 4px;
|
|
328
|
+
vertical-align: bottom;
|
|
329
|
+
}
|
|
330
|
+
|
|
321
331
|
form {
|
|
322
332
|
display: flex;
|
|
323
333
|
}
|
|
@@ -591,16 +601,6 @@ body.has-toolbar.has-sidebar-collapsed .ui.wrapper > .ui.inner.block.full {
|
|
|
591
601
|
height: 100%;
|
|
592
602
|
}
|
|
593
603
|
|
|
594
|
-
.separator {
|
|
595
|
-
position: relative;
|
|
596
|
-
top: 5px;
|
|
597
|
-
display: inline-block;
|
|
598
|
-
height: 24px;
|
|
599
|
-
border-right: 1px solid #ddd;
|
|
600
|
-
margin: 0 0 4px 4px;
|
|
601
|
-
vertical-align: bottom;
|
|
602
|
-
}
|
|
603
|
-
|
|
604
604
|
// HTML block
|
|
605
605
|
.html-editor {
|
|
606
606
|
z-index: 1;
|
|
@@ -41,3 +41,86 @@
|
|
|
41
41
|
border: none !important;
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
.object-browser {
|
|
46
|
+
.mode-switch {
|
|
47
|
+
margin-right: 8px;
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
float: right;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
header h2 {
|
|
53
|
+
margin: 2px 0 !important;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.searchResults {
|
|
57
|
+
margin-left: 20px;
|
|
58
|
+
font-size: 14px;
|
|
59
|
+
-webkit-font-smoothing: antialiased;
|
|
60
|
+
-moz-osx-font-smoothing: grayscale;
|
|
61
|
+
line-height: 1.5;
|
|
62
|
+
text-rendering: optimizeLegibility;
|
|
63
|
+
text-size-adjust: 100%;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
ul.object-listing {
|
|
67
|
+
padding: 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.image-wrapper {
|
|
71
|
+
display: block;
|
|
72
|
+
margin: 16px;
|
|
73
|
+
float: left;
|
|
74
|
+
|
|
75
|
+
img,
|
|
76
|
+
.icon-wrapper {
|
|
77
|
+
background-color: #edf1f2;
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
outline: 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.selected {
|
|
83
|
+
outline: solid 3px #517776 !important;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
img:hover,
|
|
87
|
+
.icon-wrapper:hover {
|
|
88
|
+
outline: solid 3px rgb(187, 198, 200);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.image-preview,
|
|
92
|
+
.image-preview:hover {
|
|
93
|
+
display: flex;
|
|
94
|
+
border: 0;
|
|
95
|
+
border-radius: 0;
|
|
96
|
+
box-shadow: none;
|
|
97
|
+
|
|
98
|
+
img {
|
|
99
|
+
width: 200px;
|
|
100
|
+
height: 200px;
|
|
101
|
+
object-fit: contain;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.image-preview,
|
|
106
|
+
.image-title {
|
|
107
|
+
cursor: pointer;
|
|
108
|
+
text-align: center;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.image-title {
|
|
112
|
+
margin-top: 5px;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.image-title-content {
|
|
116
|
+
overflow: hidden;
|
|
117
|
+
text-overflow: ellipsis;
|
|
118
|
+
white-space: nowrap;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.icon-wrapper {
|
|
122
|
+
display: flex;
|
|
123
|
+
padding: 46px;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|