@plone/volto 17.0.0-alpha.20 → 17.0.0-alpha.22
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/.gitignore~ +71 -0
- package/.yarn/install-state.gz +0 -0
- package/CHANGELOG.md +49 -0
- package/cypress/support/commands.js +2 -1
- package/cypress/support/e2e.js +1 -2
- package/locales/ca/LC_MESSAGES/volto.po +24 -5
- package/locales/ca.json +1 -1
- package/locales/de/LC_MESSAGES/volto.po +37 -18
- package/locales/de.json +1 -1
- package/locales/en/LC_MESSAGES/volto.po +25 -6
- package/locales/en.json +1 -1
- package/locales/es/LC_MESSAGES/volto.po +25 -6
- package/locales/es.json +1 -1
- package/locales/eu/LC_MESSAGES/volto.po +24 -5
- package/locales/eu.json +1 -1
- package/locales/fi/LC_MESSAGES/volto.po +24 -5
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +24 -5
- package/locales/fr.json +1 -1
- package/locales/it/LC_MESSAGES/volto.po +250 -231
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +24 -5
- package/locales/ja.json +1 -1
- package/locales/nl/LC_MESSAGES/volto.po +24 -5
- package/locales/nl.json +1 -1
- package/locales/pt/LC_MESSAGES/volto.po +24 -5
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +25 -6
- package/locales/pt_BR.json +1 -1
- package/locales/ro/LC_MESSAGES/volto.po +24 -5
- package/locales/ro.json +1 -1
- package/locales/volto.pot +25 -6
- package/locales/zh_CN/LC_MESSAGES/volto.po +24 -5
- package/locales/zh_CN.json +1 -1
- package/news/4547.breaking~ +1 -0
- package/package.json +6 -6
- package/packages/volto-slate/package.json +1 -1
- package/src/actions/relations/rebuild.js +7 -7
- package/src/components/index.js +1 -0
- package/src/components/manage/Actions/Actions.jsx +133 -243
- package/src/components/manage/Blocks/Container/Edit.jsx +4 -1
- package/src/components/manage/Blocks/Container/EditBlockWrapper.jsx +1 -0
- package/src/components/manage/Blocks/Grid/Edit.jsx +13 -1
- package/src/components/manage/Blocks/Image/Edit.jsx +40 -5
- package/src/components/manage/Blocks/Image/Edit.test.jsx +2 -0
- package/src/components/manage/Blocks/Image/ImageSidebar.jsx +64 -15
- package/src/components/manage/Blocks/Image/View.jsx +26 -5
- package/src/components/manage/Blocks/Image/View.test.jsx +20 -0
- package/src/components/manage/Blocks/Image/schema.js +1 -9
- package/src/components/manage/Blocks/Image/utils.js +14 -0
- package/src/components/manage/Blocks/LeadImage/Edit.jsx +32 -10
- package/src/components/manage/Blocks/LeadImage/Edit.test.jsx +11 -1
- package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.jsx +28 -9
- package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +8 -2
- package/src/components/manage/Blocks/LeadImage/View.jsx +50 -38
- package/src/components/manage/Blocks/LeadImage/View.test.jsx +11 -1
- package/src/components/manage/Blocks/Listing/SummaryTemplate.jsx +1 -1
- package/src/components/manage/Blocks/Maps/Edit.jsx +135 -209
- package/src/components/manage/Blocks/Search/SearchBlockView.jsx +3 -2
- package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +13 -23
- package/src/components/manage/Contents/Contents.jsx +8 -6
- package/src/components/manage/Contents/ContentsPropertiesModal.jsx +1 -13
- package/src/components/manage/Controlpanels/Groups/RenderGroups.jsx +2 -2
- package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +30 -7
- package/src/components/manage/Controlpanels/Relations/Relations.jsx +2 -2
- package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +53 -59
- package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +2 -2
- package/src/components/manage/Delete/Delete.jsx +96 -171
- package/src/components/manage/Sidebar/AlignBlock.jsx +1 -1
- package/src/components/manage/Widgets/SelectUtils.js +1 -1
- package/src/components/manage/Workflow/Workflow.jsx +75 -184
- package/src/components/theme/Image/Image.jsx +96 -0
- package/src/components/theme/Image/Image.test.jsx +125 -0
- package/src/components/theme/Logo/Logo.jsx +2 -0
- package/src/components/theme/PasswordReset/RequestPasswordReset.jsx +95 -170
- package/src/components/theme/PreviewImage/PreviewImage.jsx +25 -14
- package/src/components/theme/PreviewImage/PreviewImage.test.js +39 -16
- package/src/components/theme/View/AlbumView.jsx +11 -15
- package/src/components/theme/View/EventView.jsx +30 -23
- package/src/components/theme/View/ImageView.jsx +5 -2
- package/src/components/theme/View/ImageView.test.jsx +4 -0
- package/src/components/theme/View/ListingView.jsx +5 -3
- package/src/components/theme/View/NewsItemView.jsx +7 -13
- package/src/components/theme/View/SummaryView.jsx +4 -3
- package/src/config/Blocks.jsx +2 -0
- package/src/config/Components.jsx +3 -1
- package/src/config/index.js~ +223 -0
- package/src/express-middleware/files.js +8 -6
- package/src/express-middleware/images.js +7 -1
- package/src/helpers/MessageLabels/MessageLabels.js +6 -0
- package/src/helpers/Url/Url.js +22 -1
- package/src/helpers/Url/Url.test.js +41 -0
- package/src/reducers/relations/relations.js +1 -1
- package/test-setup-config.js +9 -1
- package/theme/themes/pastanaga/extras/blocks.less +3 -1
- package/theme/themes/pastanaga/extras/main.less +5 -0
- package/packages/volto-slate/build/messages/src/blocks/Table/TableBlockEdit.json +0 -90
- package/packages/volto-slate/build/messages/src/blocks/Text/DefaultTextBlockEditor.json +0 -6
- package/packages/volto-slate/build/messages/src/blocks/Text/DetachedTextBlockEditor.json +0 -6
- package/packages/volto-slate/build/messages/src/blocks/Text/SlashMenu.json +0 -6
- package/packages/volto-slate/build/messages/src/editor/plugins/AdvancedLink/index.json +0 -10
- package/packages/volto-slate/build/messages/src/editor/plugins/Link/index.json +0 -10
- package/packages/volto-slate/build/messages/src/editor/plugins/Table/index.json +0 -30
- package/packages/volto-slate/build/messages/src/elementEditor/messages.json +0 -10
- package/packages/volto-slate/build/messages/src/widgets/HtmlSlateWidget.json +0 -6
- package/packages/volto-slate/build/messages/src/widgets/RichTextWidgetView.json +0 -6
- package/src/components/manage/Blocks/Teaser/utils.js +0 -44
- package/src/components/manage/Blocks/Teaser/utils.test.jsx +0 -229
|
@@ -5,12 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
-
import { Container as SemanticContainer
|
|
9
|
-
import {
|
|
10
|
-
hasBlocksData,
|
|
11
|
-
flattenToAppURL,
|
|
12
|
-
flattenHTMLToAppURL,
|
|
13
|
-
} from '@plone/volto/helpers';
|
|
8
|
+
import { Container as SemanticContainer } from 'semantic-ui-react';
|
|
9
|
+
import { hasBlocksData, flattenHTMLToAppURL } from '@plone/volto/helpers';
|
|
14
10
|
import RenderBlocks from '@plone/volto/components/theme/View/RenderBlocks';
|
|
15
11
|
import config from '@plone/volto/registry';
|
|
16
12
|
|
|
@@ -21,6 +17,7 @@ import config from '@plone/volto/registry';
|
|
|
21
17
|
* @returns {string} Markup of the component.
|
|
22
18
|
*/
|
|
23
19
|
const NewsItemView = ({ content }) => {
|
|
20
|
+
const Image = config.getComponent({ name: 'Image' }).component;
|
|
24
21
|
const Container =
|
|
25
22
|
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
26
23
|
|
|
@@ -41,15 +38,12 @@ const NewsItemView = ({ content }) => {
|
|
|
41
38
|
)}
|
|
42
39
|
{content.image && (
|
|
43
40
|
<Image
|
|
44
|
-
className="documentImage"
|
|
41
|
+
className="documentImage ui right floated image"
|
|
45
42
|
alt={content.title}
|
|
46
43
|
title={content.title}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
: flattenToAppURL(content.image.scales.mini.download)
|
|
51
|
-
}
|
|
52
|
-
floated="right"
|
|
44
|
+
item={content}
|
|
45
|
+
imageField="image"
|
|
46
|
+
responsive={true}
|
|
53
47
|
/>
|
|
54
48
|
)}
|
|
55
49
|
{content.text && (
|
|
@@ -8,7 +8,6 @@ import PropTypes from 'prop-types';
|
|
|
8
8
|
import { UniversalLink } from '@plone/volto/components';
|
|
9
9
|
import { Container as SemanticContainer } from 'semantic-ui-react';
|
|
10
10
|
import { FormattedMessage } from 'react-intl';
|
|
11
|
-
import PreviewImage from '../PreviewImage/PreviewImage';
|
|
12
11
|
import config from '@plone/volto/registry';
|
|
13
12
|
|
|
14
13
|
/**
|
|
@@ -20,6 +19,7 @@ import config from '@plone/volto/registry';
|
|
|
20
19
|
const SummaryView = ({ content }) => {
|
|
21
20
|
const Container =
|
|
22
21
|
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
22
|
+
const PreviewImage = config.getComponent({ name: 'PreviewImage' }).component;
|
|
23
23
|
|
|
24
24
|
return (
|
|
25
25
|
<Container className="view-wrapper summary-view">
|
|
@@ -41,9 +41,10 @@ const SummaryView = ({ content }) => {
|
|
|
41
41
|
{item.image_field && (
|
|
42
42
|
<PreviewImage
|
|
43
43
|
item={item}
|
|
44
|
-
alt={item.image_caption
|
|
45
|
-
size="thumb"
|
|
44
|
+
alt={item.image_caption}
|
|
46
45
|
className="ui image floated right clear"
|
|
46
|
+
responsive={true}
|
|
47
|
+
loading="lazy"
|
|
47
48
|
/>
|
|
48
49
|
)}
|
|
49
50
|
{item.description && <p>{item.description}</p>}
|
package/src/config/Blocks.jsx
CHANGED
|
@@ -75,6 +75,7 @@ import {
|
|
|
75
75
|
DateRangeFacetFilterListEntry,
|
|
76
76
|
} from '@plone/volto/components/manage/Blocks/Search/components';
|
|
77
77
|
import getListingBlockAsyncData from '@plone/volto/components/manage/Blocks/Listing/getAsyncData';
|
|
78
|
+
import { getImageBlockSizes } from '@plone/volto/components/manage/Blocks/Image/utils';
|
|
78
79
|
|
|
79
80
|
// block sidebar schemas (not the Dexterity Layout block settings schemas)
|
|
80
81
|
import HeroImageLeftBlockSchema from '@plone/volto/components/manage/Blocks/HeroImageLeft/schema';
|
|
@@ -258,6 +259,7 @@ const blocksConfig = {
|
|
|
258
259
|
restricted: false,
|
|
259
260
|
mostUsed: true,
|
|
260
261
|
sidebarTab: 1,
|
|
262
|
+
getSizes: getImageBlockSizes,
|
|
261
263
|
},
|
|
262
264
|
leadimage: {
|
|
263
265
|
id: 'leadimage',
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { App, PreviewImage } from '@plone/volto/components';
|
|
1
|
+
import { App, PreviewImage, Image } from '@plone/volto/components';
|
|
2
2
|
|
|
3
|
+
// Register components.
|
|
3
4
|
export const components = {
|
|
4
5
|
PreviewImage: { component: PreviewImage },
|
|
5
6
|
App: { component: App },
|
|
7
|
+
Image: { component: Image },
|
|
6
8
|
};
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config.
|
|
3
|
+
* @module config
|
|
4
|
+
*/
|
|
5
|
+
import { parse as parseUrl } from 'url';
|
|
6
|
+
import { defaultWidget, widgetMapping } from './Widgets';
|
|
7
|
+
import {
|
|
8
|
+
layoutViews,
|
|
9
|
+
contentTypesViews,
|
|
10
|
+
defaultView,
|
|
11
|
+
errorViews,
|
|
12
|
+
layoutViewsNamesMapping,
|
|
13
|
+
} from './Views';
|
|
14
|
+
import { nonContentRoutes } from './NonContentRoutes';
|
|
15
|
+
import {
|
|
16
|
+
groupBlocksOrder,
|
|
17
|
+
requiredBlocks,
|
|
18
|
+
blocksConfig,
|
|
19
|
+
initialBlocks,
|
|
20
|
+
initialBlocksFocus,
|
|
21
|
+
} from './Blocks';
|
|
22
|
+
import { components } from './Components';
|
|
23
|
+
import { loadables } from './Loadables';
|
|
24
|
+
import { workflowMapping } from './Workflows';
|
|
25
|
+
|
|
26
|
+
import { contentIcons } from './ContentIcons';
|
|
27
|
+
import { styleClassNameConverters, styleClassNameExtenders } from './Style';
|
|
28
|
+
import {
|
|
29
|
+
controlPanelsIcons,
|
|
30
|
+
filterControlPanels,
|
|
31
|
+
filterControlPanelsSchema,
|
|
32
|
+
} from './ControlPanels';
|
|
33
|
+
|
|
34
|
+
import { richtextEditorSettings, richtextViewSettings } from './RichTextEditor';
|
|
35
|
+
|
|
36
|
+
import applyAddonConfiguration, { addonsInfo } from 'load-volto-addons';
|
|
37
|
+
|
|
38
|
+
import ConfigRegistry from '@plone/volto/registry';
|
|
39
|
+
|
|
40
|
+
const host = process.env.HOST || 'localhost';
|
|
41
|
+
const port = process.env.PORT || '3000';
|
|
42
|
+
|
|
43
|
+
const apiPath =
|
|
44
|
+
process.env.RAZZLE_API_PATH ||
|
|
45
|
+
(__DEVELOPMENT__ ? `http://${host}:${port}` : '');
|
|
46
|
+
|
|
47
|
+
const getServerURL = (url) => {
|
|
48
|
+
if (!url) return;
|
|
49
|
+
const apiPathURL = parseUrl(url);
|
|
50
|
+
return `${apiPathURL.protocol}//${apiPathURL.hostname}${
|
|
51
|
+
apiPathURL.port ? `:${apiPathURL.port}` : ''
|
|
52
|
+
}`;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Sensible defaults for publicURL
|
|
56
|
+
// if RAZZLE_PUBLIC_URL is present, use it
|
|
57
|
+
// if in DEV, use the host/port combination by default
|
|
58
|
+
// if in PROD, assume it's RAZZLE_API_PATH server name (no /api or alikes) or fallback
|
|
59
|
+
// to DEV settings if RAZZLE_API_PATH is not present
|
|
60
|
+
const publicURL =
|
|
61
|
+
process.env.RAZZLE_PUBLIC_URL ||
|
|
62
|
+
(__DEVELOPMENT__
|
|
63
|
+
? `http://${host}:${port}`
|
|
64
|
+
: getServerURL(process.env.RAZZLE_API_PATH) || `http://${host}:${port}`);
|
|
65
|
+
|
|
66
|
+
const serverConfig =
|
|
67
|
+
typeof __SERVER__ !== 'undefined' && __SERVER__
|
|
68
|
+
? require('./server').default
|
|
69
|
+
: {};
|
|
70
|
+
|
|
71
|
+
let config = {
|
|
72
|
+
settings: {
|
|
73
|
+
host,
|
|
74
|
+
port,
|
|
75
|
+
// The URL Volto is going to be served (see sensible defaults above)
|
|
76
|
+
publicURL,
|
|
77
|
+
apiPath,
|
|
78
|
+
apiExpanders: [
|
|
79
|
+
// Add the following expanders for only issuing a single request.
|
|
80
|
+
// https://6.docs.plone.org/volto/configuration/settings-reference.html#term-apiExpanders
|
|
81
|
+
// {
|
|
82
|
+
// match: '',
|
|
83
|
+
// GET_CONTENT: ['breadcrumbs', 'navigation', 'actions', 'types'],
|
|
84
|
+
// },
|
|
85
|
+
],
|
|
86
|
+
// Internal proxy to bypass CORS *while developing*. NOT intended for production use.
|
|
87
|
+
// In production is recommended you use a Seamless mode deployment using a web server in
|
|
88
|
+
// front of both the frontend and the backend so you can bypass CORS safely.
|
|
89
|
+
// https://6.docs.plone.org/volto/deploying/seamless-mode.html
|
|
90
|
+
devProxyToApiPath:
|
|
91
|
+
process.env.RAZZLE_DEV_PROXY_API_PATH ||
|
|
92
|
+
process.env.RAZZLE_INTERNAL_API_PATH ||
|
|
93
|
+
process.env.RAZZLE_API_PATH ||
|
|
94
|
+
'http://localhost:8080/Plone', // Set it to '' for disabling the proxy
|
|
95
|
+
// proxyRewriteTarget Set it for set a custom target for the proxy or overide the internal VHM rewrite
|
|
96
|
+
// proxyRewriteTarget: '/VirtualHostBase/http/localhost:8080/Plone/VirtualHostRoot/_vh_api'
|
|
97
|
+
// proxyRewriteTarget: 'https://myvoltositeinproduction.com'
|
|
98
|
+
proxyRewriteTarget: process.env.RAZZLE_PROXY_REWRITE_TARGET || undefined,
|
|
99
|
+
// apiPath: process.env.RAZZLE_API_PATH || 'http://localhost:8000', // for Volto reference
|
|
100
|
+
// apiPath: process.env.RAZZLE_API_PATH || 'http://localhost:8081/db/web', // for guillotina
|
|
101
|
+
actions_raising_api_errors: ['GET_CONTENT', 'UPDATE_CONTENT'],
|
|
102
|
+
internalApiPath: process.env.RAZZLE_INTERNAL_API_PATH || undefined,
|
|
103
|
+
websockets: process.env.RAZZLE_WEBSOCKETS || false,
|
|
104
|
+
// TODO: legacyTraverse to be removed when the use of the legacy traverse is deprecated.
|
|
105
|
+
legacyTraverse: process.env.RAZZLE_LEGACY_TRAVERSE || false,
|
|
106
|
+
cookieExpires: 15552000, //in seconds. Default is 6 month (15552000)
|
|
107
|
+
nonContentRoutes,
|
|
108
|
+
richtextEditorSettings, // Part of draftjs support, to be removed
|
|
109
|
+
richtextViewSettings, // Part of draftjs support, to be removed
|
|
110
|
+
imageObjects: ['Image'],
|
|
111
|
+
reservedIds: ['login', 'layout', 'plone', 'zip', 'properties'],
|
|
112
|
+
downloadableObjects: ['File'], //list of content-types for which the direct download of the file will be carried out if the user is not authenticated
|
|
113
|
+
viewableInBrowserObjects: [], //ex: ['File']. List of content-types for which the file will be displayed in browser if the user is not authenticated
|
|
114
|
+
listingPreviewImageField: 'image', // deprecated from Volto 14 onwards
|
|
115
|
+
openExternalLinkInNewTab: false,
|
|
116
|
+
notSupportedBrowsers: ['ie'],
|
|
117
|
+
defaultPageSize: 25,
|
|
118
|
+
isMultilingual: false,
|
|
119
|
+
supportedLanguages: ['en'],
|
|
120
|
+
defaultLanguage: 'en',
|
|
121
|
+
navDepth: 1,
|
|
122
|
+
expressMiddleware: serverConfig.expressMiddleware, // BBB
|
|
123
|
+
defaultBlockType: 'slate',
|
|
124
|
+
verticalFormTabs: false,
|
|
125
|
+
useEmailAsLogin: false,
|
|
126
|
+
persistentReducers: ['blocksClipboard'],
|
|
127
|
+
initialReducersBlacklist: [], // reducers in this list won't be hydrated in windows.__data
|
|
128
|
+
asyncPropsExtenders: [], // per route asyncConnect customizers
|
|
129
|
+
contentIcons: contentIcons,
|
|
130
|
+
loadables,
|
|
131
|
+
lazyBundles: {
|
|
132
|
+
cms: [
|
|
133
|
+
'prettierStandalone',
|
|
134
|
+
'prettierParserHtml',
|
|
135
|
+
'prismCore',
|
|
136
|
+
'toastify',
|
|
137
|
+
'reactSelect',
|
|
138
|
+
'reactBeautifulDnd',
|
|
139
|
+
// 'diffLib',
|
|
140
|
+
],
|
|
141
|
+
draftEditor: [
|
|
142
|
+
'immutableLib',
|
|
143
|
+
'draftJs',
|
|
144
|
+
'draftJsLibIsSoftNewlineEvent',
|
|
145
|
+
'draftJsFilters',
|
|
146
|
+
'draftJsInlineToolbarPlugin',
|
|
147
|
+
'draftJsImportHtml',
|
|
148
|
+
'draftJsBlockBreakoutPlugin',
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
appExtras: [],
|
|
152
|
+
maxResponseSize: 2000000000, // This is superagent default (200 mb)
|
|
153
|
+
serverConfig,
|
|
154
|
+
storeExtenders: [],
|
|
155
|
+
showTags: true,
|
|
156
|
+
controlpanels: [],
|
|
157
|
+
controlPanelsIcons,
|
|
158
|
+
filterControlPanels,
|
|
159
|
+
filterControlPanelsSchema,
|
|
160
|
+
externalRoutes: [
|
|
161
|
+
// URL to be considered as external
|
|
162
|
+
// {
|
|
163
|
+
// match: {
|
|
164
|
+
// path: '/news',
|
|
165
|
+
// exact: false,
|
|
166
|
+
// strict: false,
|
|
167
|
+
// },
|
|
168
|
+
// url(payload) {
|
|
169
|
+
// return payload.location.pathname;
|
|
170
|
+
// },
|
|
171
|
+
// },
|
|
172
|
+
],
|
|
173
|
+
showSelfRegistration: false,
|
|
174
|
+
contentMetadataTagsImageField: 'image',
|
|
175
|
+
hasWorkingCopySupport: false,
|
|
176
|
+
maxUndoLevels: 200, // undo history size for the main form
|
|
177
|
+
addonsInfo: addonsInfo,
|
|
178
|
+
workflowMapping,
|
|
179
|
+
errorHandlers: [], // callables for unhandled errors
|
|
180
|
+
styleClassNameConverters,
|
|
181
|
+
hashLinkSmoothScroll: false,
|
|
182
|
+
styleClassNameExtenders,
|
|
183
|
+
querystringSearchGet: false,
|
|
184
|
+
},
|
|
185
|
+
experimental: {
|
|
186
|
+
addBlockButton: {
|
|
187
|
+
enabled: false,
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
widgets: {
|
|
191
|
+
...widgetMapping,
|
|
192
|
+
default: defaultWidget,
|
|
193
|
+
},
|
|
194
|
+
views: {
|
|
195
|
+
layoutViews,
|
|
196
|
+
contentTypesViews,
|
|
197
|
+
defaultView,
|
|
198
|
+
errorViews,
|
|
199
|
+
layoutViewsNamesMapping,
|
|
200
|
+
},
|
|
201
|
+
blocks: {
|
|
202
|
+
requiredBlocks,
|
|
203
|
+
blocksConfig,
|
|
204
|
+
groupBlocksOrder,
|
|
205
|
+
initialBlocks,
|
|
206
|
+
initialBlocksFocus,
|
|
207
|
+
showEditBlocksInBabelView: false,
|
|
208
|
+
},
|
|
209
|
+
addonRoutes: [],
|
|
210
|
+
addonReducers: {},
|
|
211
|
+
components,
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
ConfigRegistry.settings = config.settings;
|
|
215
|
+
ConfigRegistry.experimental = config.experimental;
|
|
216
|
+
ConfigRegistry.blocks = config.blocks;
|
|
217
|
+
ConfigRegistry.views = config.views;
|
|
218
|
+
ConfigRegistry.widgets = config.widgets;
|
|
219
|
+
ConfigRegistry.addonRoutes = config.addonRoutes;
|
|
220
|
+
ConfigRegistry.addonReducers = config.addonReducers;
|
|
221
|
+
ConfigRegistry.components = config.components;
|
|
222
|
+
|
|
223
|
+
applyAddonConfiguration(ConfigRegistry);
|
|
@@ -2,11 +2,13 @@ import express from 'express';
|
|
|
2
2
|
import { getAPIResourceWithAuth } from '@plone/volto/helpers';
|
|
3
3
|
|
|
4
4
|
const HEADERS = [
|
|
5
|
-
'
|
|
6
|
-
'
|
|
7
|
-
'
|
|
8
|
-
'
|
|
9
|
-
'
|
|
5
|
+
'accept-ranges',
|
|
6
|
+
'cache-control',
|
|
7
|
+
'content-disposition',
|
|
8
|
+
'content-range',
|
|
9
|
+
'content-type',
|
|
10
|
+
'x-sendfile',
|
|
11
|
+
'x-accel-redirect',
|
|
10
12
|
];
|
|
11
13
|
|
|
12
14
|
function filesMiddlewareFn(req, res, next) {
|
|
@@ -14,7 +16,7 @@ function filesMiddlewareFn(req, res, next) {
|
|
|
14
16
|
.then((resource) => {
|
|
15
17
|
// Just forward the headers that we need
|
|
16
18
|
HEADERS.forEach((header) => {
|
|
17
|
-
if (resource.
|
|
19
|
+
if (resource.headers[header]) {
|
|
18
20
|
res.set(header, resource.get(header));
|
|
19
21
|
}
|
|
20
22
|
});
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import { getAPIResourceWithAuth } from '@plone/volto/helpers';
|
|
3
3
|
|
|
4
|
-
const HEADERS = [
|
|
4
|
+
const HEADERS = [
|
|
5
|
+
'content-type',
|
|
6
|
+
'content-disposition',
|
|
7
|
+
'cache-control',
|
|
8
|
+
'x-sendfile',
|
|
9
|
+
'x-accel-redirect',
|
|
10
|
+
];
|
|
5
11
|
|
|
6
12
|
function imageMiddlewareFn(req, res, next) {
|
|
7
13
|
getAPIResourceWithAuth(req)
|
|
@@ -312,6 +312,12 @@ export const messages = defineMessages({
|
|
|
312
312
|
id: 'flush intIds and rebuild relations',
|
|
313
313
|
defaultMessage: 'flush intIds and rebuild relations',
|
|
314
314
|
},
|
|
315
|
+
flushAndRebuildRelationsHints: {
|
|
316
|
+
id: 'flushAndRebuildRelationsHints',
|
|
317
|
+
defaultMessage:
|
|
318
|
+
'<ul><li>Regenerate intIds (tokens of relations in relation catalog)</li><li>Rebuild relations</li></ul><p>Check the log for details!</p><p><b>Warning</b>: If you have add-ons relying on intIds, you should not flush them.</p>',
|
|
319
|
+
},
|
|
320
|
+
|
|
315
321
|
addPotentialTargetsPath: {
|
|
316
322
|
id: 'target path',
|
|
317
323
|
defaultMessage: 'target path',
|
package/src/helpers/Url/Url.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @module helpers/Url
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { last, memoize } from 'lodash';
|
|
6
|
+
import { last, memoize, isArray, isObject, isString } from 'lodash';
|
|
7
7
|
import { urlRegex, telRegex, mailRegex } from './urlRegex';
|
|
8
8
|
import prependHttp from 'prepend-http';
|
|
9
9
|
import config from '@plone/volto/registry';
|
|
@@ -251,6 +251,27 @@ export function isUrl(url) {
|
|
|
251
251
|
return urlRegex().test(url);
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Get field url
|
|
256
|
+
* @method getFieldURL
|
|
257
|
+
* @param {object} data
|
|
258
|
+
* @returns {string | any} URL string value if field is of url type or any.
|
|
259
|
+
*/
|
|
260
|
+
export const getFieldURL = (data) => {
|
|
261
|
+
let url = data;
|
|
262
|
+
const _isObject = data && isObject(data) && !isArray(data);
|
|
263
|
+
if (_isObject && data['@type'] === 'URL') {
|
|
264
|
+
url = data['value'] ?? data['url'] ?? data['href'] ?? data;
|
|
265
|
+
} else if (_isObject) {
|
|
266
|
+
url = data['@id'] ?? data['url'] ?? data['href'] ?? data;
|
|
267
|
+
}
|
|
268
|
+
if (isArray(data)) {
|
|
269
|
+
url = data.map((item) => getFieldURL(item));
|
|
270
|
+
}
|
|
271
|
+
if (isString(url) && isInternalURL(url)) return flattenToAppURL(url);
|
|
272
|
+
return url;
|
|
273
|
+
};
|
|
274
|
+
|
|
254
275
|
/**
|
|
255
276
|
* Normalize URL, adds protocol (if required eg. user has not entered the protocol)
|
|
256
277
|
* @method normalizeUrl
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
isCmsUi,
|
|
11
11
|
isInternalURL,
|
|
12
12
|
isUrl,
|
|
13
|
+
getFieldURL,
|
|
13
14
|
normalizeUrl,
|
|
14
15
|
removeProtocol,
|
|
15
16
|
addAppURL,
|
|
@@ -260,6 +261,46 @@ describe('Url', () => {
|
|
|
260
261
|
expect(isUrl(href)).toBe(false);
|
|
261
262
|
});
|
|
262
263
|
});
|
|
264
|
+
describe('getFieldURL', () => {
|
|
265
|
+
it('returns app URL if the field is a string', () => {
|
|
266
|
+
const field = `${settings.apiPath}/foo/bar`;
|
|
267
|
+
expect(getFieldURL(field)).toBe('/foo/bar');
|
|
268
|
+
});
|
|
269
|
+
it('returns app URL if the field is an object with "@id"', () => {
|
|
270
|
+
const field = { '@id': '/foo/bar' };
|
|
271
|
+
expect(getFieldURL(field)).toBe('/foo/bar');
|
|
272
|
+
});
|
|
273
|
+
it('returns app URL if the field is an object with type URL', () => {
|
|
274
|
+
const field = { '@type': 'URL', value: '/foo/bar' };
|
|
275
|
+
expect(getFieldURL(field)).toBe('/foo/bar');
|
|
276
|
+
});
|
|
277
|
+
it('returns app URL if the field is an object with url or href properties', () => {
|
|
278
|
+
const fieldUrl = { url: '/foo/bar' };
|
|
279
|
+
const fieldHref = { href: '/foo/bar' };
|
|
280
|
+
expect(getFieldURL(fieldUrl)).toBe('/foo/bar');
|
|
281
|
+
expect(getFieldURL(fieldHref)).toBe('/foo/bar');
|
|
282
|
+
});
|
|
283
|
+
it('returns array of app URL if the field is an array of strings', () => {
|
|
284
|
+
const field = [
|
|
285
|
+
`${settings.apiPath}/foo/bar/1`,
|
|
286
|
+
`${settings.apiPath}/foo/bar/2`,
|
|
287
|
+
];
|
|
288
|
+
expect(getFieldURL(field)).toStrictEqual(['/foo/bar/1', '/foo/bar/2']);
|
|
289
|
+
});
|
|
290
|
+
it('returns array of app URL if the field is an array of objects', () => {
|
|
291
|
+
const field = [
|
|
292
|
+
{
|
|
293
|
+
'@type': 'URL',
|
|
294
|
+
value: `${settings.apiPath}/foo/bar/1`,
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
'@type': 'URL',
|
|
298
|
+
value: `${settings.apiPath}/foo/bar/2`,
|
|
299
|
+
},
|
|
300
|
+
];
|
|
301
|
+
expect(getFieldURL(field)).toStrictEqual(['/foo/bar/1', '/foo/bar/2']);
|
|
302
|
+
});
|
|
303
|
+
});
|
|
263
304
|
describe('normalizeUrl', () => {
|
|
264
305
|
it('normalizeUrl test', () => {
|
|
265
306
|
const href = `www.example.com`;
|
package/test-setup-config.js
CHANGED
|
@@ -173,7 +173,15 @@ config.set('widgets', {
|
|
|
173
173
|
default: BaseWidget('default'),
|
|
174
174
|
});
|
|
175
175
|
|
|
176
|
-
config.set('components', {
|
|
176
|
+
config.set('components', {
|
|
177
|
+
PreviewImage: {
|
|
178
|
+
component: (props) => <img alt="PreviewImage component mock" {...props} />,
|
|
179
|
+
},
|
|
180
|
+
Image: {
|
|
181
|
+
// eslint-disable-next-line jsx-a11y/img-redundant-alt
|
|
182
|
+
component: (props) => <img alt="Image component mock" {...props} />,
|
|
183
|
+
},
|
|
184
|
+
});
|
|
177
185
|
config.set('experimental', {
|
|
178
186
|
addBlockButton: {
|
|
179
187
|
enabled: false,
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
.block .block:not(.inner)::before {
|
|
24
24
|
position: absolute;
|
|
25
|
-
z-index:
|
|
25
|
+
z-index: auto;
|
|
26
26
|
top: -9px;
|
|
27
27
|
left: -9px;
|
|
28
28
|
width: ~'calc(100% + 18px)';
|
|
@@ -811,6 +811,7 @@ body.has-toolbar.has-sidebar-collapsed .ui.wrapper > .ui.inner.block.full {
|
|
|
811
811
|
.listing-item a {
|
|
812
812
|
display: flex;
|
|
813
813
|
width: 100%;
|
|
814
|
+
align-items: flex-start;
|
|
814
815
|
|
|
815
816
|
@media only screen and (max-width: (@largestMobileScreen)) {
|
|
816
817
|
flex-direction: column;
|
|
@@ -822,6 +823,7 @@ body.has-toolbar.has-sidebar-collapsed .ui.wrapper > .ui.inner.block.full {
|
|
|
822
823
|
|
|
823
824
|
img {
|
|
824
825
|
width: 15%;
|
|
826
|
+
height: auto;
|
|
825
827
|
margin-right: 20px;
|
|
826
828
|
|
|
827
829
|
@media only screen and (max-width: (@largestMobileScreen)) {
|
|
@@ -645,6 +645,11 @@ body.has-toolbar-collapsed .mobile-menu {
|
|
|
645
645
|
transition: transform 0.5s cubic-bezier(0.09, 0.11, 0.24, 0.91);
|
|
646
646
|
}
|
|
647
647
|
|
|
648
|
+
img.responsive {
|
|
649
|
+
max-width: 100%;
|
|
650
|
+
height: auto;
|
|
651
|
+
}
|
|
652
|
+
|
|
648
653
|
// Deprecated as per https://github.com/plone/volto/issues/1265
|
|
649
654
|
// @import 'utils';
|
|
650
655
|
@import (multiple) '../extras/fonts';
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"id": "Insert row before",
|
|
4
|
-
"defaultMessage": "Insert row before"
|
|
5
|
-
},
|
|
6
|
-
{
|
|
7
|
-
"id": "Insert row after",
|
|
8
|
-
"defaultMessage": "Insert row after"
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
"id": "Delete row",
|
|
12
|
-
"defaultMessage": "Delete row"
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"id": "Insert col before",
|
|
16
|
-
"defaultMessage": "Insert col before"
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"id": "Insert col after",
|
|
20
|
-
"defaultMessage": "Insert col after"
|
|
21
|
-
},
|
|
22
|
-
{
|
|
23
|
-
"id": "Delete col",
|
|
24
|
-
"defaultMessage": "Delete col"
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"id": "Hide headers",
|
|
28
|
-
"defaultMessage": "Hide headers"
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
"id": "Make the table sortable",
|
|
32
|
-
"defaultMessage": "Make the table sortable"
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"id": "Visible only in view mode",
|
|
36
|
-
"defaultMessage": "Visible only in view mode"
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"id": "Fixed width table cells",
|
|
40
|
-
"defaultMessage": "Fixed width table cells"
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
"id": "Make the table compact",
|
|
44
|
-
"defaultMessage": "Make the table compact"
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"id": "Reduce complexity",
|
|
48
|
-
"defaultMessage": "Reduce complexity"
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
"id": "Divide each row into separate cells",
|
|
52
|
-
"defaultMessage": "Divide each row into separate cells"
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
"id": "Table color inverted",
|
|
56
|
-
"defaultMessage": "Table color inverted"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"id": "Stripe alternate rows with color",
|
|
60
|
-
"defaultMessage": "Stripe alternate rows with color"
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
"id": "Left",
|
|
64
|
-
"defaultMessage": "Left"
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"id": "Center",
|
|
68
|
-
"defaultMessage": "Center"
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
"id": "Right",
|
|
72
|
-
"defaultMessage": "Right"
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
"id": "Bottom",
|
|
76
|
-
"defaultMessage": "Bottom"
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
"id": "Middle",
|
|
80
|
-
"defaultMessage": "Middle"
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
"id": "Top",
|
|
84
|
-
"defaultMessage": "Top"
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
"id": "Table",
|
|
88
|
-
"defaultMessage": "Table"
|
|
89
|
-
}
|
|
90
|
-
]
|