design-comuni-plone-theme 11.9.1 → 11.10.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/.github/workflows/performance.yml +47 -0
- package/.yarn/cache/minipass-npm-5.0.0-c64fb63c92-425dab2887.zip +0 -0
- package/.yarn/cache/tar-npm-6.2.1-237800bb20-f1322768c9.zip +0 -0
- package/.yarn/cache/{volto-gdpr-privacy-npm-2.1.1-414b7e6a62-2246b94027.zip → volto-gdpr-privacy-npm-2.2.0-6be0f74d53-8a93254251.zip} +0 -0
- package/.yarn/cache/volto-slimheader-npm-0.1.1-6c4a32fae4-94bafa197c.zip +0 -0
- package/.yarn/install-state.gz +0 -0
- package/CHANGELOG.md +48 -0
- package/RELEASE.md +27 -0
- package/locales/de/LC_MESSAGES/volto.po +61 -36
- package/locales/en/LC_MESSAGES/volto.po +63 -38
- package/locales/es/LC_MESSAGES/volto.po +61 -36
- package/locales/fr/LC_MESSAGES/volto.po +62 -37
- package/locales/it/LC_MESSAGES/volto.po +61 -36
- package/locales/volto.pot +62 -37
- package/package.json +5 -3
- package/publiccode.yml +2 -2
- package/src/components/ItaliaTheme/AppExtras/TrackFocus.jsx +47 -0
- package/src/components/ItaliaTheme/Blocks/Accordion/View.jsx +1 -1
- package/src/components/ItaliaTheme/Blocks/ArgumentsInEvidence/BodyWrapper.jsx +8 -3
- package/src/components/ItaliaTheme/Blocks/ArgumentsInEvidence/BottomBody.jsx +25 -16
- package/src/components/ItaliaTheme/Blocks/ArgumentsInEvidence/Edit.jsx +10 -2
- package/src/components/ItaliaTheme/Blocks/ArgumentsInEvidence/Sidebar.jsx +39 -3
- package/src/components/ItaliaTheme/Blocks/ArgumentsInEvidence/View.jsx +31 -16
- package/src/components/ItaliaTheme/Blocks/Calendar/Body.jsx +23 -59
- package/src/components/ItaliaTheme/Blocks/Common/SearchFilters/SelectFilter.jsx +9 -1
- package/src/components/ItaliaTheme/Blocks/EventSearch/DefaultFilters.js +5 -0
- package/src/components/ItaliaTheme/Blocks/IconBlocks/Block/ViewBlock.jsx +17 -0
- package/src/components/ItaliaTheme/Blocks/Listing/CardWithImage/CardWithImageDefault.jsx +182 -0
- package/src/components/ItaliaTheme/Blocks/Listing/CardWithImageTemplate.jsx +7 -173
- package/src/components/ItaliaTheme/Blocks/Listing/Commons/utils.js +0 -70
- package/src/components/ItaliaTheme/Blocks/Listing/PhotogalleryTemplate.jsx +24 -36
- package/src/components/ItaliaTheme/Blocks/Listing/SimpleCard/Card/SimpleCardDefault.jsx +177 -0
- package/src/components/ItaliaTheme/Blocks/Listing/SimpleCard/SimpleCardTemplateDefault.jsx +8 -170
- package/src/components/ItaliaTheme/Blocks/Listing/Slider/SlideItemDefault.jsx +65 -0
- package/src/components/ItaliaTheme/Blocks/Listing/SliderTemplate.jsx +62 -212
- package/src/components/ItaliaTheme/Blocks/VideoGallery/Body.jsx +10 -48
- package/src/components/ItaliaTheme/Blocks/VideoGallery/Edit.jsx +3 -2
- package/src/components/ItaliaTheme/Blocks/VideoGallery/View.jsx +3 -2
- package/src/components/ItaliaTheme/Footer/FooterNavigation.jsx +6 -0
- package/src/components/ItaliaTheme/Header/HeaderSlim/TertiaryMenu.jsx +34 -5
- package/src/components/ItaliaTheme/Icons/FontAwesomeIcon.jsx +2 -0
- package/src/components/ItaliaTheme/MegaMenu/MegaMenu.jsx +8 -2
- package/src/components/ItaliaTheme/MenuSecondary/MenuSecondary.jsx +3 -0
- package/src/components/ItaliaTheme/Slider/ButtonPlayPause.jsx +48 -0
- package/src/components/ItaliaTheme/Slider/CarouselWrapper.jsx +23 -0
- package/src/components/ItaliaTheme/Slider/NextArrow.jsx +31 -0
- package/src/components/ItaliaTheme/Slider/PrevArrow.jsx +33 -0
- package/src/components/ItaliaTheme/Slider/SingleSlideWrapper.jsx +39 -0
- package/src/components/ItaliaTheme/Slider/slider.js +203 -0
- package/src/components/ItaliaTheme/View/Commons/ContactLink.jsx +3 -2
- package/src/components/ItaliaTheme/View/Commons/Dates.jsx +12 -4
- package/src/components/ItaliaTheme/View/Commons/Gallery.jsx +13 -9
- package/src/components/ItaliaTheme/View/Commons/Metadata.jsx +1 -1
- package/src/components/ItaliaTheme/View/Commons/RenderBlocks.jsx +20 -7
- package/src/components/ItaliaTheme/View/DocumentoView/DocumentoDescrizione.jsx +15 -7
- package/src/components/ItaliaTheme/View/EventoView/EventoContattiOrganizzatoreEsterno.jsx +12 -1
- package/src/components/ItaliaTheme/View/EventoView/EventoLuoghi.jsx +7 -7
- package/src/components/ItaliaTheme/View/UOView/UOServices.jsx +1 -1
- package/src/components/ItaliaTheme/View/__tests__/ServizioMetadati.test.jsx +1 -1
- package/src/components/ItaliaTheme/index.js +7 -2
- package/src/config/Blocks/ListingOptions/cardWithImageTemplate.js +18 -2
- package/src/config/Blocks/ListingOptions/simpleCardTemplate.js +34 -17
- package/src/config/Blocks/ListingOptions/sliderTemplate.js +68 -11
- package/src/config/Blocks/listingVariations.js +8 -0
- package/src/config/italiaConfig.js +13 -2
- package/src/customizations/volto/components/manage/Blocks/Listing/ListingBody.jsx +5 -0
- package/src/customizations/volto/components/manage/Blocks/Search/components/SelectFacetFilterListEntry.jsx +43 -36
- package/src/customizations/volto/components/manage/UniversalLink/UniversalLink.jsx +8 -3
- package/src/customizations/volto/components/manage/Widgets/FileWidget.jsx +2 -2
- package/src/customizations/volto/components/theme/Sitemap/Sitemap.jsx +126 -0
- package/src/helpers/config.js +1 -1
- package/src/theme/ItaliaTheme/Blocks/_argumentsInEvidence.scss +4 -4
- package/src/theme/ItaliaTheme/Blocks/{_cardWithImageAndInEvidence.scss → _cardWithImage.scss} +63 -38
- package/src/theme/ItaliaTheme/Blocks/_iconBlocks.scss +7 -6
- package/src/theme/ItaliaTheme/Blocks/_inEvidenceTemplate.scss +123 -0
- package/src/theme/ItaliaTheme/Blocks/_simpleCardTemplate.scss +65 -67
- package/src/theme/ItaliaTheme/Blocks/_sliderTemplate.scss +81 -0
- package/src/theme/ItaliaTheme/Blocks/common/_searchBlockFilters.scss +16 -0
- package/src/theme/ItaliaTheme/Components/_cardPersona.scss +1 -1
- package/src/theme/ItaliaTheme/Components/_mobileMenu.scss +1 -1
- package/src/theme/ItaliaTheme/Components/_navigation.scss +15 -0
- package/src/theme/ItaliaTheme/Components/_tertiaryMenu.scss +6 -0
- package/src/theme/ItaliaTheme/Print/_all_pages.scss +33 -0
- package/src/theme/ItaliaTheme/Print/_page.scss +21 -0
- package/src/theme/ItaliaTheme/Print/_uo.scss +7 -2
- package/src/theme/ItaliaTheme/Views/_common.scss +4 -0
- package/src/theme/bootstrap-override/bootstrap-italia/_chips.scss +16 -1
- package/src/theme/bootstrap-override/bootstrap-italia/_footer.scss +2 -0
- package/src/theme/site.scss +4 -2
- package/.yarn/cache/nanoid-npm-3.3.4-3d250377d6-2fddd6dee9.zip +0 -0
- package/.yarn/cache/postcss-npm-8.4.16-7367383579-10eee25efd.zip +0 -0
- package/.yarn/cache/tar-npm-6.1.11-e6ac3cba9c-a04c07bb9e.zip +0 -0
- package/src/components/ItaliaTheme/Blocks/Listing/Commons/NextArrow.jsx +0 -10
- package/src/components/ItaliaTheme/Blocks/Listing/Commons/PrevArrow.jsx +0 -10
- package/src/theme/ItaliaTheme/Blocks/_inevidencetemplate.scss +0 -34
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
3
|
+
const messages = defineMessages({
|
|
4
|
+
carousel: {
|
|
5
|
+
id: 'carousel',
|
|
6
|
+
defaultMessage: 'Carosello',
|
|
7
|
+
},
|
|
8
|
+
});
|
|
9
|
+
const CarouselWrapper = ({ className, children }) => {
|
|
10
|
+
const intl = useIntl();
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div
|
|
14
|
+
className={`it-carousel-all ${className ?? ''}`}
|
|
15
|
+
role="region"
|
|
16
|
+
aria-label={intl.formatMessage(messages.carousel)}
|
|
17
|
+
>
|
|
18
|
+
{children}
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default CarouselWrapper;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Icon } from 'design-comuni-plone-theme/components/ItaliaTheme';
|
|
3
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
4
|
+
|
|
5
|
+
const messages = defineMessages({
|
|
6
|
+
successivo: {
|
|
7
|
+
id: 'successivo',
|
|
8
|
+
defaultMessage: 'Successivo',
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export default function NextArrow(props) {
|
|
13
|
+
const intl = useIntl();
|
|
14
|
+
const { className, style, onClick, onKeyDown, title, id } = props;
|
|
15
|
+
const _title = title ?? intl.formatMessage(messages.successivo);
|
|
16
|
+
return (
|
|
17
|
+
<button
|
|
18
|
+
className={className}
|
|
19
|
+
style={{ ...style }}
|
|
20
|
+
onClick={onClick}
|
|
21
|
+
title={_title}
|
|
22
|
+
aria-label={_title}
|
|
23
|
+
aria-hidden={false}
|
|
24
|
+
onKeyDown={onKeyDown}
|
|
25
|
+
id={id}
|
|
26
|
+
>
|
|
27
|
+
<Icon icon="chevron-right" key="chevron-right" title={_title} />
|
|
28
|
+
<span class="visually-hidden">{_title}</span>
|
|
29
|
+
</button>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Icon } from 'design-comuni-plone-theme/components/ItaliaTheme';
|
|
3
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
4
|
+
|
|
5
|
+
const messages = defineMessages({
|
|
6
|
+
precedente: {
|
|
7
|
+
id: 'precedente',
|
|
8
|
+
defaultMessage: 'Precedente',
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export default function PrevArrow(props) {
|
|
13
|
+
const intl = useIntl();
|
|
14
|
+
const { className, style, onClick, onKeyDown, title, id } = props;
|
|
15
|
+
|
|
16
|
+
const _title = title ?? intl.formatMessage(messages.precedente);
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<button
|
|
20
|
+
className={className}
|
|
21
|
+
style={{ ...style }}
|
|
22
|
+
onClick={onClick}
|
|
23
|
+
title={_title}
|
|
24
|
+
aria-label={_title}
|
|
25
|
+
aria-hidden={false}
|
|
26
|
+
id={id}
|
|
27
|
+
onKeyDown={onKeyDown}
|
|
28
|
+
>
|
|
29
|
+
<Icon icon="chevron-left" key="chevron-left-prev" title={_title} />
|
|
30
|
+
<span class="visually-hidden">{_title}</span>
|
|
31
|
+
</button>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
3
|
+
const messages = defineMessages({
|
|
4
|
+
carouselSlide: {
|
|
5
|
+
id: 'carouselSlide',
|
|
6
|
+
defaultMessage: 'Slide',
|
|
7
|
+
},
|
|
8
|
+
});
|
|
9
|
+
const SingleSlideWrapper = (props) => {
|
|
10
|
+
const { className, key, index, children, onKeyDown } = props;
|
|
11
|
+
const intl = useIntl();
|
|
12
|
+
const wrapperKey = key ?? 'slide-wrapper-' + index;
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div
|
|
16
|
+
className={`it-single-slide-wrapper ${className ?? ''}`}
|
|
17
|
+
key={wrapperKey}
|
|
18
|
+
data-slide={index}
|
|
19
|
+
role="group"
|
|
20
|
+
aria-label={
|
|
21
|
+
intl.formatMessage(messages.carouselSlide) +
|
|
22
|
+
' ' +
|
|
23
|
+
(index ? index + 1 : '') +
|
|
24
|
+
' - ' +
|
|
25
|
+
(props['aria-label'] ?? '')
|
|
26
|
+
}
|
|
27
|
+
onKeyDown={onKeyDown}
|
|
28
|
+
onClick={(e) => {
|
|
29
|
+
e.preventDefault();
|
|
30
|
+
e.stopPropagation();
|
|
31
|
+
}}
|
|
32
|
+
tabIndex={0}
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export default SingleSlideWrapper;
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { useRef, useEffect } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
NextArrow,
|
|
4
|
+
PrevArrow,
|
|
5
|
+
} from 'design-comuni-plone-theme/components/ItaliaTheme';
|
|
6
|
+
|
|
7
|
+
export const useSlider = (userAutoplay, setUserAutoplay, block_id) => {
|
|
8
|
+
const slider = useRef(null);
|
|
9
|
+
const sliderContainer = document.getElementById('outside-slider-' + block_id);
|
|
10
|
+
const sliderElementSelector = `#slider_${block_id}`;
|
|
11
|
+
const sliderElement = document.querySelector(sliderElementSelector);
|
|
12
|
+
const onIntersection = (entries, opt) => {
|
|
13
|
+
entries.forEach((entry) =>
|
|
14
|
+
entry.target.classList.toggle('visible', entry.isIntersecting),
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
const observer = new IntersectionObserver(onIntersection, {
|
|
18
|
+
root: null,
|
|
19
|
+
threshold: 0.5,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const setAutoplay = (a) => {
|
|
23
|
+
setUserAutoplay(a);
|
|
24
|
+
slider.current.slickPause(a);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
if (sliderContainer) observer.observe(sliderContainer);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
return () => observer.disconnect();
|
|
30
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
31
|
+
}, []);
|
|
32
|
+
|
|
33
|
+
const focusSlide = (slideIndex) => {
|
|
34
|
+
if (!sliderElement) return;
|
|
35
|
+
const sliderIsVisible = sliderContainer?.classList?.contains('visible');
|
|
36
|
+
|
|
37
|
+
if (!sliderIsVisible) {
|
|
38
|
+
setAutoplay(false);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const slide = document.querySelector(
|
|
43
|
+
`${sliderElementSelector} .slick-slide[data-index="${slideIndex}"] .it-single-slide-wrapper`,
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
if (userAutoplay && !slide) return;
|
|
47
|
+
|
|
48
|
+
if (!slide || document.activeElement === slide) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//se c'è l'autoplay e non ho il focus sullo, non faccio il focus sulle slide per non perdere il focus sull'elemento della pagina su cui sono e che sta fuori dallo slider.
|
|
53
|
+
const focusedSliderElement = Array.from(
|
|
54
|
+
document.querySelectorAll(sliderElementSelector),
|
|
55
|
+
).some((node) => node.contains(document.activeElement));
|
|
56
|
+
|
|
57
|
+
if (focusedSliderElement) {
|
|
58
|
+
slide.focus();
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const visibleSlide = (selector) => {
|
|
63
|
+
// Needed to deal with react-slick duplicating a lot of slides
|
|
64
|
+
// when used in infinite mode. It's an useless and counterproductive
|
|
65
|
+
// thing to do on their part, there are multiple issues opened.
|
|
66
|
+
// The lib is not actually mantained so...
|
|
67
|
+
|
|
68
|
+
return Array.from(document.querySelectorAll(selector)).find((e) => {
|
|
69
|
+
const slick_slide = e.closest('.slick-slide');
|
|
70
|
+
return !slick_slide.classList.contains('slick-cloned');
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const SliderNextArrow = (props) => {
|
|
75
|
+
// Custom handling of focus for a11y
|
|
76
|
+
const { className, style, onClick, currentSlide } = props;
|
|
77
|
+
const handleClick = (options) => {
|
|
78
|
+
onClick(options, false);
|
|
79
|
+
};
|
|
80
|
+
const handleKeyboardUsers = (e) => {
|
|
81
|
+
if (e.key === 'Tab' && e.shiftKey) {
|
|
82
|
+
e.stopPropagation();
|
|
83
|
+
e.preventDefault();
|
|
84
|
+
setAutoplay(false);
|
|
85
|
+
const slide = visibleSlide(
|
|
86
|
+
`${sliderElementSelector} .slick-slide[data-index="${currentSlide}"]`,
|
|
87
|
+
);
|
|
88
|
+
slide && slide.focus();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<NextArrow
|
|
94
|
+
className={className}
|
|
95
|
+
style={{ ...style }}
|
|
96
|
+
onClick={handleClick}
|
|
97
|
+
onKeyDown={handleKeyboardUsers}
|
|
98
|
+
id={'sliderNextArrow_' + block_id}
|
|
99
|
+
/>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const SliderPrevArrow = (props) => {
|
|
104
|
+
// Custom handling of focus for a11y
|
|
105
|
+
const { className, style, onClick, currentSlide, slideCount } = props;
|
|
106
|
+
const handleClick = (options) => {
|
|
107
|
+
onClick(options, false);
|
|
108
|
+
};
|
|
109
|
+
const handleKeyboardUsers = (e) => {
|
|
110
|
+
if (e.key === 'Tab' && !e.shiftKey) {
|
|
111
|
+
e.stopPropagation();
|
|
112
|
+
e.preventDefault();
|
|
113
|
+
|
|
114
|
+
setAutoplay(false);
|
|
115
|
+
|
|
116
|
+
if (currentSlide < slideCount) {
|
|
117
|
+
const slide = visibleSlide(
|
|
118
|
+
`${sliderElementSelector} .slick-slide[data-index="${currentSlide}"]`,
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
slide && slide.focus();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
return (
|
|
126
|
+
<PrevArrow
|
|
127
|
+
className={className}
|
|
128
|
+
style={{ ...style }}
|
|
129
|
+
onClick={handleClick}
|
|
130
|
+
onKeyDown={handleKeyboardUsers}
|
|
131
|
+
id={'sliderPrevArrow_' + block_id}
|
|
132
|
+
/>
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const handleSlideKeydown = (index, prevIndex, nextIndex) => (e) => {
|
|
137
|
+
const { key, shiftKey } = e;
|
|
138
|
+
|
|
139
|
+
setAutoplay(false);
|
|
140
|
+
|
|
141
|
+
if (key === 'Tab') {
|
|
142
|
+
const slide_selector = `#slider_${block_id} .slick-slide[data-index="${index}"]`;
|
|
143
|
+
|
|
144
|
+
const focusableSlideElements = document.querySelectorAll(
|
|
145
|
+
`${slide_selector} a, ${slide_selector} button, ${slide_selector} [tabindex="0"]`,
|
|
146
|
+
);
|
|
147
|
+
const isFirstSlideFocusableElement =
|
|
148
|
+
e.target === focusableSlideElements[0];
|
|
149
|
+
const isLastSlideFocusableElement =
|
|
150
|
+
e.target === focusableSlideElements[focusableSlideElements.length - 1];
|
|
151
|
+
|
|
152
|
+
if (
|
|
153
|
+
(isFirstSlideFocusableElement && shiftKey) ||
|
|
154
|
+
(isLastSlideFocusableElement && !shiftKey)
|
|
155
|
+
) {
|
|
156
|
+
e.preventDefault();
|
|
157
|
+
e.stopPropagation();
|
|
158
|
+
//shift+tab ed è il primo elemento focusabile nella slide, oppure tab ed è l'ultimo elemento focusabile nella slide
|
|
159
|
+
//go to next/prev slide or to next/prev button.
|
|
160
|
+
} else {
|
|
161
|
+
return; //continue doing default bhv of Tab key, to focus next focusable element inside slide.
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (shiftKey) {
|
|
165
|
+
if (prevIndex != null) {
|
|
166
|
+
slider.current.slickGoTo(prevIndex);
|
|
167
|
+
} else {
|
|
168
|
+
document.getElementById('sliderPrevArrow_' + block_id).focus();
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
if (nextIndex != null) {
|
|
172
|
+
slider.current.slickGoTo(nextIndex);
|
|
173
|
+
} else {
|
|
174
|
+
document.getElementById('sliderNextArrow_' + block_id).focus();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (key === 'ArrowRight') {
|
|
180
|
+
if (nextIndex != null) {
|
|
181
|
+
e.preventDefault();
|
|
182
|
+
e.stopPropagation();
|
|
183
|
+
slider.current.slickGoTo(nextIndex);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
if (key === 'ArrowLeft') {
|
|
187
|
+
if (prevIndex != null) {
|
|
188
|
+
e.preventDefault();
|
|
189
|
+
e.stopPropagation();
|
|
190
|
+
slider.current.slickGoTo(prevIndex);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
slider,
|
|
197
|
+
focusSlide,
|
|
198
|
+
visibleSlide,
|
|
199
|
+
SliderNextArrow,
|
|
200
|
+
SliderPrevArrow,
|
|
201
|
+
handleSlideKeydown,
|
|
202
|
+
};
|
|
203
|
+
};
|
|
@@ -49,11 +49,12 @@ const ContactLink = ({ tel, fax, email, label = true, strong = false }) => {
|
|
|
49
49
|
function replaceString(str, type) {
|
|
50
50
|
const regex = type === 'mailto' ? emailRegex : phoneRegex;
|
|
51
51
|
return str.split(regex).reduce((acc, substr, i) => {
|
|
52
|
-
if (substr.trim()
|
|
52
|
+
if (substr.trim() === '') return acc;
|
|
53
|
+
|
|
53
54
|
return [
|
|
54
55
|
...acc,
|
|
55
56
|
acc.length === 0 ? '' : ' ',
|
|
56
|
-
|
|
57
|
+
regex.test(substr) ? (
|
|
57
58
|
<a
|
|
58
59
|
key={`${type}-${i}`}
|
|
59
60
|
href={`${type}:${substr
|
|
@@ -67,6 +67,14 @@ const Dates = ({ content, show_image, moment: momentlib, rrule }) => {
|
|
|
67
67
|
const end = viewDate(intl.locale, content.end);
|
|
68
68
|
const openEnd = content?.open_end;
|
|
69
69
|
const wholeDay = content?.whole_day;
|
|
70
|
+
const rdates = rruleSet?.rdates() ?? [];
|
|
71
|
+
const exdates = rruleSet?.exdates() ?? [];
|
|
72
|
+
const additionalDates = rdates.reduce((acc, curr) => {
|
|
73
|
+
const isExdate = exdates.some((b) => b.toString() === curr.toString());
|
|
74
|
+
if (!isExdate) {
|
|
75
|
+
return [...acc, curr];
|
|
76
|
+
} else return acc;
|
|
77
|
+
}, []);
|
|
70
78
|
|
|
71
79
|
return content ? (
|
|
72
80
|
<>
|
|
@@ -134,20 +142,20 @@ const Dates = ({ content, show_image, moment: momentlib, rrule }) => {
|
|
|
134
142
|
<strong>{recurrenceText}</strong>
|
|
135
143
|
</div>
|
|
136
144
|
)}
|
|
137
|
-
{
|
|
145
|
+
{additionalDates.length > 0 && (
|
|
138
146
|
<div className="mt-4">
|
|
139
147
|
<h5>{intl.formatMessage(messages.additional_dates)}</h5>
|
|
140
|
-
{
|
|
148
|
+
{additionalDates.map((additionalDate) => (
|
|
141
149
|
<div className="font-serif">
|
|
142
150
|
{viewDate(intl.locale, additionalDate, 'dddd DD MMMM YYYY')}
|
|
143
151
|
</div>
|
|
144
152
|
))}
|
|
145
153
|
</div>
|
|
146
154
|
)}
|
|
147
|
-
{
|
|
155
|
+
{exdates.length > 0 && (
|
|
148
156
|
<div className="mt-4">
|
|
149
157
|
<h5>{intl.formatMessage(messages.excluded_dates)}</h5>
|
|
150
|
-
{
|
|
158
|
+
{exdates.map((exDate) => (
|
|
151
159
|
<div className="font-serif">
|
|
152
160
|
{viewDate(intl.locale, exDate, 'dddd DD MMMM YYYY')}
|
|
153
161
|
</div>
|
|
@@ -8,7 +8,11 @@ import { resetSearchContent, searchContent } from '@plone/volto/actions';
|
|
|
8
8
|
import { useDispatch, useSelector } from 'react-redux';
|
|
9
9
|
|
|
10
10
|
import EmbeddedVideo from './EmbeddedVideo';
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
GalleryPreview,
|
|
13
|
+
SingleSlideWrapper,
|
|
14
|
+
CarouselWrapper,
|
|
15
|
+
} from 'design-comuni-plone-theme/components/ItaliaTheme';
|
|
12
16
|
import PropTypes from 'prop-types';
|
|
13
17
|
import { contentFolderHasItems } from 'design-comuni-plone-theme/helpers';
|
|
14
18
|
import { UniversalLink } from '@plone/volto/components';
|
|
@@ -146,10 +150,10 @@ const Gallery = ({
|
|
|
146
150
|
{title_type === 'h5' && <h5 id={title_id}>{gallery_title}</h5>}
|
|
147
151
|
</div>
|
|
148
152
|
</div>
|
|
149
|
-
<
|
|
153
|
+
<CarouselWrapper className="it-card-bg">
|
|
150
154
|
<Slider {...getSettings(images.length)}>
|
|
151
155
|
{images.map((item, i) => (
|
|
152
|
-
<
|
|
156
|
+
<SingleSlideWrapper key={item['@id']} index={i}>
|
|
153
157
|
<figure>
|
|
154
158
|
<UniversalLink
|
|
155
159
|
item={item}
|
|
@@ -181,7 +185,7 @@ const Gallery = ({
|
|
|
181
185
|
{item.title}
|
|
182
186
|
</figcaption>
|
|
183
187
|
</figure>
|
|
184
|
-
</
|
|
188
|
+
</SingleSlideWrapper>
|
|
185
189
|
))}
|
|
186
190
|
</Slider>
|
|
187
191
|
|
|
@@ -191,7 +195,7 @@ const Gallery = ({
|
|
|
191
195
|
setViewIndex={setViewImageIndex}
|
|
192
196
|
items={images}
|
|
193
197
|
/>
|
|
194
|
-
</
|
|
198
|
+
</CarouselWrapper>
|
|
195
199
|
</div>
|
|
196
200
|
</div>
|
|
197
201
|
) : null}
|
|
@@ -219,20 +223,20 @@ const Gallery = ({
|
|
|
219
223
|
</div>
|
|
220
224
|
</div>
|
|
221
225
|
)}
|
|
222
|
-
<
|
|
226
|
+
<CarouselWrapper className="it-card-bg">
|
|
223
227
|
<Slider {...video_settings}>
|
|
224
228
|
{videos.map((item, i) => (
|
|
225
|
-
<
|
|
229
|
+
<SingleSlideWrapper key={item['@id']} index={i}>
|
|
226
230
|
<EmbeddedVideo
|
|
227
231
|
title={item.title}
|
|
228
232
|
key={item['@id'] ?? i}
|
|
229
233
|
id={item['@id'] ?? i}
|
|
230
234
|
video_url={item?.remoteUrl || item}
|
|
231
235
|
/>
|
|
232
|
-
</
|
|
236
|
+
</SingleSlideWrapper>
|
|
233
237
|
))}
|
|
234
238
|
</Slider>
|
|
235
|
-
</
|
|
239
|
+
</CarouselWrapper>
|
|
236
240
|
</div>
|
|
237
241
|
</div>
|
|
238
242
|
) : null}
|
|
@@ -50,7 +50,7 @@ const Metadata = ({
|
|
|
50
50
|
{children}
|
|
51
51
|
<p className="font-serif mb-0 mt-4 last-modified">
|
|
52
52
|
<strong>{intl.formatMessage(messages.modified)}:</strong>{' '}
|
|
53
|
-
{viewDate(intl.locale, content.modified, 'DD-MM-Y, HH:
|
|
53
|
+
{viewDate(intl.locale, content.modified, 'DD-MM-Y, HH:mm')}
|
|
54
54
|
</p>
|
|
55
55
|
{content.rights && (
|
|
56
56
|
<>
|
|
@@ -16,6 +16,13 @@ const messages = defineMessages({
|
|
|
16
16
|
defaultMessage: 'Blocco sconosciuto',
|
|
17
17
|
},
|
|
18
18
|
});
|
|
19
|
+
const Wrapper = ({ block, id, children }) => {
|
|
20
|
+
return block['@type'] === 'listing' && block.variation === 'slider' ? (
|
|
21
|
+
<div id={`outside-slider-${id}`}>{children}</div>
|
|
22
|
+
) : (
|
|
23
|
+
<>{children}</>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
19
26
|
/**
|
|
20
27
|
* RenderBlocks view component class.
|
|
21
28
|
* @function RenderBlocks
|
|
@@ -57,15 +64,21 @@ const RenderBlocks = ({
|
|
|
57
64
|
{map(items, (block) => {
|
|
58
65
|
const blockType = blockContent[blocksFieldname]?.[block]?.['@type'];
|
|
59
66
|
const Block = config.blocks.blocksConfig[blockType]?.['view'] || null;
|
|
67
|
+
|
|
60
68
|
if (Block != null) {
|
|
61
69
|
return (
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
<Wrapper block={blockContent[blocksFieldname]?.[block]} id={block}>
|
|
71
|
+
<Block
|
|
72
|
+
key={block}
|
|
73
|
+
id={block}
|
|
74
|
+
properties={content ?? data}
|
|
75
|
+
data={{
|
|
76
|
+
...blockContent[blocksFieldname][block],
|
|
77
|
+
block: block,
|
|
78
|
+
}}
|
|
79
|
+
path={getBaseUrl(location?.pathname || '')}
|
|
80
|
+
/>
|
|
81
|
+
</Wrapper>
|
|
69
82
|
);
|
|
70
83
|
} else {
|
|
71
84
|
return (
|
|
@@ -42,11 +42,15 @@ const DocumentoDescrizione = ({ content }) => {
|
|
|
42
42
|
return richTextHasContent(content.descrizione_estesa) ||
|
|
43
43
|
contentFolderHasItems(content, 'multimedia') ||
|
|
44
44
|
content.autori?.length > 0 ||
|
|
45
|
-
content.
|
|
45
|
+
content.identificativo ||
|
|
46
|
+
content.licenza_distribuzione?.length > 0 ||
|
|
47
|
+
content.tipologia_licenze?.title ||
|
|
48
|
+
content.tipologia_documento?.length > 0 ||
|
|
49
|
+
content.tipologia_documenti_albopretorio?.title ? (
|
|
46
50
|
<RichTextSection
|
|
47
51
|
tag_id={'text-body'}
|
|
48
52
|
title={intl.formatMessage(messages.descrizione)}
|
|
49
|
-
show_title={
|
|
53
|
+
show_title={richTextHasContent(content.descrizione_estesa)}
|
|
50
54
|
data={content.descrizione_estesa}
|
|
51
55
|
>
|
|
52
56
|
{contentFolderHasItems(content, 'multimedia') && (
|
|
@@ -61,7 +65,7 @@ const DocumentoDescrizione = ({ content }) => {
|
|
|
61
65
|
)}
|
|
62
66
|
{content.identificativo && (
|
|
63
67
|
<div className="mt-5">
|
|
64
|
-
<h4>{intl.formatMessage(messages.identificativo)}</
|
|
68
|
+
<h3 className="h4">{intl.formatMessage(messages.identificativo)}</h3>
|
|
65
69
|
<p className="font-serif">{content.identificativo}</p>
|
|
66
70
|
</div>
|
|
67
71
|
)}
|
|
@@ -71,7 +75,9 @@ const DocumentoDescrizione = ({ content }) => {
|
|
|
71
75
|
{(content.licenza_distribuzione?.length > 0 ||
|
|
72
76
|
content.tipologia_licenze?.title) && (
|
|
73
77
|
<div className="mt-5">
|
|
74
|
-
<h4>
|
|
78
|
+
<h3 className="h4">
|
|
79
|
+
{intl.formatMessage(messages.licenza_distribuzione)}
|
|
80
|
+
</h3>
|
|
75
81
|
{content.licenza_distribuzione?.length > 0 && (
|
|
76
82
|
<p className="font-serif">{content.licenza_distribuzione}</p>
|
|
77
83
|
)}
|
|
@@ -82,7 +88,9 @@ const DocumentoDescrizione = ({ content }) => {
|
|
|
82
88
|
)}
|
|
83
89
|
{content.tipologia_documento?.length > 0 && (
|
|
84
90
|
<div className="mt-5">
|
|
85
|
-
<h4>
|
|
91
|
+
<h3 className="h4">
|
|
92
|
+
{intl.formatMessage(messages.tipologia_documento)}
|
|
93
|
+
</h3>
|
|
86
94
|
{content.tipologia_documento.map((tipo) => (
|
|
87
95
|
<p key={tipo.token} className="font-serif">
|
|
88
96
|
{tipo.title}
|
|
@@ -92,9 +100,9 @@ const DocumentoDescrizione = ({ content }) => {
|
|
|
92
100
|
)}
|
|
93
101
|
{content.tipologia_documenti_albopretorio?.title && (
|
|
94
102
|
<div className="mt-5">
|
|
95
|
-
<h4>
|
|
103
|
+
<h3 className="h4">
|
|
96
104
|
{intl.formatMessage(messages.tipologia_documenti_albopretorio)}
|
|
97
|
-
</
|
|
105
|
+
</h3>
|
|
98
106
|
<p className="font-serif">
|
|
99
107
|
{content.tipologia_documenti_albopretorio?.title}
|
|
100
108
|
</p>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
2
3
|
import { Card, CardBody } from 'design-react-kit';
|
|
3
4
|
import {
|
|
4
5
|
RichText,
|
|
@@ -6,12 +7,22 @@ import {
|
|
|
6
7
|
ContactLink,
|
|
7
8
|
} from 'design-comuni-plone-theme/components/ItaliaTheme/View';
|
|
8
9
|
|
|
10
|
+
const messages = defineMessages({
|
|
11
|
+
organizzatore: {
|
|
12
|
+
id: 'organizzatore',
|
|
13
|
+
defaultMessage: 'Organizzatore',
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
9
17
|
const EventoContattiOrganizzatoreEsterno = ({ content }) => {
|
|
18
|
+
const intl = useIntl();
|
|
19
|
+
|
|
10
20
|
return richTextHasContent(content?.organizzato_da_esterno) ||
|
|
11
21
|
content?.telefono ||
|
|
12
22
|
content?.email ||
|
|
13
23
|
content?.fax ? (
|
|
14
|
-
<div className="mb-5">
|
|
24
|
+
<div className="mb-5 mt-3">
|
|
25
|
+
<h3 className="h5">{intl.formatMessage(messages.organizzatore)}</h3>
|
|
15
26
|
<Card
|
|
16
27
|
className="card card-teaser rounded shadow mt-3"
|
|
17
28
|
noWrapper={true}
|
|
@@ -19,14 +19,14 @@ const EventoLuoghi = ({ content }) => {
|
|
|
19
19
|
const intl = useIntl();
|
|
20
20
|
|
|
21
21
|
return content?.luoghi_correlati?.length > 0 ||
|
|
22
|
-
content?.nome_sede > 0 ||
|
|
23
|
-
content?.street > 0 ||
|
|
22
|
+
content?.nome_sede?.length > 0 ||
|
|
23
|
+
content?.street?.length > 0 ||
|
|
24
24
|
(content?.geolocation?.latitude && content?.geolocation?.longitude) ||
|
|
25
|
-
content?.zip_code ||
|
|
26
|
-
content?.city ||
|
|
27
|
-
content?.quartiere ||
|
|
28
|
-
content?.circoscrizione ||
|
|
29
|
-
content?.country ? (
|
|
25
|
+
content?.zip_code?.length > 0 ||
|
|
26
|
+
content?.city?.length > 0 ||
|
|
27
|
+
content?.quartiere?.length > 0 ||
|
|
28
|
+
content?.circoscrizione?.length > 0 ||
|
|
29
|
+
content?.country?.length > 0 ? (
|
|
30
30
|
<RichTextSection
|
|
31
31
|
tag_id="luoghi"
|
|
32
32
|
title={intl.formatMessage(messages.luoghi)}
|
|
@@ -29,7 +29,7 @@ const UOServices = ({ content }) => {
|
|
|
29
29
|
<h2 id={`header-servizi_offerti`} className="mb-3 h4">
|
|
30
30
|
{intl.formatMessage(messages.servizi_offerti)}
|
|
31
31
|
</h2>
|
|
32
|
-
<Row className="card-wrapper card-teaser-wrapper">
|
|
32
|
+
<Row className="card-wrapper card-teaser-wrapper align-items-stretch">
|
|
33
33
|
{content?.servizi_offerti?.map((servizio, i) => (
|
|
34
34
|
<Col xs="12" lg="6">
|
|
35
35
|
<Card className="shadow rounded card-big-io-comune p-3 my-3">
|
|
@@ -2235,7 +2235,7 @@ test('expect to render fields in page', async () => {
|
|
|
2235
2235
|
);
|
|
2236
2236
|
|
|
2237
2237
|
expect(screen.getByText(/Ultimo aggiornamento/i)).toBeInTheDocument();
|
|
2238
|
-
expect(screen.getByText(/15-03-2023, 15:
|
|
2238
|
+
expect(screen.getByText(/15-03-2023, 15:56/i)).toBeInTheDocument();
|
|
2239
2239
|
});
|
|
2240
2240
|
|
|
2241
2241
|
test('todo', () => {
|
|
@@ -83,11 +83,16 @@ export CardCalendar from 'design-comuni-plone-theme/components/ItaliaTheme/Block
|
|
|
83
83
|
export ListingCategory from 'design-comuni-plone-theme/components/ItaliaTheme/Blocks/Listing/Commons/ListingCategory';
|
|
84
84
|
export ListingText from 'design-comuni-plone-theme/components/ItaliaTheme/Blocks/Listing/Commons/ListingText';
|
|
85
85
|
export ListingLinkMore from 'design-comuni-plone-theme/components/ItaliaTheme/Blocks/Listing/Commons/ListingLinkMore';
|
|
86
|
-
|
|
87
|
-
export PrevArrow from 'design-comuni-plone-theme/components/ItaliaTheme/Blocks/Listing/Commons/PrevArrow';
|
|
86
|
+
|
|
88
87
|
export ListingImage, {
|
|
89
88
|
getListingImageBackground,
|
|
90
89
|
} from 'design-comuni-plone-theme/components/ItaliaTheme/Blocks/Listing/Commons/ListingImage';
|
|
91
90
|
|
|
91
|
+
/*Slider*/
|
|
92
|
+
export SingleSlideWrapper from 'design-comuni-plone-theme/components/ItaliaTheme/Slider/SingleSlideWrapper';
|
|
93
|
+
export CarouselWrapper from 'design-comuni-plone-theme/components/ItaliaTheme/Slider/CarouselWrapper';
|
|
94
|
+
export ButtonPlayPause from 'design-comuni-plone-theme/components/ItaliaTheme/Slider/ButtonPlayPause';
|
|
95
|
+
export NextArrow from 'design-comuni-plone-theme/components/ItaliaTheme/Slider/NextArrow';
|
|
96
|
+
export PrevArrow from 'design-comuni-plone-theme/components/ItaliaTheme/Slider/PrevArrow';
|
|
92
97
|
/********* ERROR PAGES ********* */
|
|
93
98
|
export Unauthorized from 'design-comuni-plone-theme/components/ItaliaTheme/Unauthorized/Unauthorized';
|