@eeacms/volto-eea-website-policy 1.13.1 → 1.14.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/.eslintrc.js +65 -0
- package/CHANGELOG.md +10 -12
- package/jest-addon.config.js +19 -4
- package/jest.setup.js +65 -0
- package/package.json +2 -1
- package/src/components/Blocks/ContextNavigation/index.js +3 -1
- package/src/customizations/volto/components/manage/Display/Display.jsx +306 -0
- package/src/customizations/volto/components/manage/Display/Readme.md +1 -0
- package/src/customizations/volto/components/manage/Toolbar/More.jsx +2 -3
- package/src/customizations/volto/components/manage/Workflow/Workflow.jsx +10 -10
- package/src/index.js +8 -1
- package/.project.eslintrc.js +0 -48
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const projectRootPath = fs.realpathSync(__dirname + '/../../../');
|
|
4
|
+
|
|
5
|
+
let voltoPath = path.join(projectRootPath, 'node_modules/@plone/volto');
|
|
6
|
+
let configFile;
|
|
7
|
+
if (fs.existsSync(`${projectRootPath}/tsconfig.json`))
|
|
8
|
+
configFile = `${projectRootPath}/tsconfig.json`;
|
|
9
|
+
else if (fs.existsSync(`${projectRootPath}/jsconfig.json`))
|
|
10
|
+
configFile = `${projectRootPath}/jsconfig.json`;
|
|
11
|
+
|
|
12
|
+
if (configFile) {
|
|
13
|
+
const jsConfig = require(configFile).compilerOptions;
|
|
14
|
+
const pathsConfig = jsConfig.paths;
|
|
15
|
+
if (pathsConfig['@plone/volto'])
|
|
16
|
+
voltoPath = `./${jsConfig.baseUrl}/${pathsConfig['@plone/volto'][0]}`;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const AddonConfigurationRegistry = require(`${voltoPath}/addon-registry.js`);
|
|
20
|
+
const reg = new AddonConfigurationRegistry(projectRootPath);
|
|
21
|
+
|
|
22
|
+
// Extends ESlint configuration for adding the aliases to `src` directories in Volto addons
|
|
23
|
+
const addonAliases = Object.keys(reg.packages).map((o) => [
|
|
24
|
+
o,
|
|
25
|
+
reg.packages[o].modulePath,
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
const addonExtenders = reg.getEslintExtenders().map((m) => require(m));
|
|
29
|
+
|
|
30
|
+
const defaultConfig = {
|
|
31
|
+
extends: `${voltoPath}/.eslintrc`,
|
|
32
|
+
settings: {
|
|
33
|
+
'import/resolver': {
|
|
34
|
+
alias: {
|
|
35
|
+
map: [
|
|
36
|
+
['@plone/volto', '@plone/volto/src'],
|
|
37
|
+
['@plone/volto-slate', '@plone/volto/packages/volto-slate/src'],
|
|
38
|
+
...addonAliases,
|
|
39
|
+
['@package', `${__dirname}/src`],
|
|
40
|
+
['@root', `${__dirname}/src`],
|
|
41
|
+
['~', `${__dirname}/src`],
|
|
42
|
+
],
|
|
43
|
+
extensions: ['.js', '.jsx', '.json'],
|
|
44
|
+
},
|
|
45
|
+
'babel-plugin-root-import': {
|
|
46
|
+
rootPathSuffix: 'src',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
rules: {
|
|
51
|
+
'react/jsx-no-target-blank': [
|
|
52
|
+
'error',
|
|
53
|
+
{
|
|
54
|
+
allowReferrer: true,
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const config = addonExtenders.reduce(
|
|
61
|
+
(acc, extender) => extender.modify(acc),
|
|
62
|
+
defaultConfig,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
module.exports = config;
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
### [1.14.0](https://github.com/eea/volto-eea-website-policy/compare/1.13.1...1.14.0) - 16 April 2024
|
|
8
|
+
|
|
9
|
+
#### :rocket: New Features
|
|
10
|
+
|
|
11
|
+
- feat: Default view layout restriction to Manager - refs #268249 [ichim-david - [`1840c1b`](https://github.com/eea/volto-eea-website-policy/commit/1840c1bd9aae6ce18a23800ce618f8bbe47525ab)]
|
|
12
|
+
- feat: Volto 17 - refs #264527 [EEA Jenkins - [`253a322`](https://github.com/eea/volto-eea-website-policy/commit/253a3221e36500b4f0f3b160bb2455a066ff3ebd)]
|
|
13
|
+
|
|
14
|
+
#### :hammer_and_wrench: Others
|
|
15
|
+
|
|
16
|
+
- Update Jenkinsfile [Alexandru Ghica - [`c962b11`](https://github.com/eea/volto-eea-website-policy/commit/c962b118d4e2dbe6f5fe938cb8aa1fe610a09d3a)]
|
|
7
17
|
### [1.13.1](https://github.com/eea/volto-eea-website-policy/compare/1.13.0...1.13.1) - 28 March 2024
|
|
8
18
|
|
|
9
19
|
#### :bug: Bug Fixes
|
|
@@ -31,7 +41,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
31
41
|
|
|
32
42
|
#### :hammer_and_wrench: Others
|
|
33
43
|
|
|
34
|
-
- test: [JENKINS] fail with logs on coverage [valentinab25 - [`5cf68f8`](https://github.com/eea/volto-eea-website-policy/commit/5cf68f8db34448d10fe993d16541ad9732434cc8)]
|
|
35
44
|
### [1.12.0-beta.1](https://github.com/eea/volto-eea-website-policy/compare/1.11.1...1.12.0-beta.1) - 12 January 2024
|
|
36
45
|
|
|
37
46
|
#### :hammer_and_wrench: Others
|
|
@@ -52,11 +61,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
52
61
|
#### :hammer_and_wrench: Others
|
|
53
62
|
|
|
54
63
|
- Release 1.11.0 [Alin Voinea - [`3249160`](https://github.com/eea/volto-eea-website-policy/commit/3249160422c6c6e0cf14823b614f8885101a847a)]
|
|
55
|
-
- test: [JENKINS] Use java17 for sonarqube scanner [valentinab25 - [`8beb7e7`](https://github.com/eea/volto-eea-website-policy/commit/8beb7e7a12cbc314e56e4b1aceab5ef8d00ca6f3)]
|
|
56
|
-
- test: [JENKINS] Run cypress in started frontend container [valentinab25 - [`12d3da1`](https://github.com/eea/volto-eea-website-policy/commit/12d3da12e9a3b0882cf55efe2d40f3032724d41b)]
|
|
57
|
-
- test: [JENKINS] Add cpu limit on cypress docker [valentinab25 - [`0af0764`](https://github.com/eea/volto-eea-website-policy/commit/0af076467120ed9a80c697931e869837b92a0a4c)]
|
|
58
|
-
- test: [JENKINS] Increase shm-size to cypress docker [valentinab25 - [`8662e3e`](https://github.com/eea/volto-eea-website-policy/commit/8662e3e5fc3640d678ce320eb8856a37d419306c)]
|
|
59
|
-
- test: [JENKINS] Improve cypress time [valentinab25 - [`ef1074f`](https://github.com/eea/volto-eea-website-policy/commit/ef1074fdf968cafdf476d4ee4951eb18ebac048a)]
|
|
60
64
|
### [1.10.0](https://github.com/eea/volto-eea-website-policy/compare/1.9.2...1.10.0) - 2 November 2023
|
|
61
65
|
|
|
62
66
|
#### :rocket: New Features
|
|
@@ -65,7 +69,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
65
69
|
|
|
66
70
|
#### :house: Internal changes
|
|
67
71
|
|
|
68
|
-
- chore: [JENKINS] Refactor automated testing [valentinab25 - [`8b1b422`](https://github.com/eea/volto-eea-website-policy/commit/8b1b42297b46d9fb7325589b3bd043233c0d66e9)]
|
|
69
72
|
- chore: husky, lint-staged use fixed versions [valentinab25 - [`44ac62e`](https://github.com/eea/volto-eea-website-policy/commit/44ac62e6f8b7e5b7d57edfbf82812c91dc5d6bba)]
|
|
70
73
|
- chore:volto 16 in tests, update docs, fix stylelint overrides [valentinab25 - [`b9a46d8`](https://github.com/eea/volto-eea-website-policy/commit/b9a46d85a64739188a3df9e8cbe645418b5d8b0a)]
|
|
71
74
|
|
|
@@ -186,7 +189,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
186
189
|
|
|
187
190
|
- Release 1.5.0 [Alin Voinea - [`a3dea8e`](https://github.com/eea/volto-eea-website-policy/commit/a3dea8ea15cb8d2a876dc10da926ece3a5707ea9)]
|
|
188
191
|
- test(Jenkinsfile): Use latest stable volto for testing [Alin Voinea - [`a8f7123`](https://github.com/eea/volto-eea-website-policy/commit/a8f712364187f9638886667c249fa102cb49b5c0)]
|
|
189
|
-
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`124a8f8`](https://github.com/eea/volto-eea-website-policy/commit/124a8f8ad4ced507aeec27012d725f2e2b977e08)]
|
|
190
192
|
### [1.4.0](https://github.com/eea/volto-eea-website-policy/compare/1.3.4...1.4.0) - 21 February 2023
|
|
191
193
|
|
|
192
194
|
#### :rocket: New Features
|
|
@@ -266,7 +268,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
266
268
|
#### :hammer_and_wrench: Others
|
|
267
269
|
|
|
268
270
|
- Release 1.1.0 [Alin Voinea - [`0291b3b`](https://github.com/eea/volto-eea-website-policy/commit/0291b3bb7b4c6ab09ca98728885cea4051eac8e3)]
|
|
269
|
-
- yarn 3 [Alin Voinea - [`593aa58`](https://github.com/eea/volto-eea-website-policy/commit/593aa58eaa4d28aced0603b7f7dd125c857a6f54)]
|
|
270
271
|
### [1.0.4](https://github.com/eea/volto-eea-website-policy/compare/1.0.3...1.0.4) - 22 November 2022
|
|
271
272
|
|
|
272
273
|
#### :nail_care: Enhancements
|
|
@@ -312,7 +313,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
312
313
|
|
|
313
314
|
#### :hammer_and_wrench: Others
|
|
314
315
|
|
|
315
|
-
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`d153f54`](https://github.com/eea/volto-eea-website-policy/commit/d153f54e55e918fa4746e05488c734624eaf14a9)]
|
|
316
316
|
### [0.4.0](https://github.com/eea/volto-eea-website-policy/compare/0.3.3...0.4.0) - 19 September 2022
|
|
317
317
|
|
|
318
318
|
#### :hammer_and_wrench: Others
|
|
@@ -388,7 +388,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
388
388
|
- format index.js [Andrei Grigore - [`db4481a`](https://github.com/eea/volto-eea-website-policy/commit/db4481aeeba59a769272659f33278c902fc69bec)]
|
|
389
389
|
- Update index.js [Alexandru Ghica - [`dc09886`](https://github.com/eea/volto-eea-website-policy/commit/dc0988640a76a9914381b120f58bb61a9ab1eb39)]
|
|
390
390
|
- Added externalRoutes [Alexandru Ghica - [`b68135b`](https://github.com/eea/volto-eea-website-policy/commit/b68135b013fafa93a41ea602ea2fad30879abe0f)]
|
|
391
|
-
- Add Sonarqube tag using eea-website-frontend addons list [EEA Jenkins - [`575cca6`](https://github.com/eea/volto-eea-website-policy/commit/575cca674602ca2e1c2a41300c47ba594ff49aa0)]
|
|
392
391
|
### [0.1.1](https://github.com/eea/volto-eea-website-policy/compare/0.1.0...0.1.1) - 4 March 2022
|
|
393
392
|
|
|
394
393
|
#### :hammer_and_wrench: Others
|
|
@@ -401,5 +400,4 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
401
400
|
|
|
402
401
|
#### :hammer_and_wrench: Others
|
|
403
402
|
|
|
404
|
-
- yarn bootstrap [Alin Voinea - [`9b4d197`](https://github.com/eea/volto-eea-website-policy/commit/9b4d197cbc7992566cb36524d190078d5ad21a44)]
|
|
405
403
|
- Initial commit [Alin Voinea - [`3800692`](https://github.com/eea/volto-eea-website-policy/commit/3800692f7a4de6460815bd6061facacb986cbef0)]
|
package/jest-addon.config.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require('dotenv').config({ path: __dirname + '/.env' })
|
|
2
|
+
|
|
1
3
|
module.exports = {
|
|
2
4
|
testMatch: ['**/src/addons/**/?(*.)+(spec|test).[jt]s?(x)'],
|
|
3
5
|
collectCoverageFrom: [
|
|
@@ -9,18 +11,26 @@ module.exports = {
|
|
|
9
11
|
'@plone/volto/cypress': '<rootDir>/node_modules/@plone/volto/cypress',
|
|
10
12
|
'@plone/volto/babel': '<rootDir>/node_modules/@plone/volto/babel',
|
|
11
13
|
'@plone/volto/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
|
|
12
|
-
'@package/(.*)$': '<rootDir>/src/$1',
|
|
13
|
-
'@root/(.*)$': '<rootDir>/src/$1',
|
|
14
|
+
'@package/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
|
|
15
|
+
'@root/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
|
|
14
16
|
'@plone/volto-quanta/(.*)$': '<rootDir>/src/addons/volto-quanta/src/$1',
|
|
17
|
+
'@eeacms/search/(.*)$': '<rootDir>/src/addons/volto-searchlib/searchlib/$1',
|
|
18
|
+
'@eeacms/search': '<rootDir>/src/addons/volto-searchlib/searchlib',
|
|
15
19
|
'@eeacms/(.*?)/(.*)$': '<rootDir>/node_modules/@eeacms/$1/src/$2',
|
|
16
|
-
'@plone/volto-slate':
|
|
20
|
+
'@plone/volto-slate$':
|
|
17
21
|
'<rootDir>/node_modules/@plone/volto/packages/volto-slate/src',
|
|
22
|
+
'@plone/volto-slate/(.*)$':
|
|
23
|
+
'<rootDir>/node_modules/@plone/volto/packages/volto-slate/src/$1',
|
|
18
24
|
'~/(.*)$': '<rootDir>/src/$1',
|
|
19
25
|
'load-volto-addons':
|
|
20
26
|
'<rootDir>/node_modules/@plone/volto/jest-addons-loader.js',
|
|
21
27
|
},
|
|
28
|
+
transformIgnorePatterns: [
|
|
29
|
+
'/node_modules/(?!(@plone|@root|@package|@eeacms)/).*/',
|
|
30
|
+
],
|
|
22
31
|
transform: {
|
|
23
32
|
'^.+\\.js(x)?$': 'babel-jest',
|
|
33
|
+
'^.+\\.ts(x)?$': 'babel-jest',
|
|
24
34
|
'^.+\\.(png)$': 'jest-file',
|
|
25
35
|
'^.+\\.(jpg)$': 'jest-file',
|
|
26
36
|
'^.+\\.(svg)$': './node_modules/@plone/volto/jest-svgsystem-transform.js',
|
|
@@ -33,4 +43,9 @@ module.exports = {
|
|
|
33
43
|
statements: 5,
|
|
34
44
|
},
|
|
35
45
|
},
|
|
36
|
-
|
|
46
|
+
...(process.env.JEST_USE_SETUP === 'ON' && {
|
|
47
|
+
setupFilesAfterEnv: [
|
|
48
|
+
'<rootDir>/node_modules/@eeacms/volto-eea-website-policy/jest.setup.js',
|
|
49
|
+
],
|
|
50
|
+
}),
|
|
51
|
+
}
|
package/jest.setup.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jest } from '@jest/globals';
|
|
2
|
+
import configureStore from 'redux-mock-store';
|
|
3
|
+
import thunk from 'redux-thunk';
|
|
4
|
+
import { blocksConfig } from '@plone/volto/config/Blocks';
|
|
5
|
+
import installSlate from '@plone/volto-slate/index';
|
|
6
|
+
|
|
7
|
+
var mockSemanticComponents = jest.requireActual('semantic-ui-react');
|
|
8
|
+
var mockComponents = jest.requireActual('@plone/volto/components');
|
|
9
|
+
var config = jest.requireActual('@plone/volto/registry').default;
|
|
10
|
+
|
|
11
|
+
config.blocks.blocksConfig = {
|
|
12
|
+
...blocksConfig,
|
|
13
|
+
...config.blocks.blocksConfig,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
jest.doMock('semantic-ui-react', () => ({
|
|
17
|
+
__esModule: true,
|
|
18
|
+
...mockSemanticComponents,
|
|
19
|
+
Popup: ({ content, trigger }) => {
|
|
20
|
+
return (
|
|
21
|
+
<div className="popup">
|
|
22
|
+
<div className="trigger">{trigger}</div>
|
|
23
|
+
<div className="content">{content}</div>
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
26
|
+
},
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
jest.doMock('@plone/volto/components', () => {
|
|
30
|
+
return {
|
|
31
|
+
__esModule: true,
|
|
32
|
+
...mockComponents,
|
|
33
|
+
SidebarPortal: ({ children }) => <div id="sidebar">{children}</div>,
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
jest.doMock('@plone/volto/registry', () =>
|
|
38
|
+
[installSlate].reduce((acc, apply) => apply(acc), config),
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const mockStore = configureStore([thunk]);
|
|
42
|
+
|
|
43
|
+
global.fetch = jest.fn(() =>
|
|
44
|
+
Promise.resolve({
|
|
45
|
+
json: () => Promise.resolve({}),
|
|
46
|
+
}),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
global.store = mockStore({
|
|
50
|
+
intl: {
|
|
51
|
+
locale: 'en',
|
|
52
|
+
messages: {},
|
|
53
|
+
formatMessage: jest.fn(),
|
|
54
|
+
},
|
|
55
|
+
content: {
|
|
56
|
+
create: {},
|
|
57
|
+
subrequests: [],
|
|
58
|
+
},
|
|
59
|
+
connected_data_parameters: {},
|
|
60
|
+
screen: {
|
|
61
|
+
page: {
|
|
62
|
+
width: 768,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eeacms/volto-eea-website-policy",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "@eeacms/volto-eea-website-policy: Volto add-on",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"author": "European Environment Agency: IDM2 A-Team",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"@cypress/code-coverage": "^3.10.0",
|
|
27
27
|
"@plone/scripts": "*",
|
|
28
28
|
"babel-plugin-transform-class-properties": "^6.24.1",
|
|
29
|
+
"dotenv": "^16.3.2",
|
|
29
30
|
"husky": "^8.0.3",
|
|
30
31
|
"lint-staged": "^14.0.1",
|
|
31
32
|
"md5": "^2.3.0"
|
|
@@ -3,7 +3,7 @@ import ContextNavigationEdit from './ContextNavigationEdit';
|
|
|
3
3
|
import ContextNavigationView from './ContextNavigationView';
|
|
4
4
|
import BlockSettingsSchema from '@plone/volto/components/manage/Blocks/Block/Schema';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const applyConfig = (config) => {
|
|
7
7
|
config.blocks.blocksConfig.contextNavigation = {
|
|
8
8
|
id: 'contextNavigation',
|
|
9
9
|
title: 'Navigation',
|
|
@@ -24,3 +24,5 @@ export default (config) => {
|
|
|
24
24
|
|
|
25
25
|
return config;
|
|
26
26
|
};
|
|
27
|
+
|
|
28
|
+
export default applyConfig;
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import React, { Component, Fragment } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { connect } from 'react-redux';
|
|
4
|
+
import { compose } from 'redux';
|
|
5
|
+
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
6
|
+
|
|
7
|
+
import jwtDecode from 'jwt-decode';
|
|
8
|
+
import {
|
|
9
|
+
getSchema,
|
|
10
|
+
getUser,
|
|
11
|
+
updateContent,
|
|
12
|
+
getContent,
|
|
13
|
+
} from '@plone/volto/actions';
|
|
14
|
+
import { getLayoutFieldname } from '@plone/volto/helpers';
|
|
15
|
+
import { FormFieldWrapper, Icon } from '@plone/volto/components';
|
|
16
|
+
import { defineMessages, injectIntl } from 'react-intl';
|
|
17
|
+
import config from '@plone/volto/registry';
|
|
18
|
+
|
|
19
|
+
import downSVG from '@plone/volto/icons/down-key.svg';
|
|
20
|
+
import upSVG from '@plone/volto/icons/up-key.svg';
|
|
21
|
+
import checkSVG from '@plone/volto/icons/check.svg';
|
|
22
|
+
|
|
23
|
+
const messages = defineMessages({
|
|
24
|
+
Viewmode: {
|
|
25
|
+
id: 'Viewmode',
|
|
26
|
+
defaultMessage: 'View',
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const Option = injectLazyLibs('reactSelect')((props) => {
|
|
31
|
+
const { Option } = props.reactSelect.components;
|
|
32
|
+
return (
|
|
33
|
+
<Option {...props}>
|
|
34
|
+
<div>{props.label}</div>
|
|
35
|
+
{props.isFocused && !props.isSelected && (
|
|
36
|
+
<Icon name={checkSVG} size="18px" color="#b8c6c8" />
|
|
37
|
+
)}
|
|
38
|
+
{props.isSelected && <Icon name={checkSVG} size="18px" color="#007bc1" />}
|
|
39
|
+
</Option>
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const DropdownIndicator = injectLazyLibs('reactSelect')((props) => {
|
|
44
|
+
const { DropdownIndicator } = props.reactSelect.components;
|
|
45
|
+
return (
|
|
46
|
+
<DropdownIndicator {...props}>
|
|
47
|
+
{props.selectProps.menuIsOpen ? (
|
|
48
|
+
<Icon name={upSVG} size="24px" color="#007bc1" />
|
|
49
|
+
) : (
|
|
50
|
+
<Icon name={downSVG} size="24px" color="#007bc1" />
|
|
51
|
+
)}
|
|
52
|
+
</DropdownIndicator>
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const selectTheme = (theme) => ({
|
|
57
|
+
...theme,
|
|
58
|
+
borderRadius: 0,
|
|
59
|
+
colors: {
|
|
60
|
+
...theme.colors,
|
|
61
|
+
primary25: 'hotpink',
|
|
62
|
+
primary: '#b8c6c8',
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const customSelectStyles = {
|
|
67
|
+
control: (styles, state) => ({
|
|
68
|
+
...styles,
|
|
69
|
+
border: 'none',
|
|
70
|
+
borderBottom: '2px solid #b8c6c8',
|
|
71
|
+
boxShadow: 'none',
|
|
72
|
+
borderBottomStyle: state.menuIsOpen ? 'dotted' : 'solid',
|
|
73
|
+
}),
|
|
74
|
+
menu: (styles, state) => ({
|
|
75
|
+
...styles,
|
|
76
|
+
top: null,
|
|
77
|
+
marginTop: 0,
|
|
78
|
+
boxShadow: 'none',
|
|
79
|
+
borderBottom: '2px solid #b8c6c8',
|
|
80
|
+
}),
|
|
81
|
+
menuList: (styles, state) => ({
|
|
82
|
+
...styles,
|
|
83
|
+
maxHeight: '400px',
|
|
84
|
+
}),
|
|
85
|
+
indicatorSeparator: (styles) => ({
|
|
86
|
+
...styles,
|
|
87
|
+
width: null,
|
|
88
|
+
}),
|
|
89
|
+
valueContainer: (styles) => ({
|
|
90
|
+
...styles,
|
|
91
|
+
padding: 0,
|
|
92
|
+
}),
|
|
93
|
+
option: (styles, state) => ({
|
|
94
|
+
...styles,
|
|
95
|
+
backgroundColor: null,
|
|
96
|
+
minHeight: '50px',
|
|
97
|
+
display: 'flex',
|
|
98
|
+
justifyContent: 'space-between',
|
|
99
|
+
alignItems: 'center',
|
|
100
|
+
padding: '12px 12px',
|
|
101
|
+
color: state.isSelected
|
|
102
|
+
? '#007bc1'
|
|
103
|
+
: state.isFocused
|
|
104
|
+
? '#4a4a4a'
|
|
105
|
+
: 'inherit',
|
|
106
|
+
':active': {
|
|
107
|
+
backgroundColor: null,
|
|
108
|
+
},
|
|
109
|
+
span: {
|
|
110
|
+
flex: '0 0 auto',
|
|
111
|
+
},
|
|
112
|
+
svg: {
|
|
113
|
+
flex: '0 0 auto',
|
|
114
|
+
},
|
|
115
|
+
}),
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Display container class.
|
|
120
|
+
* @class Display
|
|
121
|
+
* @extends Component
|
|
122
|
+
*/
|
|
123
|
+
class DisplaySelect extends Component {
|
|
124
|
+
/**
|
|
125
|
+
* Property types.
|
|
126
|
+
* @property {Object} propTypes Property types.
|
|
127
|
+
* @static
|
|
128
|
+
*/
|
|
129
|
+
static propTypes = {
|
|
130
|
+
getSchema: PropTypes.func.isRequired,
|
|
131
|
+
updateContent: PropTypes.func.isRequired,
|
|
132
|
+
getContent: PropTypes.func.isRequired,
|
|
133
|
+
loaded: PropTypes.bool.isRequired,
|
|
134
|
+
pathname: PropTypes.string.isRequired,
|
|
135
|
+
layouts: PropTypes.arrayOf(PropTypes.string),
|
|
136
|
+
layout: PropTypes.string,
|
|
137
|
+
type: PropTypes.string.isRequired,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Default properties
|
|
142
|
+
* @property {Object} defaultProps Default properties.
|
|
143
|
+
* @static
|
|
144
|
+
*/
|
|
145
|
+
static defaultProps = {
|
|
146
|
+
layouts: [],
|
|
147
|
+
layout: '',
|
|
148
|
+
rolesWhoCanChangeLayout: [],
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
state = {
|
|
152
|
+
hasMatchingRole: false,
|
|
153
|
+
selectedOption: {
|
|
154
|
+
value: this.props.layout,
|
|
155
|
+
label: config.views.layoutViewsNamesMapping?.[this.props.layout]
|
|
156
|
+
? this.props.intl.formatMessage({
|
|
157
|
+
id: config.views.layoutViewsNamesMapping?.[this.props.layout],
|
|
158
|
+
defaultMessage:
|
|
159
|
+
config.views.layoutViewsNamesMapping?.[this.props.layout],
|
|
160
|
+
})
|
|
161
|
+
: this.props.layout,
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
componentDidMount() {
|
|
166
|
+
this.props.getSchema(this.props.type);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
UNSAFE_componentWillMount() {
|
|
170
|
+
if (!this.props.rolesWhoCanChangeLayout.length) {
|
|
171
|
+
this.props.rolesWhoCanChangeLayout.push(
|
|
172
|
+
...(config?.settings?.eea?.rolesWhoCanChangeLayout || []),
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
if (!this.props.layouts.length) {
|
|
176
|
+
this.props.getSchema(this.props.type);
|
|
177
|
+
}
|
|
178
|
+
if (Object.keys(this.props.user).length === 0) {
|
|
179
|
+
this.props.getUser(this.props.userId);
|
|
180
|
+
} else {
|
|
181
|
+
const hasMatchingRole = this.props.user.roles.some((role) =>
|
|
182
|
+
this.props.rolesWhoCanChangeLayout.includes(role),
|
|
183
|
+
);
|
|
184
|
+
if (hasMatchingRole !== this.state.hasMatchingRole) {
|
|
185
|
+
this.setState({ hasMatchingRole });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Component will receive props
|
|
192
|
+
* @method componentWillReceiveProps
|
|
193
|
+
* @param {Object} nextProps Next properties
|
|
194
|
+
* @returns {undefined}
|
|
195
|
+
*/
|
|
196
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
197
|
+
if (nextProps.pathname !== this.props.pathname) {
|
|
198
|
+
this.props.getSchema(nextProps.type);
|
|
199
|
+
}
|
|
200
|
+
if (!this.props.loaded && nextProps.loaded) {
|
|
201
|
+
this.props.getContent(nextProps.pathname);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (Object.keys(nextProps.user).length !== 0) {
|
|
205
|
+
const hasMatchingRole = nextProps.user.roles.some((role) =>
|
|
206
|
+
this.props.rolesWhoCanChangeLayout.includes(role),
|
|
207
|
+
);
|
|
208
|
+
if (hasMatchingRole !== this.state.hasMatchingRole) {
|
|
209
|
+
this.setState({ hasMatchingRole });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* On set layout handler
|
|
216
|
+
* @method setLayout
|
|
217
|
+
* @param {Object} event Event object
|
|
218
|
+
* @returns {undefined}
|
|
219
|
+
*/
|
|
220
|
+
setLayout = (selectedOption) => {
|
|
221
|
+
this.props.updateContent(this.props.pathname, {
|
|
222
|
+
layout: selectedOption.value,
|
|
223
|
+
});
|
|
224
|
+
this.setState({ selectedOption });
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
selectValue = (option) => (
|
|
228
|
+
<Fragment>
|
|
229
|
+
<span className="Select-value-label">{option.label}</span>
|
|
230
|
+
</Fragment>
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
optionRenderer = (option) => (
|
|
234
|
+
<Fragment>
|
|
235
|
+
<span style={{ marginRight: 'auto' }}>{option.label}</span>
|
|
236
|
+
<Icon name={checkSVG} size="24px" />
|
|
237
|
+
</Fragment>
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
render() {
|
|
241
|
+
if (!this.state.hasMatchingRole) {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
const { selectedOption } = this.state;
|
|
245
|
+
const Select = this.props.reactSelect.default;
|
|
246
|
+
const layoutsNames = config.views.layoutViewsNamesMapping;
|
|
247
|
+
const layoutOptions = this.props.layouts
|
|
248
|
+
.filter(
|
|
249
|
+
(layout) =>
|
|
250
|
+
Object.keys(config.views.contentTypesViews).includes(layout) ||
|
|
251
|
+
Object.keys(config.views.layoutViews).includes(layout),
|
|
252
|
+
)
|
|
253
|
+
.map((item) => ({
|
|
254
|
+
value: item,
|
|
255
|
+
label:
|
|
256
|
+
this.props.intl.formatMessage({
|
|
257
|
+
id: layoutsNames[item],
|
|
258
|
+
defaultMessage: layoutsNames[item],
|
|
259
|
+
}) || item,
|
|
260
|
+
}));
|
|
261
|
+
|
|
262
|
+
return layoutOptions?.length > 1 ? (
|
|
263
|
+
<FormFieldWrapper
|
|
264
|
+
id="display-select"
|
|
265
|
+
title={this.props.intl.formatMessage(messages.Viewmode)}
|
|
266
|
+
{...this.props}
|
|
267
|
+
>
|
|
268
|
+
<Select
|
|
269
|
+
name="display-select"
|
|
270
|
+
className="react-select-container"
|
|
271
|
+
classNamePrefix="react-select"
|
|
272
|
+
options={layoutOptions}
|
|
273
|
+
styles={customSelectStyles}
|
|
274
|
+
theme={selectTheme}
|
|
275
|
+
components={{ DropdownIndicator, Option }}
|
|
276
|
+
onChange={this.setLayout}
|
|
277
|
+
defaultValue={selectedOption}
|
|
278
|
+
isSearchable={false}
|
|
279
|
+
/>
|
|
280
|
+
</FormFieldWrapper>
|
|
281
|
+
) : null;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export default compose(
|
|
286
|
+
injectIntl,
|
|
287
|
+
injectLazyLibs('reactSelect'),
|
|
288
|
+
connect(
|
|
289
|
+
(state) => ({
|
|
290
|
+
loaded: state.content.update.loaded,
|
|
291
|
+
layouts: state.schema.schema ? state.schema.schema.layouts : [],
|
|
292
|
+
layout: state.content.data
|
|
293
|
+
? state.content.data[getLayoutFieldname(state.content.data)]
|
|
294
|
+
: '',
|
|
295
|
+
layout_fieldname: state.content.data
|
|
296
|
+
? getLayoutFieldname(state.content.data)
|
|
297
|
+
: '',
|
|
298
|
+
type: state.content.data ? state.content.data['@type'] : '',
|
|
299
|
+
user: state.users.user,
|
|
300
|
+
userId: state.userSession.token
|
|
301
|
+
? jwtDecode(state.userSession.token).sub
|
|
302
|
+
: '',
|
|
303
|
+
}),
|
|
304
|
+
{ getSchema, getUser, updateContent, getContent },
|
|
305
|
+
),
|
|
306
|
+
)(DisplaySelect);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Added customization to condition the display of the layout options based on the user's roles.
|
|
@@ -82,8 +82,7 @@ const messages = defineMessages({
|
|
|
82
82
|
defaultMessage: 'Changes applied',
|
|
83
83
|
},
|
|
84
84
|
workingCopyAppliedBy: {
|
|
85
|
-
id:
|
|
86
|
-
'Made by {creator} on {date}. This is not a working copy anymore, but the main content.',
|
|
85
|
+
id: 'Made by {creator} on {date}. This is not a working copy anymore, but the main content.',
|
|
87
86
|
defaultMessage:
|
|
88
87
|
'Made by {creator} on {date}. This is not a working copy anymore, but the main content.',
|
|
89
88
|
},
|
|
@@ -342,7 +341,7 @@ class More extends Component {
|
|
|
342
341
|
<div className="pastanaga-menu-list">
|
|
343
342
|
<ul>
|
|
344
343
|
{pluggables.map((p) => (
|
|
345
|
-
|
|
344
|
+
<React.Fragment key={p.id}>{p()}</React.Fragment>
|
|
346
345
|
))}
|
|
347
346
|
</ul>
|
|
348
347
|
</div>
|
|
@@ -3,20 +3,20 @@
|
|
|
3
3
|
* @module components/manage/Workflow/Workflow
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React, { Component, Fragment } from 'react';
|
|
7
|
-
import PropTypes from 'prop-types';
|
|
8
|
-
import { withRouter } from 'react-router-dom';
|
|
9
|
-
import { compose } from 'redux';
|
|
10
|
-
import { connect } from 'react-redux';
|
|
11
|
-
import { uniqBy } from 'lodash';
|
|
12
|
-
import { toast } from 'react-toastify';
|
|
13
|
-
import { defineMessages, injectIntl } from 'react-intl';
|
|
14
6
|
import { FormFieldWrapper, Icon, Toast } from '@plone/volto/components';
|
|
15
7
|
import {
|
|
16
8
|
flattenToAppURL,
|
|
17
9
|
getCurrentStateMapping,
|
|
18
10
|
getWorkflowOptions,
|
|
19
11
|
} from '@plone/volto/helpers';
|
|
12
|
+
import { uniqBy } from 'lodash';
|
|
13
|
+
import PropTypes from 'prop-types';
|
|
14
|
+
import { Component, Fragment } from 'react';
|
|
15
|
+
import { defineMessages, injectIntl } from 'react-intl';
|
|
16
|
+
import { connect } from 'react-redux';
|
|
17
|
+
import { withRouter } from 'react-router-dom';
|
|
18
|
+
import { toast } from 'react-toastify';
|
|
19
|
+
import { compose } from 'redux';
|
|
20
20
|
|
|
21
21
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
22
22
|
|
|
@@ -26,9 +26,9 @@ import {
|
|
|
26
26
|
transitionWorkflow,
|
|
27
27
|
} from '@plone/volto/actions';
|
|
28
28
|
|
|
29
|
+
import checkSVG from '@plone/volto/icons/check.svg';
|
|
29
30
|
import downSVG from '@plone/volto/icons/down-key.svg';
|
|
30
31
|
import upSVG from '@plone/volto/icons/up-key.svg';
|
|
31
|
-
import checkSVG from '@plone/volto/icons/check.svg';
|
|
32
32
|
|
|
33
33
|
const messages = defineMessages({
|
|
34
34
|
messageUpdated: {
|
|
@@ -200,7 +200,7 @@ class Workflow extends Component {
|
|
|
200
200
|
getContent: PropTypes.func.isRequired,
|
|
201
201
|
getWorkflow: PropTypes.func.isRequired,
|
|
202
202
|
transitionWorkflow: PropTypes.func.isRequired,
|
|
203
|
-
workflowLoaded: PropTypes.
|
|
203
|
+
workflowLoaded: PropTypes.bool,
|
|
204
204
|
loaded: PropTypes.bool.isRequired,
|
|
205
205
|
pathname: PropTypes.string.isRequired,
|
|
206
206
|
|
package/src/index.js
CHANGED
|
@@ -39,7 +39,8 @@ const overrideBlocks = {
|
|
|
39
39
|
|
|
40
40
|
const applyConfig = (config) => {
|
|
41
41
|
// #158717#note-25 any path that isn't static, en or controlpanel is treated as external
|
|
42
|
-
const notInEN =
|
|
42
|
+
const notInEN =
|
|
43
|
+
/^(?!(#|\/en|\/login-authomatic|\/fallback_login|\/static|\/controlpanel|\/cypress|\/login|\/logout|\/contact-form|\/passwordreset)).*$/;
|
|
43
44
|
config.settings.externalRoutes = [
|
|
44
45
|
...(config.settings.externalRoutes || []),
|
|
45
46
|
{
|
|
@@ -92,6 +93,12 @@ const applyConfig = (config) => {
|
|
|
92
93
|
if (config.settings.eea) {
|
|
93
94
|
config.settings.eea.logoTargetUrl = '/en';
|
|
94
95
|
}
|
|
96
|
+
// #268249 - only allow managers to change layout from more menu
|
|
97
|
+
config.settings.eea = {
|
|
98
|
+
...config.settings.eea,
|
|
99
|
+
rolesWhoCanChangeLayout: ['Manager'],
|
|
100
|
+
};
|
|
101
|
+
// config.settings.eea.rolesWhoCanChangeLayout = ['Manager'];
|
|
95
102
|
|
|
96
103
|
// Custom blocks
|
|
97
104
|
// context navigation
|
package/.project.eslintrc.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
const projectRootPath = fs.existsSync('./project')
|
|
5
|
-
? fs.realpathSync('./project')
|
|
6
|
-
: fs.realpathSync('./../../../');
|
|
7
|
-
const packageJson = require(path.join(projectRootPath, 'package.json'));
|
|
8
|
-
const jsConfig = require(path.join(projectRootPath, 'jsconfig.json')).compilerOptions;
|
|
9
|
-
|
|
10
|
-
const pathsConfig = jsConfig.paths;
|
|
11
|
-
|
|
12
|
-
let voltoPath = path.join(projectRootPath, 'node_modules/@plone/volto');
|
|
13
|
-
|
|
14
|
-
Object.keys(pathsConfig).forEach(pkg => {
|
|
15
|
-
if (pkg === '@plone/volto') {
|
|
16
|
-
voltoPath = `./${jsConfig.baseUrl}/${pathsConfig[pkg][0]}`;
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
const AddonConfigurationRegistry = require(`${voltoPath}/addon-registry.js`);
|
|
20
|
-
const reg = new AddonConfigurationRegistry(projectRootPath);
|
|
21
|
-
|
|
22
|
-
// Extends ESlint configuration for adding the aliases to `src` directories in Volto addons
|
|
23
|
-
const addonAliases = Object.keys(reg.packages).map(o => [
|
|
24
|
-
o,
|
|
25
|
-
reg.packages[o].modulePath,
|
|
26
|
-
]);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
module.exports = {
|
|
30
|
-
extends: `${projectRootPath}/node_modules/@plone/volto/.eslintrc`,
|
|
31
|
-
settings: {
|
|
32
|
-
'import/resolver': {
|
|
33
|
-
alias: {
|
|
34
|
-
map: [
|
|
35
|
-
['@plone/volto', '@plone/volto/src'],
|
|
36
|
-
...addonAliases,
|
|
37
|
-
['@package', `${__dirname}/src`],
|
|
38
|
-
['~', `${__dirname}/src`],
|
|
39
|
-
],
|
|
40
|
-
extensions: ['.js', '.jsx', '.json'],
|
|
41
|
-
},
|
|
42
|
-
'babel-plugin-root-import': {
|
|
43
|
-
rootPathSuffix: 'src',
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
|