@plone/volto 17.0.0-alpha.16 → 17.0.0-alpha.17
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/.yarn/install-state.gz +0 -0
- package/CHANGELOG.md +22 -0
- package/news/4351.bugfix +1 -0
- package/news/4725.bugfix +1 -0
- package/news/4932.bugfix +1 -0
- package/news/4941.documentation +1 -0
- package/news/4951.breaking +1 -0
- package/news/4962.feature +1 -0
- package/news/4964.bugfix +1 -0
- package/package.json +1 -1
- package/packages/volto-slate/package.json +1 -1
- package/src/components/manage/Blocks/Grid/View.jsx +1 -0
- package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +3 -4
- package/src/components/manage/Blocks/Teaser/Body.jsx +0 -1
- package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +20 -15
- package/src/components/manage/UniversalLink/UniversalLink.jsx +2 -6
- package/src/components/manage/UniversalLink/UniversalLink.test.jsx +36 -0
- package/src/components/theme/Anontools/Anontools.jsx +3 -4
- package/src/components/theme/Header/Header.jsx +2 -2
- package/src/components/theme/View/AlbumView.jsx +9 -1
- package/src/components/theme/View/EventView.jsx +6 -2
- package/src/components/theme/View/FileView.jsx +23 -18
- package/src/components/theme/View/ImageView.jsx +37 -32
- package/src/components/theme/View/LinkView.jsx +4 -1
- package/src/components/theme/View/ListingView.jsx +33 -27
- package/src/components/theme/View/SummaryView.jsx +47 -38
- package/src/components/theme/View/TabularView.jsx +59 -53
- package/src/hooks/index.js +0 -1
- package/src/hooks/content/useContent.js +0 -31
- package/src/hooks/userSession/useToken.js +0 -5
package/.yarn/install-state.gz
CHANGED
|
Binary file
|
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,28 @@
|
|
|
8
8
|
|
|
9
9
|
<!-- towncrier release notes start -->
|
|
10
10
|
|
|
11
|
+
## 17.0.0-alpha.17 (2023-07-11)
|
|
12
|
+
|
|
13
|
+
### Breaking
|
|
14
|
+
|
|
15
|
+
- Remove useToken & useContent hooks-@Tishasoumya-02 [#4951](https://github.com/plone/volto/issues/4951)
|
|
16
|
+
|
|
17
|
+
### Feature
|
|
18
|
+
|
|
19
|
+
- Use container from component registry in content type views, if defined. @sneridagh [#4962](https://github.com/plone/volto/issues/4962)
|
|
20
|
+
|
|
21
|
+
### Bugfix
|
|
22
|
+
|
|
23
|
+
- Fix temporary rendering of folder contents while query results are loading. @davisagli [#4351](https://github.com/plone/volto/issues/4351)
|
|
24
|
+
- Fix isBlacklisted method check for volto externalRoutes [#4725](https://github.com/plone/volto/issues/4725)
|
|
25
|
+
- Add a marker in the props passed to `RenderBlocks` in the Grid block view @sneridagh [#4932](https://github.com/plone/volto/issues/4932)
|
|
26
|
+
- Fix handling of overriden image in Teaser, improve in case that a custom image component is present. @sneridagh [#4964](https://github.com/plone/volto/issues/4964)
|
|
27
|
+
|
|
28
|
+
### Documentation
|
|
29
|
+
|
|
30
|
+
- Replace broken link for @albertcasado to use GitHub instead of Twitter. @stevepiercy [#4941](https://github.com/plone/volto/issues/4941)
|
|
31
|
+
|
|
32
|
+
|
|
11
33
|
## 17.0.0-alpha.16 (2023-06-28)
|
|
12
34
|
|
|
13
35
|
### Feature
|
package/news/4351.bugfix
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Fix temporary rendering of folder contents while query results are loading. @davisagli
|
package/news/4725.bugfix
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Fix isBlacklisted method check for volto externalRoutes
|
package/news/4932.bugfix
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Add a marker in the props passed to `RenderBlocks` in the Grid block view @sneridagh
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Replace broken link for @albertcasado to use GitHub instead of Twitter. @stevepiercy
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Remove useToken & useContent hooks-@Tishasoumya-02
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Use container from component registry in content type views, if defined. @sneridagh
|
package/news/4964.bugfix
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Fix handling of overriden image in Teaser, improve in case that a custom image component is present. @sneridagh
|
package/package.json
CHANGED
|
@@ -54,10 +54,9 @@ export default function withQuerystringResults(WrappedComponent) {
|
|
|
54
54
|
const hasQuery = querystring?.query?.length > 0;
|
|
55
55
|
const hasLoaded = hasQuery ? querystringResults?.[id]?.loaded : true;
|
|
56
56
|
|
|
57
|
-
const listingItems =
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
: folderItems;
|
|
57
|
+
const listingItems = hasQuery
|
|
58
|
+
? querystringResults?.[id]?.items || []
|
|
59
|
+
: folderItems;
|
|
61
60
|
|
|
62
61
|
const showAsFolderListing = !hasQuery && content?.items_total > b_size;
|
|
63
62
|
const showAsQueryListing =
|
|
@@ -18,20 +18,31 @@ const messages = defineMessages({
|
|
|
18
18
|
},
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
const DefaultImage = (props) => <img {...props} alt={props.alt || ''} />;
|
|
22
|
-
|
|
23
21
|
const TeaserDefaultTemplate = (props) => {
|
|
24
22
|
const { className, data, isEditMode } = props;
|
|
25
23
|
const intl = useIntl();
|
|
26
24
|
const href = data.href?.[0];
|
|
27
|
-
const
|
|
25
|
+
const imageOverride = data.preview_image?.[0];
|
|
28
26
|
const align = data?.styles?.align;
|
|
29
27
|
|
|
30
|
-
const hasImageComponent = config.getComponent('Image').component;
|
|
31
|
-
const Image = config.getComponent('Image').component || DefaultImage;
|
|
32
28
|
const { openExternalLinkInNewTab } = config.settings;
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
|
|
30
|
+
let renderedImage = null;
|
|
31
|
+
if (href && (imageOverride || href.hasPreviewImage || href.image_field)) {
|
|
32
|
+
let Image = config.getComponent('Image').component;
|
|
33
|
+
if (Image) {
|
|
34
|
+
// custom image component expects item summary as src
|
|
35
|
+
renderedImage = (
|
|
36
|
+
<Image src={imageOverride || href} alt="" loading="lazy" />
|
|
37
|
+
);
|
|
38
|
+
} else {
|
|
39
|
+
// default img expects string src
|
|
40
|
+
const src = flattenToAppURL(
|
|
41
|
+
getTeaserImageURL({ href, imageOverride, align }),
|
|
42
|
+
);
|
|
43
|
+
renderedImage = <img src={src} alt="" loading="lazy" />;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
35
46
|
|
|
36
47
|
return (
|
|
37
48
|
<div className={cx('block teaser', className)}>
|
|
@@ -57,14 +68,8 @@ const TeaserDefaultTemplate = (props) => {
|
|
|
57
68
|
}
|
|
58
69
|
>
|
|
59
70
|
<div className="teaser-item default">
|
|
60
|
-
{
|
|
61
|
-
<div className="image-wrapper">
|
|
62
|
-
<Image
|
|
63
|
-
src={hasImageComponent ? href : defaultImageSrc}
|
|
64
|
-
alt=""
|
|
65
|
-
loading="lazy"
|
|
66
|
-
/>
|
|
67
|
-
</div>
|
|
71
|
+
{renderedImage && (
|
|
72
|
+
<div className="image-wrapper">{renderedImage}</div>
|
|
68
73
|
)}
|
|
69
74
|
<div className="content">
|
|
70
75
|
{data?.head_title && (
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
isInternalURL,
|
|
13
13
|
URLUtils,
|
|
14
14
|
} from '@plone/volto/helpers/Url/Url';
|
|
15
|
-
import { matchPath } from 'react-router';
|
|
16
15
|
|
|
17
16
|
import config from '@plone/volto/registry';
|
|
18
17
|
|
|
@@ -66,11 +65,8 @@ const UniversalLink = ({
|
|
|
66
65
|
}
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
matchPath(flattenToAppURL(url), route.match),
|
|
72
|
-
)?.length > 0;
|
|
73
|
-
const isExternal = !isInternalURL(url) || isBlacklisted;
|
|
68
|
+
const isExternal = !isInternalURL(url);
|
|
69
|
+
|
|
74
70
|
const isDownload = (!isExternal && url.includes('@@download')) || download;
|
|
75
71
|
const isDisplayFile =
|
|
76
72
|
(!isExternal && url.includes('@@display-file')) || false;
|
|
@@ -157,6 +157,42 @@ describe('UniversalLink', () => {
|
|
|
157
157
|
);
|
|
158
158
|
});
|
|
159
159
|
|
|
160
|
+
it('UniversalLink renders external link where link is blacklisted', () => {
|
|
161
|
+
const notInEN = /^(?!.*(#|\/en|\/static|\/controlpanel|\/cypress|\/login|\/logout|\/contact-form)).*$/;
|
|
162
|
+
config.settings.externalRoutes = [
|
|
163
|
+
{
|
|
164
|
+
match: {
|
|
165
|
+
path: notInEN,
|
|
166
|
+
exact: false,
|
|
167
|
+
strict: false,
|
|
168
|
+
},
|
|
169
|
+
url(payload) {
|
|
170
|
+
return payload.location.pathname;
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
const { getByTitle } = render(
|
|
176
|
+
<Provider store={store}>
|
|
177
|
+
<MemoryRouter>
|
|
178
|
+
<UniversalLink
|
|
179
|
+
href="http://localhost:3000/blacklisted-app"
|
|
180
|
+
title="External blacklisted app"
|
|
181
|
+
>
|
|
182
|
+
<h1>Title</h1>
|
|
183
|
+
</UniversalLink>
|
|
184
|
+
</MemoryRouter>
|
|
185
|
+
</Provider>,
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
expect(getByTitle('External blacklisted app').getAttribute('target')).toBe(
|
|
189
|
+
'_blank',
|
|
190
|
+
);
|
|
191
|
+
expect(getByTitle('External blacklisted app').getAttribute('rel')).toBe(
|
|
192
|
+
'noopener noreferrer',
|
|
193
|
+
);
|
|
194
|
+
});
|
|
195
|
+
|
|
160
196
|
it('check UniversalLink does not break with error in item', () => {
|
|
161
197
|
const component = renderer.create(
|
|
162
198
|
<Provider store={store}>
|
|
@@ -3,13 +3,12 @@ import { Link } from 'react-router-dom';
|
|
|
3
3
|
import { Menu } from 'semantic-ui-react';
|
|
4
4
|
import { FormattedMessage } from 'react-intl';
|
|
5
5
|
import { flattenToAppURL } from '@plone/volto/helpers';
|
|
6
|
-
import { useToken } from '@plone/volto/hooks/userSession/useToken';
|
|
7
|
-
import { useContent } from '@plone/volto/hooks/content/useContent';
|
|
8
6
|
import config from '@plone/volto/registry';
|
|
7
|
+
import { useSelector, shallowEqual } from 'react-redux';
|
|
9
8
|
|
|
10
9
|
const Anontools = () => {
|
|
11
|
-
const token =
|
|
12
|
-
const
|
|
10
|
+
const token = useSelector((state) => state.userSession.token, shallowEqual);
|
|
11
|
+
const content = useSelector((state) => state.content.data, shallowEqual);
|
|
13
12
|
|
|
14
13
|
const { settings } = config;
|
|
15
14
|
return (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Container, Segment } from 'semantic-ui-react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import {
|
|
3
|
+
import { useSelector, shallowEqual } from 'react-redux';
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
Anontools,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from '@plone/volto/components';
|
|
12
12
|
|
|
13
13
|
const Header = ({ pathname }) => {
|
|
14
|
-
const token =
|
|
14
|
+
const token = useSelector((state) => state.userSession.token, shallowEqual);
|
|
15
15
|
|
|
16
16
|
return (
|
|
17
17
|
<Segment basic className="header-wrapper" role="banner">
|
|
@@ -5,9 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
import React, { Component } from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
Container as SemanticContainer,
|
|
10
|
+
GridColumn,
|
|
11
|
+
Segment,
|
|
12
|
+
} from 'semantic-ui-react';
|
|
9
13
|
import { Button, Modal, Grid } from 'semantic-ui-react';
|
|
10
14
|
import { Icon, UniversalLink, PreviewImage } from '@plone/volto/components';
|
|
15
|
+
import config from '@plone/volto/registry';
|
|
11
16
|
|
|
12
17
|
import openSVG from '@plone/volto/icons/open.svg';
|
|
13
18
|
import aheadSVG from '@plone/volto/icons/ahead.svg';
|
|
@@ -56,6 +61,9 @@ class AlbumView extends Component {
|
|
|
56
61
|
|
|
57
62
|
render() {
|
|
58
63
|
const { content } = this.props;
|
|
64
|
+
const Container =
|
|
65
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
66
|
+
|
|
59
67
|
return (
|
|
60
68
|
<Container className="view-wrapper">
|
|
61
69
|
<article id="content">
|
|
@@ -9,6 +9,8 @@ import { hasBlocksData, flattenHTMLToAppURL } from '@plone/volto/helpers';
|
|
|
9
9
|
import { Image, Grid } from 'semantic-ui-react';
|
|
10
10
|
import RenderBlocks from '@plone/volto/components/theme/View/RenderBlocks';
|
|
11
11
|
import { EventDetails } from '@plone/volto/components';
|
|
12
|
+
import { Container as SemanticContainer } from 'semantic-ui-react';
|
|
13
|
+
import config from '@plone/volto/registry';
|
|
12
14
|
|
|
13
15
|
const EventTextfieldView = ({ content }) => (
|
|
14
16
|
<React.Fragment>
|
|
@@ -41,9 +43,11 @@ const EventTextfieldView = ({ content }) => (
|
|
|
41
43
|
*/
|
|
42
44
|
const EventView = (props) => {
|
|
43
45
|
const { content } = props;
|
|
46
|
+
const Container =
|
|
47
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
44
48
|
|
|
45
49
|
return (
|
|
46
|
-
<
|
|
50
|
+
<Container id="page-document" className="view-wrapper event-view">
|
|
47
51
|
<Grid>
|
|
48
52
|
<Grid.Column width={7} className="mobile hidden">
|
|
49
53
|
{hasBlocksData(content) ? (
|
|
@@ -83,7 +87,7 @@ const EventView = (props) => {
|
|
|
83
87
|
)}
|
|
84
88
|
</Grid.Column>
|
|
85
89
|
</Grid>
|
|
86
|
-
</
|
|
90
|
+
</Container>
|
|
87
91
|
);
|
|
88
92
|
};
|
|
89
93
|
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
-
import { Container } from 'semantic-ui-react';
|
|
9
|
-
|
|
8
|
+
import { Container as SemanticContainer } from 'semantic-ui-react';
|
|
10
9
|
import { flattenToAppURL } from '@plone/volto/helpers';
|
|
10
|
+
import config from '@plone/volto/registry';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* File view component class.
|
|
@@ -15,22 +15,27 @@ import { flattenToAppURL } from '@plone/volto/helpers';
|
|
|
15
15
|
* @params {object} content Content object.
|
|
16
16
|
* @returns {string} Markup of the component.
|
|
17
17
|
*/
|
|
18
|
-
const FileView = ({ content }) =>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
{content.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
18
|
+
const FileView = ({ content }) => {
|
|
19
|
+
const Container =
|
|
20
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Container className="view-wrapper">
|
|
24
|
+
<h1 className="documentFirstHeading">
|
|
25
|
+
{content.title}
|
|
26
|
+
{content.subtitle && ` - ${content.subtitle}`}
|
|
27
|
+
</h1>
|
|
28
|
+
{content.description && (
|
|
29
|
+
<p className="documentDescription">{content.description}</p>
|
|
30
|
+
)}
|
|
31
|
+
{content.file?.download && (
|
|
32
|
+
<a href={flattenToAppURL(content.file.download)}>
|
|
33
|
+
{content.file.filename}
|
|
34
|
+
</a>
|
|
35
|
+
)}
|
|
36
|
+
</Container>
|
|
37
|
+
);
|
|
38
|
+
};
|
|
34
39
|
|
|
35
40
|
/**
|
|
36
41
|
* Property types.
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
-
import { Container } from 'semantic-ui-react';
|
|
8
|
+
import { Container as SemanticContainer } from 'semantic-ui-react';
|
|
9
9
|
import { FormattedMessage } from 'react-intl';
|
|
10
10
|
import prettybytes from 'pretty-bytes';
|
|
11
|
-
|
|
12
11
|
import { flattenToAppURL } from '@plone/volto/helpers';
|
|
12
|
+
import config from '@plone/volto/registry';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Image view component class.
|
|
@@ -17,37 +17,42 @@ import { flattenToAppURL } from '@plone/volto/helpers';
|
|
|
17
17
|
* @params {object} content Content object.
|
|
18
18
|
* @returns {string} Markup of the component.
|
|
19
19
|
*/
|
|
20
|
-
const ImageView = ({ content }) =>
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
defaultMessage="Size: {size}"
|
|
39
|
-
values={{ size: prettybytes(content.image.size) }}
|
|
40
|
-
/>
|
|
41
|
-
—
|
|
42
|
-
<FormattedMessage
|
|
43
|
-
id="Click to download full sized image"
|
|
44
|
-
defaultMessage="Click to download full sized image"
|
|
20
|
+
const ImageView = ({ content }) => {
|
|
21
|
+
const Container =
|
|
22
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Container className="view-wrapper">
|
|
26
|
+
<h1 className="documentFirstHeading">
|
|
27
|
+
{content.title}
|
|
28
|
+
{content.subtitle && ` - ${content.subtitle}`}
|
|
29
|
+
</h1>
|
|
30
|
+
{content.description && (
|
|
31
|
+
<p className="documentDescription">{content.description}</p>
|
|
32
|
+
)}
|
|
33
|
+
{content?.image?.download && (
|
|
34
|
+
<a href={flattenToAppURL(content.image.download)}>
|
|
35
|
+
<img
|
|
36
|
+
alt={content.title}
|
|
37
|
+
src={flattenToAppURL(content.image.scales.preview.download)}
|
|
45
38
|
/>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
)
|
|
39
|
+
<figcaption>
|
|
40
|
+
<FormattedMessage
|
|
41
|
+
id="Size: {size}"
|
|
42
|
+
defaultMessage="Size: {size}"
|
|
43
|
+
values={{ size: prettybytes(content.image.size) }}
|
|
44
|
+
/>
|
|
45
|
+
—
|
|
46
|
+
<FormattedMessage
|
|
47
|
+
id="Click to download full sized image"
|
|
48
|
+
defaultMessage="Click to download full sized image"
|
|
49
|
+
/>
|
|
50
|
+
</figcaption>
|
|
51
|
+
</a>
|
|
52
|
+
)}
|
|
53
|
+
</Container>
|
|
54
|
+
);
|
|
55
|
+
};
|
|
51
56
|
|
|
52
57
|
/**
|
|
53
58
|
* Property types.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import React, { Component } from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import { isInternalURL, flattenToAppURL } from '@plone/volto/helpers';
|
|
9
|
-
import { Container } from 'semantic-ui-react';
|
|
9
|
+
import { Container as SemanticContainer } from 'semantic-ui-react';
|
|
10
10
|
import { UniversalLink } from '@plone/volto/components';
|
|
11
11
|
import { FormattedMessage } from 'react-intl';
|
|
12
12
|
import config from '@plone/volto/registry';
|
|
@@ -60,6 +60,9 @@ class LinkView extends Component {
|
|
|
60
60
|
render() {
|
|
61
61
|
const { remoteUrl } = this.props.content;
|
|
62
62
|
const { openExternalLinkInNewTab } = config.settings;
|
|
63
|
+
const Container =
|
|
64
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
65
|
+
|
|
63
66
|
return (
|
|
64
67
|
<Container id="page-document">
|
|
65
68
|
<h1 className="documentFirstHeading">{this.props.content.title}</h1>
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
|
-
import { Segment, Container } from 'semantic-ui-react';
|
|
8
|
+
import { Segment, Container as SemanticContainer } from 'semantic-ui-react';
|
|
9
9
|
import { UniversalLink, PreviewImage } from '@plone/volto/components';
|
|
10
|
+
import config from '@plone/volto/registry';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* List view component class.
|
|
@@ -14,32 +15,37 @@ import { UniversalLink, PreviewImage } from '@plone/volto/components';
|
|
|
14
15
|
* @params {object} content Content object.
|
|
15
16
|
* @returns {string} Markup of the component.
|
|
16
17
|
*/
|
|
17
|
-
const ListingView = ({ content }) =>
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
item
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
18
|
+
const ListingView = ({ content }) => {
|
|
19
|
+
const Container =
|
|
20
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Container id="page-home">
|
|
24
|
+
<section id="content-core">
|
|
25
|
+
{content.items.map((item) => (
|
|
26
|
+
<Segment key={item.url} className="listing-item">
|
|
27
|
+
<Container>
|
|
28
|
+
<h2>
|
|
29
|
+
<UniversalLink item={item} title={item['@type']}>
|
|
30
|
+
{item.title}
|
|
31
|
+
</UniversalLink>
|
|
32
|
+
</h2>
|
|
33
|
+
{item.description && <p>{item.description}</p>}
|
|
34
|
+
</Container>
|
|
35
|
+
{item.image_field && (
|
|
36
|
+
<PreviewImage
|
|
37
|
+
item={item}
|
|
38
|
+
size="thumb"
|
|
39
|
+
alt={item.image_caption ? item.image_caption : item.title}
|
|
40
|
+
className="ui image"
|
|
41
|
+
/>
|
|
42
|
+
)}
|
|
43
|
+
</Segment>
|
|
44
|
+
))}
|
|
45
|
+
</section>
|
|
46
|
+
</Container>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
43
49
|
|
|
44
50
|
/**
|
|
45
51
|
* Property types.
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import { UniversalLink } from '@plone/volto/components';
|
|
9
|
-
import { Container } from 'semantic-ui-react';
|
|
9
|
+
import { Container as SemanticContainer } from 'semantic-ui-react';
|
|
10
10
|
import { FormattedMessage } from 'react-intl';
|
|
11
11
|
import PreviewImage from '../PreviewImage/PreviewImage';
|
|
12
|
+
import config from '@plone/volto/registry';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Summary view component class.
|
|
@@ -16,43 +17,51 @@ import PreviewImage from '../PreviewImage/PreviewImage';
|
|
|
16
17
|
* @param {Object} content Content object.
|
|
17
18
|
* @returns {string} Markup of the component.
|
|
18
19
|
*/
|
|
19
|
-
const SummaryView = ({ content }) =>
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
</
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
20
|
+
const SummaryView = ({ content }) => {
|
|
21
|
+
const Container =
|
|
22
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Container className="view-wrapper summary-view">
|
|
26
|
+
<article id="content">
|
|
27
|
+
<header>
|
|
28
|
+
<h1 className="documentFirstHeading">{content.title}</h1>
|
|
29
|
+
{content.description && (
|
|
30
|
+
<p className="documentDescription">{content.description}</p>
|
|
31
|
+
)}
|
|
32
|
+
</header>
|
|
33
|
+
<section id="content-core">
|
|
34
|
+
{content.items.map((item) => (
|
|
35
|
+
<article key={item.url}>
|
|
36
|
+
<h2>
|
|
37
|
+
<UniversalLink item={item} title={item['@type']}>
|
|
38
|
+
{item.title}
|
|
39
|
+
</UniversalLink>
|
|
40
|
+
</h2>
|
|
41
|
+
{item.image_field && (
|
|
42
|
+
<PreviewImage
|
|
43
|
+
item={item}
|
|
44
|
+
alt={item.image_caption ? item.image_caption : item.title}
|
|
45
|
+
size="thumb"
|
|
46
|
+
className="ui image floated right clear"
|
|
47
|
+
/>
|
|
48
|
+
)}
|
|
49
|
+
{item.description && <p>{item.description}</p>}
|
|
50
|
+
<p>
|
|
51
|
+
<UniversalLink item={item}>
|
|
52
|
+
<FormattedMessage
|
|
53
|
+
id="Read More…"
|
|
54
|
+
defaultMessage="Read More…"
|
|
55
|
+
/>
|
|
56
|
+
</UniversalLink>
|
|
57
|
+
</p>
|
|
58
|
+
</article>
|
|
59
|
+
))}
|
|
60
|
+
</section>
|
|
61
|
+
</article>
|
|
62
|
+
</Container>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
56
65
|
|
|
57
66
|
/**
|
|
58
67
|
* Property types.
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import { UniversalLink } from '@plone/volto/components';
|
|
9
|
-
import { Container, Table } from 'semantic-ui-react';
|
|
9
|
+
import { Container as SemanticContainer, Table } from 'semantic-ui-react';
|
|
10
10
|
import { FormattedMessage } from 'react-intl';
|
|
11
|
+
import config from '@plone/volto/registry';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Tabular view component class.
|
|
@@ -15,59 +16,64 @@ import { FormattedMessage } from 'react-intl';
|
|
|
15
16
|
* @param {Object} content Content object.
|
|
16
17
|
* @returns {string} Markup of the component.
|
|
17
18
|
*/
|
|
18
|
-
const TabularView = ({ content }) =>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<Table.
|
|
35
|
-
<
|
|
36
|
-
id="
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
<Table.Row key={item.url}>
|
|
51
|
-
<Table.Cell>
|
|
52
|
-
<UniversalLink
|
|
53
|
-
item={item}
|
|
54
|
-
className="summary url"
|
|
55
|
-
title={item['@type']}
|
|
56
|
-
>
|
|
57
|
-
{item.title}
|
|
58
|
-
</UniversalLink>
|
|
59
|
-
</Table.Cell>
|
|
60
|
-
<Table.Cell>{item.description}</Table.Cell>
|
|
61
|
-
<Table.Cell>{item['@type']}</Table.Cell>
|
|
62
|
-
<Table.Cell>{item.review_state}</Table.Cell>
|
|
19
|
+
const TabularView = ({ content }) => {
|
|
20
|
+
const Container =
|
|
21
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<Container className="view-wrapper">
|
|
25
|
+
<article id="content">
|
|
26
|
+
<header>
|
|
27
|
+
<h1 className="documentFirstHeading">{content.title}</h1>
|
|
28
|
+
{content.description && (
|
|
29
|
+
<p className="documentDescription">{content.description}</p>
|
|
30
|
+
)}
|
|
31
|
+
</header>
|
|
32
|
+
<section id="content-core">
|
|
33
|
+
<Table celled padded>
|
|
34
|
+
<Table.Header>
|
|
35
|
+
<Table.Row>
|
|
36
|
+
<Table.HeaderCell>
|
|
37
|
+
<FormattedMessage id="Title" defaultMessage="Title" />
|
|
38
|
+
</Table.HeaderCell>
|
|
39
|
+
<Table.HeaderCell>
|
|
40
|
+
<FormattedMessage
|
|
41
|
+
id="Description"
|
|
42
|
+
defaultMessage="Description"
|
|
43
|
+
/>
|
|
44
|
+
</Table.HeaderCell>
|
|
45
|
+
<Table.HeaderCell>
|
|
46
|
+
<FormattedMessage id="Type" defaultMessage="Type" />
|
|
47
|
+
</Table.HeaderCell>
|
|
48
|
+
<Table.HeaderCell>
|
|
49
|
+
<FormattedMessage id="State" defaultMessage="State" />
|
|
50
|
+
</Table.HeaderCell>
|
|
63
51
|
</Table.Row>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
52
|
+
</Table.Header>
|
|
53
|
+
<Table.Body>
|
|
54
|
+
{content.items.map((item) => (
|
|
55
|
+
<Table.Row key={item.url}>
|
|
56
|
+
<Table.Cell>
|
|
57
|
+
<UniversalLink
|
|
58
|
+
item={item}
|
|
59
|
+
className="summary url"
|
|
60
|
+
title={item['@type']}
|
|
61
|
+
>
|
|
62
|
+
{item.title}
|
|
63
|
+
</UniversalLink>
|
|
64
|
+
</Table.Cell>
|
|
65
|
+
<Table.Cell>{item.description}</Table.Cell>
|
|
66
|
+
<Table.Cell>{item['@type']}</Table.Cell>
|
|
67
|
+
<Table.Cell>{item.review_state}</Table.Cell>
|
|
68
|
+
</Table.Row>
|
|
69
|
+
))}
|
|
70
|
+
</Table.Body>
|
|
71
|
+
</Table>
|
|
72
|
+
</section>
|
|
73
|
+
</article>
|
|
74
|
+
</Container>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
71
77
|
|
|
72
78
|
/**
|
|
73
79
|
* Property types.
|
package/src/hooks/index.js
CHANGED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { useSelector, shallowEqual } from 'react-redux';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* useContent hook
|
|
5
|
-
*
|
|
6
|
-
* This hook returns the current content that is stored in the Redux store in the
|
|
7
|
-
* `content` reducer, and returns it along with the related state (loading/loaded/error).
|
|
8
|
-
*
|
|
9
|
-
* @export
|
|
10
|
-
* @return {{ data: ContentData, loading: boolean, loaded: boolean, error: Error }}
|
|
11
|
-
*/
|
|
12
|
-
export function useContent() {
|
|
13
|
-
const data = useSelector((state) => state.content.data, shallowEqual);
|
|
14
|
-
const loading = useSelector((state) => state.content.get.loading);
|
|
15
|
-
const loaded = useSelector((state) => state.content.get.loaded);
|
|
16
|
-
const error = useSelector((state) => state.content.get.error, shallowEqual);
|
|
17
|
-
|
|
18
|
-
return { data, loading, loaded, error };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// For reference purposes: Potential future useQuery version
|
|
22
|
-
// export function useContent() {
|
|
23
|
-
// // the cache will need to know the current location
|
|
24
|
-
// const pathname = useLocation();
|
|
25
|
-
// const query = useQuery(getContentQuery({ path }))
|
|
26
|
-
|
|
27
|
-
// // This might not be needed if we rename the properties
|
|
28
|
-
// const {isLoading: loading, isSuccess: loaded, ...rest} = query;
|
|
29
|
-
|
|
30
|
-
// return { loading, loaded, ...rest };
|
|
31
|
-
// }
|