@plone/volto 18.4.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/CHANGELOG.md +19 -0
- package/README.md +8 -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 +5 -5
- 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/Robots/Robots.js +3 -1
- package/test-setup-config.jsx +1 -0
- package/theme/themes/pastanaga/extras/main.less +5 -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/slots.d.ts +10 -2
- package/types/constants/Languages.d.cts +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
|
|
|
@@ -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';
|
|
@@ -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/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
|
}
|