@plone/volto 18.3.0 → 18.5.0
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/.release-it.json +1 -1
- package/CHANGELOG.md +33 -0
- package/README.md +32 -8
- package/locales/ca/LC_MESSAGES/volto.po +5 -0
- package/locales/ca.json +1 -1
- package/locales/de/LC_MESSAGES/volto.po +5 -0
- package/locales/de.json +1 -1
- package/locales/en/LC_MESSAGES/volto.po +5 -0
- package/locales/en.json +1 -1
- package/locales/es/LC_MESSAGES/volto.po +5 -0
- package/locales/es.json +1 -1
- package/locales/eu/LC_MESSAGES/volto.po +5 -0
- package/locales/eu.json +1 -1
- package/locales/fi/LC_MESSAGES/volto.po +5 -0
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +5 -0
- package/locales/fr.json +1 -1
- package/locales/hi/LC_MESSAGES/volto.po +5 -0
- package/locales/hi.json +1 -1
- package/locales/it/LC_MESSAGES/volto.po +5 -0
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +5 -0
- package/locales/ja.json +1 -1
- package/locales/nl/LC_MESSAGES/volto.po +5 -0
- package/locales/nl.json +1 -1
- package/locales/pt/LC_MESSAGES/volto.po +5 -0
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +5 -0
- package/locales/pt_BR.json +1 -1
- package/locales/ro/LC_MESSAGES/volto.po +5 -0
- package/locales/ro.json +1 -1
- package/locales/sv/LC_MESSAGES/volto.po +5193 -0
- package/locales/sv.json +1 -0
- package/locales/volto.pot +5 -0
- package/locales/zh_CN/LC_MESSAGES/volto.po +5 -0
- package/locales/zh_CN.json +1 -1
- package/package.json +4 -4
- package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +3 -0
- package/src/components/manage/Contents/Contents.jsx +6 -0
- package/src/components/theme/App/App.jsx +5 -2
- package/src/components/theme/RelatedItems/RelatedItems.jsx +70 -0
- package/src/components/theme/RelatedItems/RelatedItems.test.jsx +83 -0
- package/src/config/index.js +1 -0
- package/src/config/slots.js +5 -0
- package/src/constants/Languages.cjs +1 -0
- package/src/helpers/Html/Html.jsx +6 -0
- package/src/helpers/Robots/Robots.js +3 -1
- package/test-setup-config.jsx +1 -0
- package/theme/themes/pastanaga/extras/main.less +5 -0
- package/tsconfig.declarations.json +3 -1
- package/types/components/manage/Contents/ContentsDeleteModal.d.ts +10 -0
- package/types/components/theme/Navigation/ContextNavigation.d.ts +1 -1
- package/types/components/theme/RelatedItems/RelatedItems.d.ts +13 -0
- package/types/components/theme/RelatedItems/RelatedItems.test.d.ts +1 -0
- package/types/components/theme/View/RenderBlocks.d.ts +1 -1
- package/types/components/theme/Widgets/ArrayWidget.d.ts +1 -1
- package/types/components/theme/Widgets/DateWidget.d.ts +1 -1
- package/types/components/theme/Widgets/DatetimeWidget.d.ts +1 -1
- package/types/components/theme/Widgets/DescriptionWidget.d.ts +1 -1
- package/types/components/theme/Widgets/EmailWidget.d.ts +1 -1
- package/types/components/theme/Widgets/FileWidget.d.ts +1 -1
- package/types/components/theme/Widgets/ImageWidget.d.ts +1 -1
- package/types/components/theme/Widgets/PasswordWidget.d.ts +1 -1
- package/types/components/theme/Widgets/RelationWidget.d.ts +1 -1
- package/types/components/theme/Widgets/RelationsWidget.d.ts +1 -1
- package/types/components/theme/Widgets/RichTextWidget.d.ts +1 -1
- package/types/components/theme/Widgets/SelectWidget.d.ts +1 -1
- package/types/components/theme/Widgets/TextWidget.d.ts +1 -1
- package/types/components/theme/Widgets/TitleWidget.d.ts +1 -1
- package/types/components/theme/Widgets/TokenWidget.d.ts +1 -1
- package/types/components/theme/Widgets/UrlWidget.d.ts +1 -1
- package/types/config/Blocks.d.ts +1 -0
- package/types/config/Views.d.ts +1 -0
- package/types/config/Widgets.d.ts +1 -0
- package/types/config/slots.d.ts +10 -2
- package/types/constants/Languages.d.cts +1 -0
- package/types/reducers/index.d.ts +2 -0
- package/types/reducers/linkIntegrity/linkIntegrity.d.ts +8 -0
- package/types/reducers/linkIntegrity/linkIntegrity.test.d.ts +1 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RelatedItems component.
|
|
3
|
+
* @module components/theme/RelatedItems/RelatedItems
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
|
|
7
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
8
|
+
import PropTypes from 'prop-types';
|
|
9
|
+
import { Container } from 'semantic-ui-react';
|
|
10
|
+
import config from '@plone/volto/registry';
|
|
11
|
+
|
|
12
|
+
const messages = defineMessages({
|
|
13
|
+
relatedItems: {
|
|
14
|
+
id: 'Related Items',
|
|
15
|
+
defaultMessage: 'Related Items',
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Related Items component.
|
|
21
|
+
* @function RelatedItems
|
|
22
|
+
* @param {array} relatedItems Array of related items.
|
|
23
|
+
* @returns {JSX.Element} Markup of the component.
|
|
24
|
+
*/
|
|
25
|
+
const RelatedItems = ({ content }) => {
|
|
26
|
+
const intl = useIntl();
|
|
27
|
+
const relatedItems = content?.relatedItems;
|
|
28
|
+
if (
|
|
29
|
+
!config.settings.showRelatedItems ||
|
|
30
|
+
!relatedItems ||
|
|
31
|
+
relatedItems.length === 0
|
|
32
|
+
) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<Container className="related-items">
|
|
38
|
+
<h2>{intl.formatMessage(messages.relatedItems)}</h2>
|
|
39
|
+
<ul>
|
|
40
|
+
{relatedItems.map((relatedItem) =>
|
|
41
|
+
relatedItem ? (
|
|
42
|
+
<li key={relatedItem['@id']}>
|
|
43
|
+
<UniversalLink href={relatedItem['@id']}>
|
|
44
|
+
{relatedItem.title}
|
|
45
|
+
</UniversalLink>
|
|
46
|
+
</li>
|
|
47
|
+
) : null,
|
|
48
|
+
)}
|
|
49
|
+
</ul>
|
|
50
|
+
</Container>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Property types.
|
|
56
|
+
* @property {Object} propTypes Property types.
|
|
57
|
+
* @static
|
|
58
|
+
*/
|
|
59
|
+
RelatedItems.propTypes = {
|
|
60
|
+
content: PropTypes.shape({
|
|
61
|
+
relatedItems: PropTypes.arrayOf(
|
|
62
|
+
PropTypes.shape({
|
|
63
|
+
'@id': PropTypes.string.isRequired,
|
|
64
|
+
title: PropTypes.string.isRequired,
|
|
65
|
+
}),
|
|
66
|
+
),
|
|
67
|
+
}),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default RelatedItems;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import renderer from 'react-test-renderer';
|
|
2
|
+
import configureStore from 'redux-mock-store';
|
|
3
|
+
import { Provider } from 'react-intl-redux';
|
|
4
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
5
|
+
|
|
6
|
+
import RelatedItems from './RelatedItems';
|
|
7
|
+
|
|
8
|
+
const mockStore = configureStore();
|
|
9
|
+
let store;
|
|
10
|
+
|
|
11
|
+
describe('Related Items', () => {
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
store = mockStore({
|
|
14
|
+
intl: {
|
|
15
|
+
locale: 'en',
|
|
16
|
+
messages: {},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('renders without related items', () => {
|
|
22
|
+
const content = {};
|
|
23
|
+
const component = renderer.create(
|
|
24
|
+
<Provider store={store}>
|
|
25
|
+
<MemoryRouter>
|
|
26
|
+
<RelatedItems content={content} />
|
|
27
|
+
</MemoryRouter>
|
|
28
|
+
</Provider>,
|
|
29
|
+
);
|
|
30
|
+
const json = component.toJSON();
|
|
31
|
+
expect(json).toMatchSnapshot();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('renders with related items', () => {
|
|
35
|
+
const content = {
|
|
36
|
+
relatedItems: [
|
|
37
|
+
{
|
|
38
|
+
'@id': '/test-1',
|
|
39
|
+
title: 'Title 1',
|
|
40
|
+
description: 'Description 1',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
'@id': '/test-2',
|
|
44
|
+
title: 'Title 2',
|
|
45
|
+
description: 'Description 2',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const component = renderer.create(
|
|
51
|
+
<Provider store={store}>
|
|
52
|
+
<MemoryRouter>
|
|
53
|
+
<RelatedItems content={content} />
|
|
54
|
+
</MemoryRouter>
|
|
55
|
+
</Provider>,
|
|
56
|
+
);
|
|
57
|
+
const json = component.toJSON();
|
|
58
|
+
expect(json).toMatchSnapshot();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('renders with related items has null', () => {
|
|
62
|
+
const content = {
|
|
63
|
+
relatedItems: [
|
|
64
|
+
{
|
|
65
|
+
'@id': '/test-1',
|
|
66
|
+
title: 'Title 1',
|
|
67
|
+
description: 'Description 1',
|
|
68
|
+
},
|
|
69
|
+
null,
|
|
70
|
+
],
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const component = renderer.create(
|
|
74
|
+
<Provider store={store}>
|
|
75
|
+
<MemoryRouter>
|
|
76
|
+
<RelatedItems content={content} />
|
|
77
|
+
</MemoryRouter>
|
|
78
|
+
</Provider>,
|
|
79
|
+
);
|
|
80
|
+
const json = component.toJSON();
|
|
81
|
+
expect(json).toMatchSnapshot();
|
|
82
|
+
});
|
|
83
|
+
});
|
package/src/config/index.js
CHANGED
package/src/config/slots.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import RelatedItems from '@plone/volto/components/theme/RelatedItems/RelatedItems';
|
|
1
2
|
import Tags from '@plone/volto/components/theme/Tags/Tags';
|
|
2
3
|
|
|
3
4
|
const slots = {
|
|
@@ -6,6 +7,10 @@ const slots = {
|
|
|
6
7
|
name: 'tags',
|
|
7
8
|
component: Tags,
|
|
8
9
|
},
|
|
10
|
+
{
|
|
11
|
+
name: 'relatedItems',
|
|
12
|
+
component: RelatedItems,
|
|
13
|
+
},
|
|
9
14
|
],
|
|
10
15
|
};
|
|
11
16
|
|
|
@@ -102,6 +102,12 @@ class Html extends Component {
|
|
|
102
102
|
{head.meta.toComponent()}
|
|
103
103
|
{head.link.toComponent()}
|
|
104
104
|
{head.script.toComponent()}
|
|
105
|
+
|
|
106
|
+
{config.settings.cssLayers && (
|
|
107
|
+
// Load the CSS layers from config, if any
|
|
108
|
+
<style>{`@layer ${config.settings.cssLayers.join(', ')};`}</style>
|
|
109
|
+
)}
|
|
110
|
+
|
|
105
111
|
{head.style.toComponent()}
|
|
106
112
|
|
|
107
113
|
<script
|
|
@@ -16,7 +16,9 @@ import { addHeadersFactory } from '@plone/volto/helpers/Proxy/Proxy';
|
|
|
16
16
|
export const generateRobots = (req) =>
|
|
17
17
|
new Promise((resolve) => {
|
|
18
18
|
const internalUrl =
|
|
19
|
-
config.settings.internalApiPath ??
|
|
19
|
+
config.settings.internalApiPath ??
|
|
20
|
+
config.settings.devProxyToApiPath ??
|
|
21
|
+
config.settings.apiPath;
|
|
20
22
|
const request = superagent.get(`${internalUrl}/robots.txt`);
|
|
21
23
|
request.set('Accept', 'text/plain');
|
|
22
24
|
const authToken = req.universalCookies.get('auth_token');
|
package/test-setup-config.jsx
CHANGED
|
@@ -651,6 +651,11 @@ img.responsive {
|
|
|
651
651
|
height: auto;
|
|
652
652
|
}
|
|
653
653
|
|
|
654
|
+
// Related Items
|
|
655
|
+
.related-items {
|
|
656
|
+
margin-top: 20px;
|
|
657
|
+
}
|
|
658
|
+
|
|
654
659
|
// Deprecated as per https://github.com/plone/volto/issues/1265
|
|
655
660
|
// @import 'utils';
|
|
656
661
|
@import (multiple) '../extras/fonts';
|
|
@@ -11,7 +11,9 @@
|
|
|
11
11
|
"preserveSymlinks": true,
|
|
12
12
|
"downlevelIteration": true,
|
|
13
13
|
"paths": {
|
|
14
|
-
"@plone/volto/*": ["./src/*"]
|
|
14
|
+
"@plone/volto/*": ["./src/*"],
|
|
15
|
+
"react": ["./node_modules/@types/react"],
|
|
16
|
+
"react-dom": ["./node_modules/@types/react-dom"]
|
|
15
17
|
}
|
|
16
18
|
},
|
|
17
19
|
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.tsx"]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default ContentsDeleteModal;
|
|
2
|
+
declare function ContentsDeleteModal(props: any): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
declare namespace ContentsDeleteModal {
|
|
4
|
+
namespace propTypes {
|
|
5
|
+
let itemsToDelete: any;
|
|
6
|
+
let open: any;
|
|
7
|
+
let onOk: any;
|
|
8
|
+
let onCancel: any;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* portlet. It uses the same API, so the options are similar to
|
|
4
4
|
* INavigationPortlet
|
|
5
5
|
*/
|
|
6
|
-
export function ContextNavigationComponent(props: any): import("react/jsx-runtime").JSX.Element
|
|
6
|
+
export function ContextNavigationComponent(props: any): "" | import("react/jsx-runtime").JSX.Element;
|
|
7
7
|
export namespace ContextNavigationComponent {
|
|
8
8
|
namespace propTypes {
|
|
9
9
|
let navigation: any;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export default RelatedItems;
|
|
2
|
+
/**
|
|
3
|
+
* Related Items component.
|
|
4
|
+
* @function RelatedItems
|
|
5
|
+
* @param {array} relatedItems Array of related items.
|
|
6
|
+
* @returns {JSX.Element} Markup of the component.
|
|
7
|
+
*/
|
|
8
|
+
declare function RelatedItems({ content }: any[]): JSX.Element;
|
|
9
|
+
declare namespace RelatedItems {
|
|
10
|
+
namespace propTypes {
|
|
11
|
+
let content: any;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export default RenderBlocks;
|
|
2
|
-
declare function RenderBlocks(props: any): import("react/jsx-runtime").JSX.Element
|
|
2
|
+
declare function RenderBlocks(props: any): "" | import("react/jsx-runtime").JSX.Element;
|
package/types/config/Blocks.d.ts
CHANGED
package/types/config/Views.d.ts
CHANGED
package/types/config/slots.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default slots;
|
|
2
2
|
declare namespace slots {
|
|
3
|
-
let belowContent: {
|
|
3
|
+
let belowContent: ({
|
|
4
4
|
name: string;
|
|
5
5
|
component: {
|
|
6
6
|
({ content }: {
|
|
@@ -17,5 +17,13 @@ declare namespace slots {
|
|
|
17
17
|
};
|
|
18
18
|
};
|
|
19
19
|
};
|
|
20
|
-
}
|
|
20
|
+
} | {
|
|
21
|
+
name: string;
|
|
22
|
+
component: {
|
|
23
|
+
({ content }: any[]): JSX.Element;
|
|
24
|
+
propTypes: {
|
|
25
|
+
content: any;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
})[];
|
|
21
29
|
}
|
|
@@ -18,6 +18,7 @@ declare namespace reducers {
|
|
|
18
18
|
export { form };
|
|
19
19
|
export { groups };
|
|
20
20
|
export { history };
|
|
21
|
+
export { linkIntegrity };
|
|
21
22
|
export { messages };
|
|
22
23
|
export { navigation };
|
|
23
24
|
export { querystring };
|
|
@@ -66,6 +67,7 @@ import emailSend from '@plone/volto/reducers/emailSend/emailSend';
|
|
|
66
67
|
import form from '@plone/volto/reducers/form/form';
|
|
67
68
|
import groups from '@plone/volto/reducers/groups/groups';
|
|
68
69
|
import history from '@plone/volto/reducers/history/history';
|
|
70
|
+
import linkIntegrity from '@plone/volto/reducers/linkIntegrity/linkIntegrity';
|
|
69
71
|
import messages from '@plone/volto/reducers/messages/messages';
|
|
70
72
|
import navigation from '@plone/volto/reducers/navigation/navigation';
|
|
71
73
|
import querystring from '@plone/volto/reducers/querystring/querystring';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|