design-comuni-plone-theme 11.2.1 → 11.3.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/CHANGELOG.md +20 -0
- package/RELEASE.md +12 -0
- package/locales/de/LC_MESSAGES/volto.po +5 -5
- package/locales/en/LC_MESSAGES/volto.po +5 -5
- package/locales/es/LC_MESSAGES/volto.po +5 -5
- package/locales/fr/LC_MESSAGES/volto.po +5 -5
- package/locales/it/LC_MESSAGES/volto.po +5 -5
- package/locales/volto.pot +6 -6
- package/package.json +2 -2
- package/publiccode.yml +2 -2
- package/src/components/ItaliaTheme/Blocks/Calendar/Item.jsx +6 -1
- package/src/components/ItaliaTheme/View/Commons/ContactsCard.jsx +4 -1
- package/src/components/ItaliaTheme/View/PuntoDiContattoView/PuntoDiContattoView.jsx +2 -7
- package/src/components/ItaliaTheme/manage/Widgets/LuoghiCorrelatiEventoWidget.jsx +64 -0
- package/src/config/Widgets/widgets.js +2 -0
- package/src/customizations/volto/components/manage/Widgets/SelectWidget.jsx +314 -0
- package/src/helpers/FormValidation/FormValidationHelpers.js +98 -0
- package/src/theme/ItaliaTheme/Subsites/ItaliaTheme/Blocks/_searchSections.scss +15 -2
- package/src/theme/ItaliaTheme/Widgets/_luoghiCorrelatiEventoWidget.scss +15 -0
- package/src/theme/site.scss +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
+
## [11.3.0](https://github.com/redturtle/design-comuni-plone-theme/compare/v11.2.1...v11.3.0) (2024-01-16)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add new widget for event luoghi_correlati with custom form validation ([#485](https://github.com/redturtle/design-comuni-plone-theme/issues/485)) ([bea6407](https://github.com/redturtle/design-comuni-plone-theme/commit/bea64070b1cfe86781fd99c15cb492f34f95e4ff))
|
|
9
|
+
* aggiunta descrizione nei punti di contatto ([#483](https://github.com/redturtle/design-comuni-plone-theme/issues/483)) ([3528f15](https://github.com/redturtle/design-comuni-plone-theme/commit/3528f15e902dfa58239be7ad309817e6c16556f7))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* removed date filters previously set with getCalendarResults ([#487](https://github.com/redturtle/design-comuni-plone-theme/issues/487)) ([42aa789](https://github.com/redturtle/design-comuni-plone-theme/commit/42aa7898d5dfdee8017df5ec408cff326bba4d1f))
|
|
15
|
+
* selectors for search block styles and added styles for dates ([#486](https://github.com/redturtle/design-comuni-plone-theme/issues/486)) ([b46fc68](https://github.com/redturtle/design-comuni-plone-theme/commit/b46fc6895dfddb9f6bd8d9a37569b8b56f3ccde5))
|
|
16
|
+
* upgraded volto-dropdownmenu to 4.1.1 ([d3918e6](https://github.com/redturtle/design-comuni-plone-theme/commit/d3918e63c820ebe73835a7fdd335cd44d0e82f9f))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Documentation
|
|
20
|
+
|
|
21
|
+
* updated publiccode and release log ([e6ea0d5](https://github.com/redturtle/design-comuni-plone-theme/commit/e6ea0d57cf6b9780989a01bfb87974ad34eceee6))
|
|
22
|
+
|
|
3
23
|
## [11.2.1](https://github.com/redturtle/design-comuni-plone-theme/compare/v11.2.0...v11.2.1) (2024-01-15)
|
|
4
24
|
|
|
5
25
|
|
package/RELEASE.md
CHANGED
|
@@ -41,6 +41,18 @@
|
|
|
41
41
|
- ...
|
|
42
42
|
-->
|
|
43
43
|
|
|
44
|
+
## Versione 11.3.0 (16/01/2024)
|
|
45
|
+
|
|
46
|
+
### Novità
|
|
47
|
+
|
|
48
|
+
- Aggiunto un campo descrizione nei punti di contatto per aiutare nella disambiguazione.
|
|
49
|
+
- Ora per gli eventi è obbligatorio inserire il campo "Luoghi correlati" oppure compilare i campi dell'indirizzo.
|
|
50
|
+
|
|
51
|
+
### Fix
|
|
52
|
+
|
|
53
|
+
- Migliorati gli stili per i sottositi.
|
|
54
|
+
- Risolto un problema con i filtri per data nel blocco Calendario.
|
|
55
|
+
|
|
44
56
|
## Versione 11.2.1 (15/01/2024)
|
|
45
57
|
|
|
46
58
|
### Migliorie
|
|
@@ -2251,11 +2251,6 @@ msgstr ""
|
|
|
2251
2251
|
msgid "iter_del_procedimento"
|
|
2252
2252
|
msgstr ""
|
|
2253
2253
|
|
|
2254
|
-
#: components/ItaliaTheme/View/PuntoDiContattoView/PuntoDiContattoView
|
|
2255
|
-
# defaultMessage: {value}:
|
|
2256
|
-
msgid "label"
|
|
2257
|
-
msgstr ""
|
|
2258
|
-
|
|
2259
2254
|
#: components/ItaliaTheme/View/UOView/UOStructure
|
|
2260
2255
|
# defaultMessage: Servizi o uffici di riferimento
|
|
2261
2256
|
msgid "legami_altre_strutture"
|
|
@@ -2420,6 +2415,11 @@ msgstr ""
|
|
|
2420
2415
|
msgid "luoghi_correlati"
|
|
2421
2416
|
msgstr ""
|
|
2422
2417
|
|
|
2418
|
+
#: components/ItaliaTheme/manage/Widgets/LuoghiCorrelatiEventoWidget
|
|
2419
|
+
# defaultMessage: Luogo dell'evento
|
|
2420
|
+
msgid "luoghi_correlati_evento_widget_title"
|
|
2421
|
+
msgstr ""
|
|
2422
|
+
|
|
2423
2423
|
#: components/ItaliaTheme/View/NewsItemView/NewsItemLuoghiCorrelati
|
|
2424
2424
|
# defaultMessage: Luoghi
|
|
2425
2425
|
msgid "luoghi_notizia"
|
|
@@ -2236,11 +2236,6 @@ msgstr ""
|
|
|
2236
2236
|
msgid "iter_del_procedimento"
|
|
2237
2237
|
msgstr "Procedure of the procedure"
|
|
2238
2238
|
|
|
2239
|
-
#: components/ItaliaTheme/View/PuntoDiContattoView/PuntoDiContattoView
|
|
2240
|
-
# defaultMessage: {value}:
|
|
2241
|
-
msgid "label"
|
|
2242
|
-
msgstr ""
|
|
2243
|
-
|
|
2244
2239
|
#: components/ItaliaTheme/View/UOView/UOStructure
|
|
2245
2240
|
# defaultMessage: Servizi o uffici di riferimento
|
|
2246
2241
|
msgid "legami_altre_strutture"
|
|
@@ -2405,6 +2400,11 @@ msgstr ""
|
|
|
2405
2400
|
msgid "luoghi_correlati"
|
|
2406
2401
|
msgstr ""
|
|
2407
2402
|
|
|
2403
|
+
#: components/ItaliaTheme/manage/Widgets/LuoghiCorrelatiEventoWidget
|
|
2404
|
+
# defaultMessage: Luogo dell'evento
|
|
2405
|
+
msgid "luoghi_correlati_evento_widget_title"
|
|
2406
|
+
msgstr "Event location"
|
|
2407
|
+
|
|
2408
2408
|
#: components/ItaliaTheme/View/NewsItemView/NewsItemLuoghiCorrelati
|
|
2409
2409
|
# defaultMessage: Luoghi
|
|
2410
2410
|
msgid "luoghi_notizia"
|
|
@@ -2245,11 +2245,6 @@ msgstr "Inserta un filtro del menú lateral para ver los resultados relacionados
|
|
|
2245
2245
|
msgid "iter_del_procedimento"
|
|
2246
2246
|
msgstr "Procedimiento"
|
|
2247
2247
|
|
|
2248
|
-
#: components/ItaliaTheme/View/PuntoDiContattoView/PuntoDiContattoView
|
|
2249
|
-
# defaultMessage: {value}:
|
|
2250
|
-
msgid "label"
|
|
2251
|
-
msgstr ""
|
|
2252
|
-
|
|
2253
2248
|
#: components/ItaliaTheme/View/UOView/UOStructure
|
|
2254
2249
|
# defaultMessage: Servizi o uffici di riferimento
|
|
2255
2250
|
msgid "legami_altre_strutture"
|
|
@@ -2414,6 +2409,11 @@ msgstr ""
|
|
|
2414
2409
|
msgid "luoghi_correlati"
|
|
2415
2410
|
msgstr ""
|
|
2416
2411
|
|
|
2412
|
+
#: components/ItaliaTheme/manage/Widgets/LuoghiCorrelatiEventoWidget
|
|
2413
|
+
# defaultMessage: Luogo dell'evento
|
|
2414
|
+
msgid "luoghi_correlati_evento_widget_title"
|
|
2415
|
+
msgstr ""
|
|
2416
|
+
|
|
2417
2417
|
#: components/ItaliaTheme/View/NewsItemView/NewsItemLuoghiCorrelati
|
|
2418
2418
|
# defaultMessage: Luoghi
|
|
2419
2419
|
msgid "luoghi_notizia"
|
|
@@ -2253,11 +2253,6 @@ msgstr ""
|
|
|
2253
2253
|
msgid "iter_del_procedimento"
|
|
2254
2254
|
msgstr "Procédure"
|
|
2255
2255
|
|
|
2256
|
-
#: components/ItaliaTheme/View/PuntoDiContattoView/PuntoDiContattoView
|
|
2257
|
-
# defaultMessage: {value}:
|
|
2258
|
-
msgid "label"
|
|
2259
|
-
msgstr ""
|
|
2260
|
-
|
|
2261
2256
|
#: components/ItaliaTheme/View/UOView/UOStructure
|
|
2262
2257
|
# defaultMessage: Servizi o uffici di riferimento
|
|
2263
2258
|
msgid "legami_altre_strutture"
|
|
@@ -2422,6 +2417,11 @@ msgstr ""
|
|
|
2422
2417
|
msgid "luoghi_correlati"
|
|
2423
2418
|
msgstr ""
|
|
2424
2419
|
|
|
2420
|
+
#: components/ItaliaTheme/manage/Widgets/LuoghiCorrelatiEventoWidget
|
|
2421
|
+
# defaultMessage: Luogo dell'evento
|
|
2422
|
+
msgid "luoghi_correlati_evento_widget_title"
|
|
2423
|
+
msgstr ""
|
|
2424
|
+
|
|
2425
2425
|
#: components/ItaliaTheme/View/NewsItemView/NewsItemLuoghiCorrelati
|
|
2426
2426
|
# defaultMessage: Luoghi
|
|
2427
2427
|
msgid "luoghi_notizia"
|
|
@@ -2236,11 +2236,6 @@ msgstr "Inserire un filtro dal menù laterale per visualizzare i relativi risult
|
|
|
2236
2236
|
msgid "iter_del_procedimento"
|
|
2237
2237
|
msgstr "Iter del procedimento"
|
|
2238
2238
|
|
|
2239
|
-
#: components/ItaliaTheme/View/PuntoDiContattoView/PuntoDiContattoView
|
|
2240
|
-
# defaultMessage: {value}:
|
|
2241
|
-
msgid "label"
|
|
2242
|
-
msgstr "{value}:"
|
|
2243
|
-
|
|
2244
2239
|
#: components/ItaliaTheme/View/UOView/UOStructure
|
|
2245
2240
|
# defaultMessage: Servizi o uffici di riferimento
|
|
2246
2241
|
msgid "legami_altre_strutture"
|
|
@@ -2405,6 +2400,11 @@ msgstr "Logo"
|
|
|
2405
2400
|
msgid "luoghi_correlati"
|
|
2406
2401
|
msgstr "Luoghi correlati"
|
|
2407
2402
|
|
|
2403
|
+
#: components/ItaliaTheme/manage/Widgets/LuoghiCorrelatiEventoWidget
|
|
2404
|
+
# defaultMessage: Luogo dell'evento
|
|
2405
|
+
msgid "luoghi_correlati_evento_widget_title"
|
|
2406
|
+
msgstr "Luogo dell'evento"
|
|
2407
|
+
|
|
2408
2408
|
#: components/ItaliaTheme/View/NewsItemView/NewsItemLuoghiCorrelati
|
|
2409
2409
|
# defaultMessage: Luoghi
|
|
2410
2410
|
msgid "luoghi_notizia"
|
package/locales/volto.pot
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
msgid ""
|
|
2
2
|
msgstr ""
|
|
3
3
|
"Project-Id-Version: Plone\n"
|
|
4
|
-
"POT-Creation-Date: 2024-01-
|
|
4
|
+
"POT-Creation-Date: 2024-01-15T16:05:18.583Z\n"
|
|
5
5
|
"Last-Translator: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
|
|
6
6
|
"Language-Team: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
|
|
7
7
|
"MIME-Version: 1.0\n"
|
|
@@ -2238,11 +2238,6 @@ msgstr ""
|
|
|
2238
2238
|
msgid "iter_del_procedimento"
|
|
2239
2239
|
msgstr ""
|
|
2240
2240
|
|
|
2241
|
-
#: components/ItaliaTheme/View/PuntoDiContattoView/PuntoDiContattoView
|
|
2242
|
-
# defaultMessage: {value}:
|
|
2243
|
-
msgid "label"
|
|
2244
|
-
msgstr ""
|
|
2245
|
-
|
|
2246
2241
|
#: components/ItaliaTheme/View/UOView/UOStructure
|
|
2247
2242
|
# defaultMessage: Servizi o uffici di riferimento
|
|
2248
2243
|
msgid "legami_altre_strutture"
|
|
@@ -2407,6 +2402,11 @@ msgstr ""
|
|
|
2407
2402
|
msgid "luoghi_correlati"
|
|
2408
2403
|
msgstr ""
|
|
2409
2404
|
|
|
2405
|
+
#: components/ItaliaTheme/manage/Widgets/LuoghiCorrelatiEventoWidget
|
|
2406
|
+
# defaultMessage: Luogo dell'evento
|
|
2407
|
+
msgid "luoghi_correlati_evento_widget_title"
|
|
2408
|
+
msgstr ""
|
|
2409
|
+
|
|
2410
2410
|
#: components/ItaliaTheme/View/NewsItemView/NewsItemLuoghiCorrelati
|
|
2411
2411
|
# defaultMessage: Luoghi
|
|
2412
2412
|
msgid "luoghi_notizia"
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "design-comuni-plone-theme",
|
|
3
3
|
"description": "Volto Theme for Italia design guidelines",
|
|
4
4
|
"license": "GPL-v3",
|
|
5
|
-
"version": "11.
|
|
5
|
+
"version": "11.3.0",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"volto-addon",
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
"typeface-titillium-web": "0.0.72",
|
|
144
144
|
"volto-blocks-widget": "3.1.0",
|
|
145
145
|
"volto-data-grid-widget": "2.3.1",
|
|
146
|
-
"volto-dropdownmenu": "4.1.
|
|
146
|
+
"volto-dropdownmenu": "4.1.1",
|
|
147
147
|
"volto-editablefooter": "5.0.3",
|
|
148
148
|
"volto-feedback": "0.1.5",
|
|
149
149
|
"volto-form-block": "3.1.0",
|
package/publiccode.yml
CHANGED
|
@@ -227,9 +227,9 @@ maintenance:
|
|
|
227
227
|
name: io-Comune - Il sito AgID per Comuni ed Enti Pubblici
|
|
228
228
|
platforms:
|
|
229
229
|
- web
|
|
230
|
-
releaseDate: '2024-01-
|
|
230
|
+
releaseDate: '2024-01-16'
|
|
231
231
|
softwareType: standalone/web
|
|
232
|
-
softwareVersion: 11.
|
|
232
|
+
softwareVersion: 11.3.0
|
|
233
233
|
url: 'https://github.com/italia/design-comuni-plone-theme'
|
|
234
234
|
usedBy:
|
|
235
235
|
- ASP Comuni Modenesi Area Nord
|
|
@@ -40,6 +40,11 @@ const Item = ({ day, path, query, inEditMode, data }) => {
|
|
|
40
40
|
const dayStart = _day.startOf('day').format('YYYY/MM/DD HH:mm');
|
|
41
41
|
const dayEnd = _day.endOf('day').format('YYYY/MM/DD HH:mm');
|
|
42
42
|
|
|
43
|
+
// remove date filters previously set for getCalendarResults in Body
|
|
44
|
+
const filtersWithoutDate = query.query.filter(
|
|
45
|
+
(el) => !el.o.includes('.date.'),
|
|
46
|
+
);
|
|
47
|
+
|
|
43
48
|
useDeepCompareEffect(() => {
|
|
44
49
|
dispatch(
|
|
45
50
|
getCalendarDayResults(
|
|
@@ -47,7 +52,7 @@ const Item = ({ day, path, query, inEditMode, data }) => {
|
|
|
47
52
|
{
|
|
48
53
|
...query,
|
|
49
54
|
query: [
|
|
50
|
-
...
|
|
55
|
+
...filtersWithoutDate,
|
|
51
56
|
{
|
|
52
57
|
i: 'start',
|
|
53
58
|
o: 'plone.app.querystring.operation.date.between',
|
|
@@ -55,7 +55,10 @@ const ContactsCard = ({ contact = {}, show_title = false, ...rest }) => {
|
|
|
55
55
|
<CardText>
|
|
56
56
|
{data?.value_punto_contatto.map((pdc, index) => (
|
|
57
57
|
<span key={index}>
|
|
58
|
-
<strong>
|
|
58
|
+
<strong>
|
|
59
|
+
{pdc.pdc_type}
|
|
60
|
+
{pdc.pdc_desc ? ` - ${pdc.pdc_desc}` : ''}:{' '}
|
|
61
|
+
</strong>
|
|
59
62
|
{renderPDCItemValue(pdc)}
|
|
60
63
|
</span>
|
|
61
64
|
)) ?? null}
|
|
@@ -69,10 +69,6 @@ const messages = defineMessages({
|
|
|
69
69
|
id: 'twitter',
|
|
70
70
|
defaultMessage: 'Twitter',
|
|
71
71
|
},
|
|
72
|
-
label: {
|
|
73
|
-
id: 'label',
|
|
74
|
-
defaultMessage: '{value}:',
|
|
75
|
-
},
|
|
76
72
|
contatti: {
|
|
77
73
|
id: 'contatti',
|
|
78
74
|
defaultMessage: 'Contatti',
|
|
@@ -112,9 +108,8 @@ const PuntoDiContattoView = (props) => {
|
|
|
112
108
|
<h5 className="h6">
|
|
113
109
|
{messages[pdc?.pdc_type] === undefined
|
|
114
110
|
? pdc?.pdc_type
|
|
115
|
-
: intl.formatMessage(messages.
|
|
116
|
-
|
|
117
|
-
})}
|
|
111
|
+
: intl.formatMessage(messages[pdc.pdc_type])}
|
|
112
|
+
{pdc?.pdc_desc && ` - ${pdc.pdc_desc}`}:
|
|
118
113
|
<span className="ms-1">{renderPDCItemValue(pdc)}</span>
|
|
119
114
|
</h5>
|
|
120
115
|
</div>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
2
|
+
import { Form } from 'semantic-ui-react';
|
|
3
|
+
import cx from 'classnames';
|
|
4
|
+
import config from '@plone/volto/registry';
|
|
5
|
+
|
|
6
|
+
const messages = defineMessages({
|
|
7
|
+
luoghi_correlati_evento_widget_title: {
|
|
8
|
+
id: 'luoghi_correlati_evento_widget_title',
|
|
9
|
+
defaultMessage: "Luogo dell'evento",
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const LuoghiCorrelatiEventoWidget = (props) => {
|
|
14
|
+
const Widget = config.widgets.factory['Relation List'];
|
|
15
|
+
const intl = useIntl();
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Form.Field
|
|
19
|
+
inline
|
|
20
|
+
required={false}
|
|
21
|
+
className={cx(
|
|
22
|
+
'help',
|
|
23
|
+
'luoghi-correlati-evento-widget',
|
|
24
|
+
`field-wrapper-${props.id}`,
|
|
25
|
+
props?.multilingual_options?.language_independent
|
|
26
|
+
? 'language-independent-field'
|
|
27
|
+
: null,
|
|
28
|
+
)}
|
|
29
|
+
>
|
|
30
|
+
<div className="introduction-helper-wrapper">
|
|
31
|
+
<h3 className="field-title">
|
|
32
|
+
{intl.formatMessage(messages.luoghi_correlati_evento_widget_title)}
|
|
33
|
+
</h3>
|
|
34
|
+
<p className="help">
|
|
35
|
+
Sezione obbligatoria secondo il{' '}
|
|
36
|
+
<a
|
|
37
|
+
target="_blank"
|
|
38
|
+
href="https://docs.italia.it/italia/designers-italia/design-comuni-docs/it/versione-corrente/conformita/buone-pratiche-asseverazione.html"
|
|
39
|
+
rel="noopener noreferrer"
|
|
40
|
+
>
|
|
41
|
+
documento di buone pratiche per l'asseverazione dei siti
|
|
42
|
+
</a>
|
|
43
|
+
. Per confermare la presenza in pagina della relativa sezione devono
|
|
44
|
+
essere presenti:
|
|
45
|
+
<ul>
|
|
46
|
+
<li>
|
|
47
|
+
«Luoghi correlati» che è un campo con un riferimento ad un oggetto
|
|
48
|
+
di tipo Luogo già presente sul sito. Se compilato, questo campo è
|
|
49
|
+
sufficiente per la validazione della compilazione del modulo.
|
|
50
|
+
</li>
|
|
51
|
+
<li>
|
|
52
|
+
Se non è possibile compilare il campo «Luoghi correlati», è
|
|
53
|
+
necessario compilare almeno i campi «Nome sede», «Via», «Città» e
|
|
54
|
+
«Nazione» sottostanti.
|
|
55
|
+
</li>
|
|
56
|
+
</ul>
|
|
57
|
+
</p>
|
|
58
|
+
</div>
|
|
59
|
+
<Widget {...props} />
|
|
60
|
+
</Form.Field>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export default LuoghiCorrelatiEventoWidget;
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
LocationFiltersWidget,
|
|
18
18
|
CanaleDigitaleWidget,
|
|
19
19
|
} from 'design-comuni-plone-theme/components/ItaliaTheme';
|
|
20
|
+
import LuoghiCorrelatiEventoWidget from 'design-comuni-plone-theme/components/ItaliaTheme/manage/Widgets/LuoghiCorrelatiEventoWidget';
|
|
20
21
|
|
|
21
22
|
const getItaliaWidgets = (config) => {
|
|
22
23
|
config.registerComponent({
|
|
@@ -86,6 +87,7 @@ const getItaliaWidgets = (config) => {
|
|
|
86
87
|
color_list: ColorListWidget,
|
|
87
88
|
path_filters: PathFiltersWidget,
|
|
88
89
|
location_filter: LocationFiltersWidget,
|
|
90
|
+
luoghi_correlati_evento: LuoghiCorrelatiEventoWidget,
|
|
89
91
|
},
|
|
90
92
|
};
|
|
91
93
|
};
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SelectWidget component.
|
|
3
|
+
* @module components/manage/Widgets/SelectWidget
|
|
4
|
+
* Customizations:
|
|
5
|
+
* - pass props.onBlur to Select component
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { Component } from 'react';
|
|
9
|
+
import PropTypes from 'prop-types';
|
|
10
|
+
import { connect } from 'react-redux';
|
|
11
|
+
import { compose } from 'redux';
|
|
12
|
+
import { map } from 'lodash';
|
|
13
|
+
import { defineMessages, injectIntl } from 'react-intl';
|
|
14
|
+
import {
|
|
15
|
+
getVocabFromHint,
|
|
16
|
+
getVocabFromField,
|
|
17
|
+
getVocabFromItems,
|
|
18
|
+
} from '@plone/volto/helpers';
|
|
19
|
+
import { FormFieldWrapper } from '@plone/volto/components';
|
|
20
|
+
import { getVocabulary, getVocabularyTokenTitle } from '@plone/volto/actions';
|
|
21
|
+
import { normalizeValue } from '@plone/volto/components/manage/Widgets/SelectUtils';
|
|
22
|
+
|
|
23
|
+
import {
|
|
24
|
+
customSelectStyles,
|
|
25
|
+
DropdownIndicator,
|
|
26
|
+
ClearIndicator,
|
|
27
|
+
Option,
|
|
28
|
+
selectTheme,
|
|
29
|
+
MenuList,
|
|
30
|
+
MultiValueContainer,
|
|
31
|
+
} from '@plone/volto/components/manage/Widgets/SelectStyling';
|
|
32
|
+
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
33
|
+
|
|
34
|
+
const messages = defineMessages({
|
|
35
|
+
default: {
|
|
36
|
+
id: 'Default',
|
|
37
|
+
defaultMessage: 'Default',
|
|
38
|
+
},
|
|
39
|
+
idTitle: {
|
|
40
|
+
id: 'Short Name',
|
|
41
|
+
defaultMessage: 'Short Name',
|
|
42
|
+
},
|
|
43
|
+
idDescription: {
|
|
44
|
+
id: 'Used for programmatic access to the fieldset.',
|
|
45
|
+
defaultMessage: 'Used for programmatic access to the fieldset.',
|
|
46
|
+
},
|
|
47
|
+
title: {
|
|
48
|
+
id: 'Title',
|
|
49
|
+
defaultMessage: 'Title',
|
|
50
|
+
},
|
|
51
|
+
description: {
|
|
52
|
+
id: 'Description',
|
|
53
|
+
defaultMessage: 'Description',
|
|
54
|
+
},
|
|
55
|
+
close: {
|
|
56
|
+
id: 'Close',
|
|
57
|
+
defaultMessage: 'Close',
|
|
58
|
+
},
|
|
59
|
+
choices: {
|
|
60
|
+
id: 'Choices',
|
|
61
|
+
defaultMessage: 'Choices',
|
|
62
|
+
},
|
|
63
|
+
required: {
|
|
64
|
+
id: 'Required',
|
|
65
|
+
defaultMessage: 'Required',
|
|
66
|
+
},
|
|
67
|
+
select: {
|
|
68
|
+
id: 'Select…',
|
|
69
|
+
defaultMessage: 'Select…',
|
|
70
|
+
},
|
|
71
|
+
no_value: {
|
|
72
|
+
id: 'No value',
|
|
73
|
+
defaultMessage: 'No value',
|
|
74
|
+
},
|
|
75
|
+
no_options: {
|
|
76
|
+
id: 'No options',
|
|
77
|
+
defaultMessage: 'No options',
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* SelectWidget component class.
|
|
83
|
+
* @function SelectWidget
|
|
84
|
+
* @returns {string} Markup of the component.
|
|
85
|
+
*/
|
|
86
|
+
class SelectWidget extends Component {
|
|
87
|
+
/**
|
|
88
|
+
* Property types.
|
|
89
|
+
* @property {Object} propTypes Property types.
|
|
90
|
+
* @static
|
|
91
|
+
*/
|
|
92
|
+
static propTypes = {
|
|
93
|
+
id: PropTypes.string.isRequired,
|
|
94
|
+
title: PropTypes.string.isRequired,
|
|
95
|
+
description: PropTypes.string,
|
|
96
|
+
required: PropTypes.bool,
|
|
97
|
+
error: PropTypes.arrayOf(PropTypes.string),
|
|
98
|
+
getVocabulary: PropTypes.func.isRequired,
|
|
99
|
+
getVocabularyTokenTitle: PropTypes.func.isRequired,
|
|
100
|
+
choices: PropTypes.arrayOf(
|
|
101
|
+
PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
|
102
|
+
),
|
|
103
|
+
items: PropTypes.shape({
|
|
104
|
+
vocabulary: PropTypes.object,
|
|
105
|
+
}),
|
|
106
|
+
widgetOptions: PropTypes.shape({
|
|
107
|
+
vocabulary: PropTypes.object,
|
|
108
|
+
}),
|
|
109
|
+
value: PropTypes.oneOfType([
|
|
110
|
+
PropTypes.object,
|
|
111
|
+
PropTypes.string,
|
|
112
|
+
PropTypes.bool,
|
|
113
|
+
PropTypes.func,
|
|
114
|
+
PropTypes.array,
|
|
115
|
+
]),
|
|
116
|
+
onChange: PropTypes.func.isRequired,
|
|
117
|
+
onBlur: PropTypes.func,
|
|
118
|
+
onClick: PropTypes.func,
|
|
119
|
+
onEdit: PropTypes.func,
|
|
120
|
+
onDelete: PropTypes.func,
|
|
121
|
+
wrapped: PropTypes.bool,
|
|
122
|
+
noValueOption: PropTypes.bool,
|
|
123
|
+
customOptionStyling: PropTypes.any,
|
|
124
|
+
isMulti: PropTypes.bool,
|
|
125
|
+
placeholder: PropTypes.string,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Default properties
|
|
130
|
+
* @property {Object} defaultProps Default properties.
|
|
131
|
+
* @static
|
|
132
|
+
*/
|
|
133
|
+
static defaultProps = {
|
|
134
|
+
description: null,
|
|
135
|
+
required: false,
|
|
136
|
+
items: {
|
|
137
|
+
vocabulary: null,
|
|
138
|
+
},
|
|
139
|
+
widgetOptions: {
|
|
140
|
+
vocabulary: null,
|
|
141
|
+
},
|
|
142
|
+
error: [],
|
|
143
|
+
choices: [],
|
|
144
|
+
value: null,
|
|
145
|
+
onChange: () => {},
|
|
146
|
+
onBlur: () => {},
|
|
147
|
+
onClick: () => {},
|
|
148
|
+
onEdit: null,
|
|
149
|
+
onDelete: null,
|
|
150
|
+
noValueOption: true,
|
|
151
|
+
customOptionStyling: null,
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Component did mount
|
|
156
|
+
* @method componentDidMount
|
|
157
|
+
* @returns {undefined}
|
|
158
|
+
*/
|
|
159
|
+
componentDidMount() {
|
|
160
|
+
if (
|
|
161
|
+
(!this.props.choices || this.props.choices?.length === 0) &&
|
|
162
|
+
this.props.vocabBaseUrl
|
|
163
|
+
) {
|
|
164
|
+
this.props.getVocabulary({
|
|
165
|
+
vocabNameOrURL: this.props.vocabBaseUrl,
|
|
166
|
+
size: -1,
|
|
167
|
+
subrequest: this.props.lang,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
componentDidUpdate(prevProps) {
|
|
173
|
+
if (
|
|
174
|
+
this.props.vocabBaseUrl !== prevProps.vocabBaseUrl &&
|
|
175
|
+
(!this.props.choices || this.props.choices?.length === 0)
|
|
176
|
+
) {
|
|
177
|
+
this.props.getVocabulary({
|
|
178
|
+
vocabNameOrURL: this.props.vocabBaseUrl,
|
|
179
|
+
size: -1,
|
|
180
|
+
subrequest: this.props.lang,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Render method.
|
|
187
|
+
* @method render
|
|
188
|
+
* @returns {string} Markup for the component.
|
|
189
|
+
*/
|
|
190
|
+
render() {
|
|
191
|
+
const { id, choices, value, intl, onChange, onBlur } = this.props;
|
|
192
|
+
const normalizedValue = normalizeValue(choices, value, intl);
|
|
193
|
+
// Make sure that both disabled and isDisabled (from the DX layout feat work)
|
|
194
|
+
const disabled = this.props.disabled || this.props.isDisabled;
|
|
195
|
+
const Select = this.props.reactSelect.default;
|
|
196
|
+
|
|
197
|
+
let options = this.props.vocabBaseUrl
|
|
198
|
+
? this.props.choices
|
|
199
|
+
: [
|
|
200
|
+
...map(choices, (option) => ({
|
|
201
|
+
value: option[0],
|
|
202
|
+
label:
|
|
203
|
+
// Fix "None" on the serializer, to remove when fixed in p.restapi
|
|
204
|
+
option[1] !== 'None' && option[1] ? option[1] : option[0],
|
|
205
|
+
})),
|
|
206
|
+
// Only set "no-value" option if there's no default in the field
|
|
207
|
+
// TODO: also if this.props.defaultValue?
|
|
208
|
+
...(this.props.noValueOption &&
|
|
209
|
+
(this.props.default === undefined || this.props.default === null)
|
|
210
|
+
? [
|
|
211
|
+
{
|
|
212
|
+
label: this.props.intl.formatMessage(messages.no_value),
|
|
213
|
+
value: 'no-value',
|
|
214
|
+
},
|
|
215
|
+
]
|
|
216
|
+
: []),
|
|
217
|
+
];
|
|
218
|
+
|
|
219
|
+
const isMulti = this.props.isMulti
|
|
220
|
+
? this.props.isMulti
|
|
221
|
+
: id === 'roles' || id === 'groups' || this.props.type === 'array';
|
|
222
|
+
|
|
223
|
+
return (
|
|
224
|
+
<FormFieldWrapper {...this.props}>
|
|
225
|
+
<Select
|
|
226
|
+
id={`field-${id}`}
|
|
227
|
+
key={choices}
|
|
228
|
+
name={id}
|
|
229
|
+
menuShouldScrollIntoView={false}
|
|
230
|
+
isDisabled={disabled}
|
|
231
|
+
isSearchable={true}
|
|
232
|
+
className="react-select-container"
|
|
233
|
+
classNamePrefix="react-select"
|
|
234
|
+
isMulti={isMulti}
|
|
235
|
+
options={options}
|
|
236
|
+
styles={customSelectStyles}
|
|
237
|
+
theme={selectTheme}
|
|
238
|
+
components={{
|
|
239
|
+
...(options?.length > 25 && {
|
|
240
|
+
MenuList,
|
|
241
|
+
}),
|
|
242
|
+
MultiValueContainer,
|
|
243
|
+
DropdownIndicator,
|
|
244
|
+
ClearIndicator,
|
|
245
|
+
Option: this.props.customOptionStyling || Option,
|
|
246
|
+
}}
|
|
247
|
+
value={normalizedValue}
|
|
248
|
+
placeholder={
|
|
249
|
+
this.props.placeholder ??
|
|
250
|
+
this.props.intl.formatMessage(messages.select)
|
|
251
|
+
}
|
|
252
|
+
onChange={(selectedOption) => {
|
|
253
|
+
if (isMulti) {
|
|
254
|
+
return onChange(
|
|
255
|
+
id,
|
|
256
|
+
selectedOption.map((el) => el.value),
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
return onChange(
|
|
260
|
+
id,
|
|
261
|
+
selectedOption && selectedOption.value !== 'no-value'
|
|
262
|
+
? selectedOption.value
|
|
263
|
+
: undefined,
|
|
264
|
+
);
|
|
265
|
+
}}
|
|
266
|
+
onBlur={() => onBlur(id, normalizedValue)}
|
|
267
|
+
isClearable
|
|
268
|
+
/>
|
|
269
|
+
</FormFieldWrapper>
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export const SelectWidgetComponent = injectIntl(SelectWidget);
|
|
275
|
+
|
|
276
|
+
export default compose(
|
|
277
|
+
injectLazyLibs(['reactSelect']),
|
|
278
|
+
connect(
|
|
279
|
+
(state, props) => {
|
|
280
|
+
const vocabBaseUrl = !props.choices
|
|
281
|
+
? getVocabFromHint(props) ||
|
|
282
|
+
getVocabFromField(props) ||
|
|
283
|
+
getVocabFromItems(props)
|
|
284
|
+
: '';
|
|
285
|
+
|
|
286
|
+
const vocabState =
|
|
287
|
+
state.vocabularies?.[vocabBaseUrl]?.subrequests?.[state.intl.locale];
|
|
288
|
+
|
|
289
|
+
// If the schema already has the choices in it, then do not try to get the vocab,
|
|
290
|
+
// even if there is one
|
|
291
|
+
if (props.choices) {
|
|
292
|
+
return {
|
|
293
|
+
choices: props.choices,
|
|
294
|
+
lang: state.intl.locale,
|
|
295
|
+
};
|
|
296
|
+
} else if (vocabState) {
|
|
297
|
+
return {
|
|
298
|
+
vocabBaseUrl,
|
|
299
|
+
choices: vocabState?.items ?? [],
|
|
300
|
+
lang: state.intl.locale,
|
|
301
|
+
};
|
|
302
|
+
// There is a moment that vocabState is not there yet, so we need to pass the
|
|
303
|
+
// vocabBaseUrl to the component.
|
|
304
|
+
} else if (vocabBaseUrl) {
|
|
305
|
+
return {
|
|
306
|
+
vocabBaseUrl,
|
|
307
|
+
lang: state.intl.locale,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
return { lang: state.intl.locale };
|
|
311
|
+
},
|
|
312
|
+
{ getVocabulary, getVocabularyTokenTitle },
|
|
313
|
+
),
|
|
314
|
+
)(SelectWidgetComponent);
|
|
@@ -254,4 +254,102 @@ export const eventFormValidationHelper = (
|
|
|
254
254
|
errors['end'].push(formatMessage(customValidationMessages.event_end));
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
|
+
|
|
258
|
+
// Validazione dei campi obbligatori per il luogo
|
|
259
|
+
const fullMandatoryList = [
|
|
260
|
+
'luoghi_correlati',
|
|
261
|
+
'nome_sede',
|
|
262
|
+
'street',
|
|
263
|
+
'zip_code',
|
|
264
|
+
'city',
|
|
265
|
+
'country',
|
|
266
|
+
];
|
|
267
|
+
|
|
268
|
+
// Luoghi correlati è stato modificato
|
|
269
|
+
if ('luoghi_correlati' in touchedField) {
|
|
270
|
+
if (
|
|
271
|
+
isEmpty(touchedField.luoghi_correlati) &&
|
|
272
|
+
// Se siamo qui vuol dire che luoghi correlati è stato svuotato.
|
|
273
|
+
(isEmpty(formData.nome_sede) ||
|
|
274
|
+
isEmpty(formData.street) ||
|
|
275
|
+
isEmpty(formData.zip_code) ||
|
|
276
|
+
isEmpty(formData.city) ||
|
|
277
|
+
isEmpty(formData.country))
|
|
278
|
+
) {
|
|
279
|
+
// Se gli altri non sono tutti compilati, li metto tutti obbligatori
|
|
280
|
+
fields.push(...fullMandatoryList);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// Uno dei campi dell'indirizzo viene compilato.
|
|
284
|
+
// Per ciascuno controllo se luoghi_correlati è compilato.
|
|
285
|
+
// Se non lo è e ne manca almeno uno degli altri, metto tutto obbligatorio.
|
|
286
|
+
// Per ciascuno uso il touchedField quando è stato modificato lui stesso,
|
|
287
|
+
// mentre controllo da formData per gli altri.
|
|
288
|
+
else if ('nome_sede' in touchedField) {
|
|
289
|
+
if (
|
|
290
|
+
isEmpty(formData.luoghi_correlati) &&
|
|
291
|
+
(isEmpty(touchedField.nome_sede) ||
|
|
292
|
+
isEmpty(formData.street) ||
|
|
293
|
+
isEmpty(formData.zip_code) ||
|
|
294
|
+
isEmpty(formData.city) ||
|
|
295
|
+
isEmpty(formData.country))
|
|
296
|
+
) {
|
|
297
|
+
fields.push(...fullMandatoryList);
|
|
298
|
+
}
|
|
299
|
+
} else if ('street' in touchedField) {
|
|
300
|
+
if (
|
|
301
|
+
isEmpty(formData.luoghi_correlati) &&
|
|
302
|
+
(isEmpty(formData.nome_sede) ||
|
|
303
|
+
isEmpty(touchedField.street) ||
|
|
304
|
+
isEmpty(formData.zip_code) ||
|
|
305
|
+
isEmpty(formData.city) ||
|
|
306
|
+
isEmpty(formData.country))
|
|
307
|
+
) {
|
|
308
|
+
fields.push(...fullMandatoryList);
|
|
309
|
+
}
|
|
310
|
+
} else if ('zip_code' in touchedField) {
|
|
311
|
+
if (
|
|
312
|
+
isEmpty(formData.luoghi_correlati) &&
|
|
313
|
+
(isEmpty(formData.nome_sede) ||
|
|
314
|
+
isEmpty(formData.street) ||
|
|
315
|
+
isEmpty(touchedField.zip_code) ||
|
|
316
|
+
isEmpty(formData.city) ||
|
|
317
|
+
isEmpty(formData.country))
|
|
318
|
+
) {
|
|
319
|
+
fields.push(...fullMandatoryList);
|
|
320
|
+
}
|
|
321
|
+
} else if ('city' in touchedField) {
|
|
322
|
+
if (
|
|
323
|
+
isEmpty(formData.luoghi_correlati) &&
|
|
324
|
+
(isEmpty(formData.nome_sede) ||
|
|
325
|
+
isEmpty(formData.street) ||
|
|
326
|
+
isEmpty(formData.zip_code) ||
|
|
327
|
+
isEmpty(touchedField.city) ||
|
|
328
|
+
isEmpty(formData.country))
|
|
329
|
+
) {
|
|
330
|
+
fields.push(...fullMandatoryList);
|
|
331
|
+
}
|
|
332
|
+
} else if ('country' in touchedField) {
|
|
333
|
+
if (
|
|
334
|
+
isEmpty(formData.luoghi_correlati) &&
|
|
335
|
+
(isEmpty(formData.nome_sede) ||
|
|
336
|
+
isEmpty(formData.street) ||
|
|
337
|
+
isEmpty(formData.zip_code) ||
|
|
338
|
+
isEmpty(formData.city) ||
|
|
339
|
+
isEmpty(touchedField.country))
|
|
340
|
+
) {
|
|
341
|
+
fields.push(...fullMandatoryList);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
// Il campo modificato è un altro, faccio un check base su tutti i campi
|
|
345
|
+
else if (
|
|
346
|
+
isEmpty(formData.luoghi_correlati) &&
|
|
347
|
+
(isEmpty(formData.nome_sede) ||
|
|
348
|
+
isEmpty(formData.street) ||
|
|
349
|
+
isEmpty(formData.zip_code) ||
|
|
350
|
+
isEmpty(formData.city) ||
|
|
351
|
+
isEmpty(formData.country))
|
|
352
|
+
) {
|
|
353
|
+
fields.push(...fullMandatoryList);
|
|
354
|
+
}
|
|
257
355
|
};
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
+
|
|
64
65
|
.date-filter {
|
|
65
66
|
.DateRangePickerInput {
|
|
66
67
|
.DateInput_input {
|
|
@@ -81,7 +82,7 @@
|
|
|
81
82
|
|
|
82
83
|
.bg-secondary {
|
|
83
84
|
.search-container {
|
|
84
|
-
|
|
85
|
+
&.filter-wrapper {
|
|
85
86
|
.select-filter {
|
|
86
87
|
.react-select__control {
|
|
87
88
|
.react-select__placeholder {
|
|
@@ -93,7 +94,8 @@
|
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
|
-
|
|
97
|
+
|
|
98
|
+
&.date-filter {
|
|
97
99
|
.DateRangePickerInput {
|
|
98
100
|
.DateInput_input {
|
|
99
101
|
color: $subsite-secondary-text;
|
|
@@ -108,6 +110,17 @@
|
|
|
108
110
|
}
|
|
109
111
|
}
|
|
110
112
|
}
|
|
113
|
+
|
|
114
|
+
&.date-filter .DateRangePickerInput {
|
|
115
|
+
.DateInput_input {
|
|
116
|
+
color: $subsite-secondary-text !important;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.DateRangePickerInput_arrow .DateRangePickerInput_arrow_svg,
|
|
120
|
+
.DateRangePickerInput_clearDates svg {
|
|
121
|
+
fill: $subsite-secondary-text !important;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
111
124
|
}
|
|
112
125
|
}
|
|
113
126
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.luoghi-correlati-evento-widget {
|
|
2
|
+
.introduction-helper-wrapper {
|
|
3
|
+
padding: 1rem 1rem 0 1rem;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.field-title::after {
|
|
7
|
+
display: inline-block;
|
|
8
|
+
width: 10px;
|
|
9
|
+
height: 10px;
|
|
10
|
+
border-radius: 50%;
|
|
11
|
+
margin-left: 5px;
|
|
12
|
+
background-color: #e40166;
|
|
13
|
+
content: '';
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/theme/site.scss
CHANGED
|
@@ -118,6 +118,7 @@
|
|
|
118
118
|
@import 'ItaliaTheme/Widgets/textInput';
|
|
119
119
|
@import 'ItaliaTheme/Widgets/dataGridWidget';
|
|
120
120
|
@import 'ItaliaTheme/Widgets/canaleDigitaleWidget';
|
|
121
|
+
@import 'ItaliaTheme/Widgets/luoghiCorrelatiEventoWidget';
|
|
121
122
|
@import 'ItaliaTheme/Components/megamenu';
|
|
122
123
|
@import 'ItaliaTheme/Components/sharing';
|
|
123
124
|
@import 'ItaliaTheme/Components/logo';
|