@eeacms/volto-clms-theme 1.0.112 → 1.0.113
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 +12 -0
- package/package.json +1 -1
- package/src/components/CLMSMeetingView/CLMSMeetingView.jsx +3 -6
- package/src/components/CLMSProfileView/CLMSProfileView.jsx +1 -1
- package/src/components/CLMSSubscriptionView/SubscriptionView.jsx +16 -4
- package/src/components/CclTab/CclTabs.jsx +5 -4
- package/src/customizations/volto/components/manage/UniversalLink/UniversalLink.jsx +158 -0
- package/src/customizations/volto/components/manage/UniversalLink/UniversalLink.stories.mdx +64 -0
- package/src/customizations/volto/components/manage/UniversalLink/UniversalLink.test.jsx +193 -0
- package/theme/clms/css/ccl.less +1 -0
- package/theme/clms/css/forms.css +1 -1
- package/theme/clms/css/maps.less +0 -4
- package/theme/clms/css/volto-block-style-override.css +284 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,8 +4,20 @@ 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.0.113](https://github.com/eea/volto-clms-theme/compare/1.0.112...1.0.113)
|
|
8
|
+
|
|
9
|
+
- Area widget explanation [`#286`](https://github.com/eea/volto-clms-theme/pull/286)
|
|
10
|
+
- UniversalLink override to download files in case user is not Manager [`dd206ae`](https://github.com/eea/volto-clms-theme/commit/dd206ae6040fe927d2895c00beeaf55e1fd0a6fe)
|
|
11
|
+
- fix profile subscribe checkbox checking [`62facfa`](https://github.com/eea/volto-clms-theme/commit/62facfa2db2ba518f421eca0002c2774c080d1da)
|
|
12
|
+
- some changes [`8b27aeb`](https://github.com/eea/volto-clms-theme/commit/8b27aeb01df2a04c4331ca5e4c83150957ff076c)
|
|
13
|
+
- edit and add form dropdown overflow, override volto-block-style product css [`468ce5d`](https://github.com/eea/volto-clms-theme/commit/468ce5d51cffe86844fea63ac9640561d51a9dbd)
|
|
14
|
+
- Rename Register to this meeting to simple Register [`563e0f8`](https://github.com/eea/volto-clms-theme/commit/563e0f8a46040decc68247c17f134573d5bfb4bf)
|
|
15
|
+
|
|
7
16
|
#### [1.0.112](https://github.com/eea/volto-clms-theme/compare/1.0.111...1.0.112)
|
|
8
17
|
|
|
18
|
+
> 3 August 2022
|
|
19
|
+
|
|
20
|
+
- Develop [`#285`](https://github.com/eea/volto-clms-theme/pull/285)
|
|
9
21
|
- import fields [`#284`](https://github.com/eea/volto-clms-theme/pull/284)
|
|
10
22
|
- search filters checkbox unification [`0cd48bc`](https://github.com/eea/volto-clms-theme/commit/0cd48bc9a873ec1b3c4a082c4ec3519fbc3cef6d)
|
|
11
23
|
- check also childless parents CLMS-987 [`641a887`](https://github.com/eea/volto-clms-theme/commit/641a887e9e36f0f2e04aa8eb5362065ed53380a3)
|
package/package.json
CHANGED
|
@@ -132,10 +132,7 @@ export const CLMSMeetingView = (props) => {
|
|
|
132
132
|
) : (
|
|
133
133
|
rIsLoggedIn && (
|
|
134
134
|
<CclButton onClick={() => handleRegister()}>
|
|
135
|
-
<FormattedMessage
|
|
136
|
-
id="Register to this meeting"
|
|
137
|
-
defaultMessage="Register to this meeting"
|
|
138
|
-
/>
|
|
135
|
+
<FormattedMessage id="Register" defaultMessage="Register" />
|
|
139
136
|
</CclButton>
|
|
140
137
|
)
|
|
141
138
|
)}
|
|
@@ -395,8 +392,8 @@ export const CLMSMeetingView = (props) => {
|
|
|
395
392
|
content.anonymous_registration_form?.fullname && (
|
|
396
393
|
<CclButton url={content.anonymous_registration_form?.url}>
|
|
397
394
|
<FormattedMessage
|
|
398
|
-
id="Register
|
|
399
|
-
defaultMessage="Register
|
|
395
|
+
id="Register"
|
|
396
|
+
defaultMessage="Register"
|
|
400
397
|
/>
|
|
401
398
|
</CclButton>
|
|
402
399
|
)}
|
|
@@ -308,12 +308,20 @@ class SubscriptionView extends Component {
|
|
|
308
308
|
</div>
|
|
309
309
|
</div>
|
|
310
310
|
{!this.props.isUnsubscribe && (
|
|
311
|
-
<div className="ccl-form
|
|
311
|
+
<div className="ccl-form ccl-profile-privacy">
|
|
312
312
|
<div className="ccl-form-group">
|
|
313
313
|
<input
|
|
314
314
|
type="checkbox"
|
|
315
|
-
id=
|
|
316
|
-
|
|
315
|
+
id={`footer_privacy-${
|
|
316
|
+
this.state.type_conf
|
|
317
|
+
? this.state.type_conf.type
|
|
318
|
+
: 'loading'
|
|
319
|
+
}`}
|
|
320
|
+
name={`footer_privacy-${
|
|
321
|
+
this.state.type_conf
|
|
322
|
+
? this.state.type_conf.type
|
|
323
|
+
: 'loading'
|
|
324
|
+
}`}
|
|
317
325
|
value={this.state.inputValue}
|
|
318
326
|
onClick={this.handleInputChange}
|
|
319
327
|
className="ccl-checkbox ccl-form-check-input"
|
|
@@ -321,7 +329,11 @@ class SubscriptionView extends Component {
|
|
|
321
329
|
/>
|
|
322
330
|
<label
|
|
323
331
|
className="ccl-form-check-label"
|
|
324
|
-
htmlFor=
|
|
332
|
+
htmlFor={`footer_privacy-${
|
|
333
|
+
this.state.type_conf
|
|
334
|
+
? this.state.type_conf.type
|
|
335
|
+
: 'loading'
|
|
336
|
+
}`}
|
|
325
337
|
>
|
|
326
338
|
{this.props.intl.formatMessage(
|
|
327
339
|
messages.agreePrivacyPolicy,
|
|
@@ -24,7 +24,7 @@ const CclTabs = (props) => {
|
|
|
24
24
|
let { children, routing = false } = props;
|
|
25
25
|
let [activeTab, setActiveTab] = useState(
|
|
26
26
|
props.children[0].props.tabId ||
|
|
27
|
-
props.children[0].props.tabTitle.
|
|
27
|
+
props.children[0].props.tabTitle.split(' ').join('-'),
|
|
28
28
|
);
|
|
29
29
|
|
|
30
30
|
function onClickTabItem(tab) {
|
|
@@ -37,7 +37,7 @@ const CclTabs = (props) => {
|
|
|
37
37
|
if (hash) {
|
|
38
38
|
setActiveTab(hash);
|
|
39
39
|
} else {
|
|
40
|
-
setActiveTab(firstTab.props?.tabTitle?.
|
|
40
|
+
setActiveTab(firstTab.props?.tabTitle?.split(' ').join('-'));
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}, [children, routing]);
|
|
@@ -51,7 +51,7 @@ const CclTabs = (props) => {
|
|
|
51
51
|
.filter((item) => !!item?.props?.tabTitle)
|
|
52
52
|
.map((child, key) => {
|
|
53
53
|
const { tabTitle, redirect } = child.props;
|
|
54
|
-
const tabId = tabTitle?.
|
|
54
|
+
const tabId = tabTitle?.split(' ').join('-');
|
|
55
55
|
return (
|
|
56
56
|
<CclTab
|
|
57
57
|
activeTab={activeTab}
|
|
@@ -82,7 +82,8 @@ const CclTabs = (props) => {
|
|
|
82
82
|
.flat()
|
|
83
83
|
.filter((item) => !!item?.props?.tabTitle)
|
|
84
84
|
.map((child, index) => {
|
|
85
|
-
return child.props?.tabTitle?.
|
|
85
|
+
return child.props?.tabTitle?.split(' ').join('-') !==
|
|
86
|
+
activeTab ? (
|
|
86
87
|
<div key={index} className="deactivate-content">
|
|
87
88
|
{child.props.children}
|
|
88
89
|
</div>
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* UniversalLink
|
|
3
|
+
* @module components/UniversalLink
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import PropTypes from 'prop-types';
|
|
8
|
+
import { Link } from 'react-router-dom';
|
|
9
|
+
import { useSelector } from 'react-redux';
|
|
10
|
+
import {
|
|
11
|
+
flattenToAppURL,
|
|
12
|
+
isInternalURL,
|
|
13
|
+
URLUtils,
|
|
14
|
+
} from '@plone/volto/helpers/Url/Url';
|
|
15
|
+
import { matchPath } from 'react-router';
|
|
16
|
+
|
|
17
|
+
import config from '@plone/volto/registry';
|
|
18
|
+
|
|
19
|
+
const UniversalLink = ({
|
|
20
|
+
href,
|
|
21
|
+
item = null,
|
|
22
|
+
openLinkInNewTab,
|
|
23
|
+
download = false,
|
|
24
|
+
children,
|
|
25
|
+
className = null,
|
|
26
|
+
title = null,
|
|
27
|
+
...props
|
|
28
|
+
}) => {
|
|
29
|
+
const token = useSelector((state) => state.userSession?.token);
|
|
30
|
+
|
|
31
|
+
let url = href;
|
|
32
|
+
if (!href && item) {
|
|
33
|
+
if (!item['@id']) {
|
|
34
|
+
// eslint-disable-next-line no-console
|
|
35
|
+
console.error(
|
|
36
|
+
'Invalid item passed to UniversalLink',
|
|
37
|
+
item,
|
|
38
|
+
props,
|
|
39
|
+
children,
|
|
40
|
+
);
|
|
41
|
+
url = '#';
|
|
42
|
+
} else {
|
|
43
|
+
//case: generic item
|
|
44
|
+
url = flattenToAppURL(item['@id']);
|
|
45
|
+
|
|
46
|
+
//case: item like a Link
|
|
47
|
+
let remoteUrl = item.remoteUrl || item.getRemoteUrl;
|
|
48
|
+
if (!token && remoteUrl) {
|
|
49
|
+
url = remoteUrl;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//case: item of type 'File'
|
|
53
|
+
if (
|
|
54
|
+
!this.props.roles?.includes('Manager') &&
|
|
55
|
+
config.settings.downloadableObjects.includes(item['@type'])
|
|
56
|
+
) {
|
|
57
|
+
url = `${url}/@@download/file`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (
|
|
61
|
+
!token &&
|
|
62
|
+
config.settings.viewableInBrowserObjects.includes(item['@type'])
|
|
63
|
+
) {
|
|
64
|
+
url = `${url}/@@display-file/file`;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const isBlacklisted =
|
|
70
|
+
(config.settings.externalRoutes ?? []).find((route) =>
|
|
71
|
+
matchPath(flattenToAppURL(url), route.match),
|
|
72
|
+
)?.length > 0;
|
|
73
|
+
const isExternal = !isInternalURL(url) || isBlacklisted;
|
|
74
|
+
const isDownload = (!isExternal && url.includes('@@download')) || download;
|
|
75
|
+
const isDisplayFile =
|
|
76
|
+
(!isExternal && url.includes('@@display-file')) || false;
|
|
77
|
+
|
|
78
|
+
const checkedURL = URLUtils.checkAndNormalizeUrl(url);
|
|
79
|
+
|
|
80
|
+
url = checkedURL.url;
|
|
81
|
+
|
|
82
|
+
let tag = (
|
|
83
|
+
<Link
|
|
84
|
+
to={flattenToAppURL(url)}
|
|
85
|
+
target={openLinkInNewTab ?? false ? '_blank' : null}
|
|
86
|
+
title={title}
|
|
87
|
+
className={className}
|
|
88
|
+
{...props}
|
|
89
|
+
>
|
|
90
|
+
{children}
|
|
91
|
+
</Link>
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
if (isExternal) {
|
|
95
|
+
tag = (
|
|
96
|
+
<a
|
|
97
|
+
href={url}
|
|
98
|
+
title={title}
|
|
99
|
+
target={
|
|
100
|
+
!checkedURL.isMail &&
|
|
101
|
+
!checkedURL.isTelephone &&
|
|
102
|
+
!(openLinkInNewTab === false)
|
|
103
|
+
? '_blank'
|
|
104
|
+
: null
|
|
105
|
+
}
|
|
106
|
+
rel="noopener noreferrer"
|
|
107
|
+
className={className}
|
|
108
|
+
{...props}
|
|
109
|
+
>
|
|
110
|
+
{children}
|
|
111
|
+
</a>
|
|
112
|
+
);
|
|
113
|
+
} else if (isDownload) {
|
|
114
|
+
tag = (
|
|
115
|
+
<a
|
|
116
|
+
href={flattenToAppURL(url)}
|
|
117
|
+
download
|
|
118
|
+
title={title}
|
|
119
|
+
className={className}
|
|
120
|
+
{...props}
|
|
121
|
+
>
|
|
122
|
+
{children}
|
|
123
|
+
</a>
|
|
124
|
+
);
|
|
125
|
+
} else if (isDisplayFile) {
|
|
126
|
+
tag = (
|
|
127
|
+
<a
|
|
128
|
+
href={flattenToAppURL(url)}
|
|
129
|
+
title={title}
|
|
130
|
+
target="_blank"
|
|
131
|
+
rel="noopener noreferrer"
|
|
132
|
+
className={className}
|
|
133
|
+
{...props}
|
|
134
|
+
>
|
|
135
|
+
{children}
|
|
136
|
+
</a>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
return tag;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
UniversalLink.propTypes = {
|
|
143
|
+
href: PropTypes.string,
|
|
144
|
+
openLinkInNewTab: PropTypes.bool,
|
|
145
|
+
download: PropTypes.bool,
|
|
146
|
+
className: PropTypes.string,
|
|
147
|
+
title: PropTypes.string,
|
|
148
|
+
item: PropTypes.shape({
|
|
149
|
+
'@id': PropTypes.string.isRequired,
|
|
150
|
+
remoteUrl: PropTypes.string, //of plone @type 'Link'
|
|
151
|
+
}),
|
|
152
|
+
children: PropTypes.oneOfType([
|
|
153
|
+
PropTypes.arrayOf(PropTypes.node),
|
|
154
|
+
PropTypes.node,
|
|
155
|
+
]),
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export default UniversalLink;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Meta, Story, Canvas, ArgsTable } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import UniversalLinkComponent from './UniversalLink';
|
|
3
|
+
import { injectIntl } from 'react-intl';
|
|
4
|
+
import configureStore from 'redux-mock-store';
|
|
5
|
+
import { Provider } from 'react-intl-redux';
|
|
6
|
+
|
|
7
|
+
<Meta
|
|
8
|
+
title="UniversalLink"
|
|
9
|
+
argTypes={{
|
|
10
|
+
href: { control: 'text' },
|
|
11
|
+
item: { control: 'object' },
|
|
12
|
+
text: { control: 'text' },
|
|
13
|
+
}}
|
|
14
|
+
decorators={[
|
|
15
|
+
(Story) => (
|
|
16
|
+
<div style={{ width: '400px' }}>
|
|
17
|
+
<Story />
|
|
18
|
+
</div>
|
|
19
|
+
),
|
|
20
|
+
]}
|
|
21
|
+
/>
|
|
22
|
+
|
|
23
|
+
# UniversalLink
|
|
24
|
+
|
|
25
|
+
Link to url or item
|
|
26
|
+
|
|
27
|
+
export const UniversalLink = (args) => {
|
|
28
|
+
const mockStore = configureStore();
|
|
29
|
+
const store = mockStore({
|
|
30
|
+
userSession: {
|
|
31
|
+
token: null,
|
|
32
|
+
},
|
|
33
|
+
intl: {
|
|
34
|
+
locale: 'en',
|
|
35
|
+
messages: {},
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
return (
|
|
39
|
+
<Provider store={store}>
|
|
40
|
+
<UniversalLinkComponent
|
|
41
|
+
href="http://www.google.it"
|
|
42
|
+
item={{
|
|
43
|
+
'@id': 'localhost:3000/example-link-to-twitter',
|
|
44
|
+
remoteUrl: 'http://www.twitter.it',
|
|
45
|
+
}}
|
|
46
|
+
{...args}
|
|
47
|
+
>
|
|
48
|
+
{args.text || 'Example link to google'}
|
|
49
|
+
</UniversalLinkComponent>
|
|
50
|
+
<h4>Link to a generic object. Example code for 'item' prop:</h4>
|
|
51
|
+
<code> {`{'@id':'localhost:3000/test-page'}`}</code>
|
|
52
|
+
<h4>Link to a Link object. Example code for 'item' prop:</h4>
|
|
53
|
+
<code>
|
|
54
|
+
{`{'@id':'localhost:3000/example-link-to-twitter', 'remoteUrl':'http://www.twitter.it'}`}
|
|
55
|
+
</code>
|
|
56
|
+
</Provider>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
<Story name="UniversalLink">{injectIntl(UniversalLink).bind({})}</Story>
|
|
61
|
+
|
|
62
|
+
# Props
|
|
63
|
+
|
|
64
|
+
<ArgsTable of={UniversalLinkComponent} />
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import renderer from 'react-test-renderer';
|
|
3
|
+
import { Provider } from 'react-intl-redux';
|
|
4
|
+
import configureStore from 'redux-mock-store';
|
|
5
|
+
import { render } from '@testing-library/react';
|
|
6
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
7
|
+
import UniversalLink from './UniversalLink';
|
|
8
|
+
import config from '@plone/volto/registry';
|
|
9
|
+
|
|
10
|
+
const mockStore = configureStore();
|
|
11
|
+
const store = mockStore({
|
|
12
|
+
userSession: {
|
|
13
|
+
token: null,
|
|
14
|
+
},
|
|
15
|
+
intl: {
|
|
16
|
+
locale: 'en',
|
|
17
|
+
messages: {},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
global.console.error = jest.fn();
|
|
22
|
+
|
|
23
|
+
describe('UniversalLink', () => {
|
|
24
|
+
it('renders a UniversalLink component with internal link', () => {
|
|
25
|
+
const component = renderer.create(
|
|
26
|
+
<Provider store={store}>
|
|
27
|
+
<MemoryRouter>
|
|
28
|
+
<UniversalLink href={'/en/welcome-to-volto'}>
|
|
29
|
+
<h1>Title</h1>
|
|
30
|
+
</UniversalLink>
|
|
31
|
+
</MemoryRouter>
|
|
32
|
+
</Provider>,
|
|
33
|
+
);
|
|
34
|
+
const json = component.toJSON();
|
|
35
|
+
expect(json).toMatchSnapshot();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('renders a UniversalLink component with external link', () => {
|
|
39
|
+
const component = renderer.create(
|
|
40
|
+
<Provider store={store}>
|
|
41
|
+
<MemoryRouter>
|
|
42
|
+
<UniversalLink href="https://github.com/plone/volto">
|
|
43
|
+
<h1>Title</h1>
|
|
44
|
+
</UniversalLink>
|
|
45
|
+
</MemoryRouter>
|
|
46
|
+
</Provider>,
|
|
47
|
+
);
|
|
48
|
+
const json = component.toJSON();
|
|
49
|
+
expect(json).toMatchSnapshot();
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('renders a UniversalLink component if no external(href) link passed', () => {
|
|
53
|
+
const component = renderer.create(
|
|
54
|
+
<Provider store={store}>
|
|
55
|
+
<MemoryRouter>
|
|
56
|
+
<UniversalLink
|
|
57
|
+
item={{
|
|
58
|
+
'@id': 'http://localhost:3000/en/welcome-to-volto',
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
<h1>Title</h1>
|
|
62
|
+
</UniversalLink>
|
|
63
|
+
</MemoryRouter>
|
|
64
|
+
</Provider>,
|
|
65
|
+
);
|
|
66
|
+
const json = component.toJSON();
|
|
67
|
+
expect(json).toMatchSnapshot();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('check UniversalLink set rel attribute for ext links', () => {
|
|
71
|
+
const { getByTitle } = render(
|
|
72
|
+
<Provider store={store}>
|
|
73
|
+
<MemoryRouter>
|
|
74
|
+
<UniversalLink
|
|
75
|
+
href="https://github.com/plone/volto"
|
|
76
|
+
title="Volto GitHub repository"
|
|
77
|
+
>
|
|
78
|
+
<h1>Title</h1>
|
|
79
|
+
</UniversalLink>
|
|
80
|
+
</MemoryRouter>
|
|
81
|
+
</Provider>,
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
expect(getByTitle('Volto GitHub repository').getAttribute('rel')).toBe(
|
|
85
|
+
'noopener noreferrer',
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('check UniversalLink set target attribute for ext links', () => {
|
|
90
|
+
const { getByTitle } = render(
|
|
91
|
+
<Provider store={store}>
|
|
92
|
+
<MemoryRouter>
|
|
93
|
+
<UniversalLink
|
|
94
|
+
href="https://github.com/plone/volto"
|
|
95
|
+
title="Volto GitHub repository"
|
|
96
|
+
>
|
|
97
|
+
<h1>Title</h1>
|
|
98
|
+
</UniversalLink>
|
|
99
|
+
</MemoryRouter>
|
|
100
|
+
</Provider>,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
expect(getByTitle('Volto GitHub repository').getAttribute('target')).toBe(
|
|
104
|
+
'_blank',
|
|
105
|
+
);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('check UniversalLink can unset target for ext links with prop', () => {
|
|
109
|
+
const { getByTitle } = render(
|
|
110
|
+
<Provider store={store}>
|
|
111
|
+
<MemoryRouter>
|
|
112
|
+
<UniversalLink
|
|
113
|
+
href="https://github.com/plone/volto"
|
|
114
|
+
title="Volto GitHub repository"
|
|
115
|
+
openLinkInNewTab={false}
|
|
116
|
+
>
|
|
117
|
+
<h1>Title</h1>
|
|
118
|
+
</UniversalLink>
|
|
119
|
+
</MemoryRouter>
|
|
120
|
+
</Provider>,
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
expect(getByTitle('Volto GitHub repository').getAttribute('target')).toBe(
|
|
124
|
+
null,
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('check UniversalLink renders ext link for blacklisted urls', () => {
|
|
129
|
+
config.settings.externalRoutes = [
|
|
130
|
+
{
|
|
131
|
+
match: {
|
|
132
|
+
path: '/external-app',
|
|
133
|
+
exact: true,
|
|
134
|
+
strict: false,
|
|
135
|
+
},
|
|
136
|
+
url(payload) {
|
|
137
|
+
return payload.location.pathname;
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
];
|
|
141
|
+
|
|
142
|
+
const { getByTitle } = render(
|
|
143
|
+
<Provider store={store}>
|
|
144
|
+
<MemoryRouter>
|
|
145
|
+
<UniversalLink
|
|
146
|
+
href="http://localhost:3000/external-app"
|
|
147
|
+
title="Blacklisted route"
|
|
148
|
+
>
|
|
149
|
+
<h1>Title</h1>
|
|
150
|
+
</UniversalLink>
|
|
151
|
+
</MemoryRouter>
|
|
152
|
+
</Provider>,
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
expect(getByTitle('Blacklisted route').getAttribute('target')).toBe(
|
|
156
|
+
'_blank',
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('check UniversalLink does not break with error in item', () => {
|
|
161
|
+
const component = renderer.create(
|
|
162
|
+
<Provider store={store}>
|
|
163
|
+
<MemoryRouter>
|
|
164
|
+
<UniversalLink
|
|
165
|
+
item={{
|
|
166
|
+
error: 'Error while fetching content',
|
|
167
|
+
message: 'Something went wrong',
|
|
168
|
+
}}
|
|
169
|
+
>
|
|
170
|
+
<h1>Title</h1>
|
|
171
|
+
</UniversalLink>
|
|
172
|
+
</MemoryRouter>
|
|
173
|
+
</Provider>,
|
|
174
|
+
);
|
|
175
|
+
const json = component.toJSON();
|
|
176
|
+
expect(json).toMatchSnapshot();
|
|
177
|
+
expect(global.console.error).toHaveBeenCalled();
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('renders a UniversalLink component when url ends with @@display-file', () => {
|
|
182
|
+
const component = renderer.create(
|
|
183
|
+
<Provider store={store}>
|
|
184
|
+
<MemoryRouter>
|
|
185
|
+
<UniversalLink href="http://localhost:3000/en/welcome-to-volto/@@display-file">
|
|
186
|
+
<h1>Title</h1>
|
|
187
|
+
</UniversalLink>
|
|
188
|
+
</MemoryRouter>
|
|
189
|
+
</Provider>,
|
|
190
|
+
);
|
|
191
|
+
const json = component.toJSON();
|
|
192
|
+
expect(json).toMatchSnapshot();
|
|
193
|
+
});
|
package/theme/clms/css/ccl.less
CHANGED
package/theme/clms/css/forms.css
CHANGED
package/theme/clms/css/maps.less
CHANGED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view) .stretch {
|
|
2
|
+
position: relative;
|
|
3
|
+
z-index: 3;
|
|
4
|
+
right: 50%;
|
|
5
|
+
left: 50%;
|
|
6
|
+
width: 100vw;
|
|
7
|
+
border: none !important;
|
|
8
|
+
margin-right: 0;
|
|
9
|
+
margin-left: 0;
|
|
10
|
+
background-clip: content-box;
|
|
11
|
+
box-shadow: none;
|
|
12
|
+
transform: translate(-50%, 0%);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/* detect if is anon */
|
|
16
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
17
|
+
right: 0;
|
|
18
|
+
left: 0;
|
|
19
|
+
width: auto;
|
|
20
|
+
padding: 0;
|
|
21
|
+
margin: 0 -28.3rem;
|
|
22
|
+
transform: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
body:not(.is-authenticated):not(.document_wide_view) main {
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous)
|
|
30
|
+
main {
|
|
31
|
+
overflow: hidden;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* detect if is logged in but in view with toolbar open */
|
|
35
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous)
|
|
36
|
+
.stretch {
|
|
37
|
+
max-width: 1636px;
|
|
38
|
+
margin: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
body:not(.is-authenticated):not(.document_wide_view).stretch {
|
|
42
|
+
padding: 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@media screen and (max-width: 1790px) {
|
|
46
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous)
|
|
47
|
+
.stretch {
|
|
48
|
+
right: auto;
|
|
49
|
+
left: auto;
|
|
50
|
+
width: auto;
|
|
51
|
+
padding: 0;
|
|
52
|
+
transform: none;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar-collapsed)
|
|
56
|
+
.stretch {
|
|
57
|
+
max-width: 100vw;
|
|
58
|
+
margin: 0 -25.54vw;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
62
|
+
.stretch {
|
|
63
|
+
max-width: 100vw;
|
|
64
|
+
margin: 0 -25.5vw;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@media screen and (max-width: 1749px) {
|
|
69
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
70
|
+
.stretch {
|
|
71
|
+
margin: 0 -26.1vw;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@media screen and (max-width: 1700px) {
|
|
76
|
+
body:not(.document_wide_view):not(.view-editview):not(.view-addview):not(.is-anonymous):not(.is-authenticated).stretch {
|
|
77
|
+
margin-right: 0;
|
|
78
|
+
margin-left: 0;
|
|
79
|
+
transform: translate(-50%, 0%);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
body:not(.is-anonymous):not(.has-toolbar) .stretch {
|
|
83
|
+
max-width: 1720px;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
body:not(.is-anonymous):not(.has-toolbar-collapsed) .stretch {
|
|
87
|
+
max-width: 1778px;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
91
|
+
max-width: 1700px;
|
|
92
|
+
margin: 0 -26.8vw;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
96
|
+
.stretch {
|
|
97
|
+
margin: 0 -26.4vw;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@media screen and (max-width: 1599px) {
|
|
102
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar-collapsed)
|
|
103
|
+
.stretch {
|
|
104
|
+
margin: 0 -18.3vw;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
108
|
+
.stretch {
|
|
109
|
+
margin: 0 -18.9vw;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
113
|
+
margin: 0 -19.2vw;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
@media screen and (max-width: 1499px) {
|
|
118
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar-collapsed)
|
|
119
|
+
.stretch {
|
|
120
|
+
margin: 0 -18.4vw;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
124
|
+
.stretch {
|
|
125
|
+
margin: 0 -19vw;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
129
|
+
margin: 0 -19.5vw;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@media screen and (max-width: 1399px) {
|
|
134
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar-collapsed)
|
|
135
|
+
.stretch {
|
|
136
|
+
margin: 0 -18.5vw;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
140
|
+
.stretch {
|
|
141
|
+
margin: 0 -19.2vw;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
145
|
+
margin: 0 -19.8vw;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@media screen and (max-width: 1280px) {
|
|
150
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar-collapsed)
|
|
151
|
+
.stretch {
|
|
152
|
+
margin: 0 -17.8vw;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
156
|
+
.stretch {
|
|
157
|
+
margin: 0 -15.3rem;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@media screen and (max-width: 1220px) {
|
|
162
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
163
|
+
.stretch {
|
|
164
|
+
margin: 0 -14.9rem;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
@media screen and (max-width: 1200px) {
|
|
169
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
170
|
+
margin: 0 -0.6rem;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
174
|
+
margin: 0 -3.7vw;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
@media screen and (max-width: 1199px) {
|
|
179
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar-collapsed)
|
|
180
|
+
.stretch {
|
|
181
|
+
margin: 0 -3.6vw;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
185
|
+
.stretch {
|
|
186
|
+
margin: 0 -3.5vw;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@media screen and (max-width: 1049px) {
|
|
191
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar-collapsed)
|
|
192
|
+
.stretch {
|
|
193
|
+
margin: 0 -4vw;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
197
|
+
.stretch {
|
|
198
|
+
margin: 0 -4vw;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
202
|
+
margin: 0 -4.3vw;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
@media screen and (max-width: 1000px) {
|
|
207
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar-collapsed)
|
|
208
|
+
.stretch {
|
|
209
|
+
margin: 0 -4.2vw;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
213
|
+
.stretch {
|
|
214
|
+
margin: 0 -4.3vw;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
218
|
+
margin: 0 -4.5vw;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
@media screen and (max-width: 900px) {
|
|
223
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar-collapsed)
|
|
224
|
+
.stretch {
|
|
225
|
+
margin: 0 -4.65vw;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
229
|
+
.stretch {
|
|
230
|
+
margin: 0 -4.9vw;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
234
|
+
margin: 0 -4.5vw;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
@media screen and (max-width: 849px) {
|
|
239
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar-collapsed)
|
|
240
|
+
.stretch {
|
|
241
|
+
margin: 0 -1.2vw;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
245
|
+
.stretch {
|
|
246
|
+
margin: 0 -5vw;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
250
|
+
margin: 0 -5.2vw;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
@media screen and (max-width: 787px) {
|
|
255
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar-collapsed)
|
|
256
|
+
.stretch {
|
|
257
|
+
margin: 0 -1.2vw;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
261
|
+
.stretch {
|
|
262
|
+
margin: 0 -1.2vw;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
@media screen and (max-width: 767px) {
|
|
267
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar-collapsed)
|
|
268
|
+
.stretch {
|
|
269
|
+
padding: 0;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
body:not(.view-editview):not(.view-addview):not(.document_wide_view):not(.is-anonymous):not(.has-toolbar)
|
|
273
|
+
.stretch {
|
|
274
|
+
padding: 0;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
278
|
+
padding: 0;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
body:not(.is-authenticated):not(.document_wide_view) .stretch {
|
|
282
|
+
margin: 0 -1.3vw;
|
|
283
|
+
}
|
|
284
|
+
}
|