@plone/volto 16.30.1 → 16.30.3

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/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "16.30.1",
12
+ "version": "16.30.3",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git@github.com:plone/volto.git"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plone/volto-slate",
3
- "version": "16.30.1",
3
+ "version": "16.30.3",
4
4
  "description": "Slate.js integration with Volto",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -1,14 +1,29 @@
1
1
  import { getQueryStringResults } from '@plone/volto/actions';
2
2
  import { resolveBlockExtensions } from '@plone/volto/helpers';
3
+ import qs from 'query-string';
4
+ import { slugify } from '@plone/volto/helpers/Utils/Utils';
5
+
6
+ const getCurrentPage = (location, id) => {
7
+ const pageQueryParam = qs.parse(location.search);
8
+ switch (Object.keys(pageQueryParam).length) {
9
+ case 0:
10
+ return 1;
11
+ case 1:
12
+ // when there is only one query param, it could be the simple page number or the sluggified block id
13
+ return pageQueryParam['page'] || pageQueryParam[slugify(`page-${id}`)];
14
+ default:
15
+ return pageQueryParam[slugify(`page-${id}`)];
16
+ }
17
+ };
18
+
19
+ export default function getListingBlockAsyncData(props) {
20
+ const { data, path, location, id, dispatch, blocksConfig, content } = props;
3
21
 
4
- export default function getListingBlockAsyncData({
5
- dispatch,
6
- data,
7
- path,
8
- blocksConfig,
9
- }) {
10
22
  const { resolvedExtensions } = resolveBlockExtensions(data, blocksConfig);
11
23
 
24
+ const subrequestID = content?.UID ? `${content?.UID}-${id}` : id;
25
+ const currentPage = getCurrentPage(location, id);
26
+
12
27
  return [
13
28
  dispatch(
14
29
  getQueryStringResults(
@@ -19,7 +34,8 @@ export default function getListingBlockAsyncData({
19
34
  ? { fullobjects: 1 }
20
35
  : { metadata_fields: '_all' }),
21
36
  },
22
- data.block,
37
+ subrequestID,
38
+ currentPage,
23
39
  ),
24
40
  ),
25
41
  ];
@@ -5,16 +5,21 @@
5
5
  import { useEffect } from 'react';
6
6
  import { Helmet } from '@plone/volto/helpers';
7
7
  import { Link } from 'react-router-dom';
8
+ import { find } from 'lodash';
8
9
  import { Portal } from 'react-portal';
9
10
  import { Container, Segment, Table } from 'semantic-ui-react';
10
11
  import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
11
12
  import { useDispatch, useSelector } from 'react-redux';
12
- import { getContent, queryRelations } from '@plone/volto/actions';
13
+ import { getContent, queryRelations, listActions } from '@plone/volto/actions';
14
+ import { asyncConnect } from '@plone/volto/helpers';
15
+
13
16
  import {
14
17
  Icon as IconNext,
15
18
  Toolbar,
16
19
  UniversalLink,
20
+ Unauthorized,
17
21
  } from '@plone/volto/components';
22
+ import { compose } from 'redux';
18
23
 
19
24
  import { getBaseUrl } from '@plone/volto/helpers';
20
25
  import backSVG from '@plone/volto/icons/back.svg';
@@ -39,6 +44,8 @@ const LinksToItem = (props) => {
39
44
  const dispatch = useDispatch();
40
45
  const pathname = props.location.pathname;
41
46
  const itempath = getBaseUrl(pathname);
47
+ const objectActions = useSelector((state) => state.actions.actions.object);
48
+ const editPermission = find(objectActions, { id: 'edit' });
42
49
 
43
50
  const title = useSelector((state) => state.content.data?.title || '');
44
51
  const myrelations = useSelector(
@@ -71,6 +78,9 @@ const LinksToItem = (props) => {
71
78
  });
72
79
 
73
80
  const relations_found = Object.keys(links_ordered).length > 0;
81
+ if (!editPermission) {
82
+ return <Unauthorized />;
83
+ }
74
84
  return (
75
85
  <Container id="linkstoitem">
76
86
  <Helmet title={intl.formatMessage(messages.linkstoitem)} />
@@ -182,4 +192,15 @@ const LinksToItem = (props) => {
182
192
  );
183
193
  };
184
194
 
185
- export default LinksToItem;
195
+ export const __test__ = LinksToItem;
196
+ export default compose(
197
+ asyncConnect([
198
+ {
199
+ key: 'actions',
200
+ // Dispatch async/await to make the operation synchronous, otherwise it returns
201
+ // before the promise is resolved
202
+ promise: async ({ location, store: { dispatch } }) =>
203
+ await dispatch(listActions(getBaseUrl(location.pathname))),
204
+ },
205
+ ]),
206
+ )(LinksToItem);
@@ -4,7 +4,7 @@ import { Provider } from 'react-intl-redux';
4
4
  import configureMockStore from 'redux-mock-store';
5
5
  import thunk from 'redux-thunk';
6
6
 
7
- import LinksToItem from './LinksToItem';
7
+ import { __test__ as LinksToItem } from './LinksToItem';
8
8
 
9
9
  const middlewares = [thunk];
10
10
  const mockStore = configureMockStore(middlewares);
@@ -17,6 +17,18 @@ jest.mock('../Toolbar/More', () => jest.fn(() => <div className="More" />));
17
17
  describe('LinksToItem', () => {
18
18
  it('renders "links and references" view', () => {
19
19
  const store = mockStore({
20
+ actions: {
21
+ actions: {
22
+ document_actions: [],
23
+ object: [
24
+ {
25
+ icon: '',
26
+ id: 'edit',
27
+ title: 'Edit',
28
+ },
29
+ ],
30
+ },
31
+ },
20
32
  relations: {
21
33
  subrequests: {
22
34
  '/page-1': {
@@ -242,6 +242,7 @@ export const fetchContent = async ({ store, location }) => {
242
242
  id,
243
243
  data,
244
244
  blocksConfig,
245
+ content,
245
246
  });
246
247
  if (!p?.length) {
247
248
  throw new Error(