design-comuni-plone-theme 11.24.4 → 11.24.6
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/.yarn/cache/{volto-gdpr-privacy-npm-2.2.7-dd2359a788-beb301d21f.zip → volto-gdpr-privacy-npm-2.2.9-a1e4258e06-fe530fe8ee.zip} +0 -0
- package/.yarn/install-state.gz +0 -0
- package/CHANGELOG.md +33 -0
- package/RELEASE.md +13 -1
- package/locales/de/LC_MESSAGES/volto.po +5 -0
- package/locales/en/LC_MESSAGES/volto.po +5 -0
- package/locales/es/LC_MESSAGES/volto.po +5 -0
- package/locales/fr/LC_MESSAGES/volto.po +5 -0
- package/locales/it/LC_MESSAGES/volto.po +5 -0
- package/locales/volto.pot +6 -1
- package/package.json +2 -2
- package/publiccode.yml +2 -2
- package/src/components/ItaliaTheme/Icons/DesignIcon.jsx +80 -29
- package/src/components/ItaliaTheme/Icons/FontAwesomeIcon.jsx +6 -6
- package/src/components/ItaliaTheme/Icons/Icon.jsx +1 -0
- package/src/components/ItaliaTheme/View/BandoView/BandoApprofondimenti.jsx +1 -1
- package/src/components/ItaliaTheme/View/Commons/LocationsMap.jsx +4 -18
- package/src/components/ItaliaTheme/View/Commons/Module.jsx +18 -33
- package/src/components/ItaliaTheme/View/Commons/Modules.jsx +3 -1
- package/src/components/ItaliaTheme/View/Commons/PageHeader/PageHeaderEventDates.jsx +1 -3
- package/src/components/ItaliaTheme/View/PaginaArgomentoView/PaginaArgomentoView.jsx +13 -34
- package/src/customizations/volto/components/manage/Contents/ContentsUploadModal.jsx +373 -0
- package/src/overrideTranslations.jsx +5 -0
- package/src/theme/ItaliaTheme/_main.scss +31 -0
|
Binary file
|
package/.yarn/install-state.gz
CHANGED
|
Binary file
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
+
## [11.24.6](https://github.com/RedTurtle/design-comuni-plone-theme/compare/v11.24.5...v11.24.6) (2024-11-22)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* removed getContent from Documento, Bando, Argomento and LocationsMap ([#803](https://github.com/RedTurtle/design-comuni-plone-theme/issues/803)) ([ca1f0f0](https://github.com/RedTurtle/design-comuni-plone-theme/commit/ca1f0f0b0e8b02d2a50d420e2aa371c97517a8f9))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
* updated publiccode ([ebcf3d0](https://github.com/RedTurtle/design-comuni-plone-theme/commit/ebcf3d05408cc5e175e9f610ba752b53d28082b9))
|
|
14
|
+
|
|
15
|
+
## [11.24.5](https://github.com/RedTurtle/design-comuni-plone-theme/compare/v11.24.4...v11.24.5) (2024-11-22)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* added info on contents file upload modal on restraint in servizio-modulistica folder ([#796](https://github.com/RedTurtle/design-comuni-plone-theme/issues/796)) ([cb7b3c8](https://github.com/RedTurtle/design-comuni-plone-theme/commit/cb7b3c83325f6aa3da94faa29eaf0c940e216a93))
|
|
21
|
+
* removed whole day condition in page header subtitle ([#800](https://github.com/RedTurtle/design-comuni-plone-theme/issues/800)) ([cc7d668](https://github.com/RedTurtle/design-comuni-plone-theme/commit/cc7d6686dc91aaaf3eaef51102c8e035540efe46))
|
|
22
|
+
* safari rendering issues and overhaul old dynamic bootstrap italia icons import using cache map ([#810](https://github.com/RedTurtle/design-comuni-plone-theme/issues/810)) ([9c23ac6](https://github.com/RedTurtle/design-comuni-plone-theme/commit/9c23ac6fd172f31c0aa4723d4db008a92100b1a1))
|
|
23
|
+
* updated lockfile ([8d1cf74](https://github.com/RedTurtle/design-comuni-plone-theme/commit/8d1cf74defdec9059dff9a1e1b4313fa7b4c0402))
|
|
24
|
+
* updated volto-gdpr-privacy addon version to 2.2.9([#806](https://github.com/RedTurtle/design-comuni-plone-theme/issues/806)) ([f785ddd](https://github.com/RedTurtle/design-comuni-plone-theme/commit/f785ddd651e1528439a58852f852a9331df2a57e))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Maintenance
|
|
28
|
+
|
|
29
|
+
* removed additional info from release.md from september ([#799](https://github.com/RedTurtle/design-comuni-plone-theme/issues/799)) ([60052e7](https://github.com/RedTurtle/design-comuni-plone-theme/commit/60052e77b71a9f9dbb59714240acadc01e14ee0a))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Documentation
|
|
33
|
+
|
|
34
|
+
* updated publiccode and release log ([6a5e490](https://github.com/RedTurtle/design-comuni-plone-theme/commit/6a5e490248df7e53784b5f730b096ab9d6553ad8))
|
|
35
|
+
|
|
3
36
|
## [11.24.4](https://github.com/RedTurtle/design-comuni-plone-theme/compare/v11.24.3...v11.24.4) (2024-11-07)
|
|
4
37
|
|
|
5
38
|
|
package/RELEASE.md
CHANGED
|
@@ -41,6 +41,18 @@
|
|
|
41
41
|
- ...
|
|
42
42
|
-->
|
|
43
43
|
|
|
44
|
+
## Versione 11.24.5 (22/11/2024)
|
|
45
|
+
|
|
46
|
+
### Migliorie
|
|
47
|
+
|
|
48
|
+
- Inserito messaggio di avviso quando si tenta di caricare un file dalla cartella Modulistica all'interno di un Servizio per segnalare limitazione sull'upload
|
|
49
|
+
|
|
50
|
+
### Fix
|
|
51
|
+
|
|
52
|
+
- L'impostazione "Solo cookie tecnici" non causa problemi nell'apertura del cookie banner.
|
|
53
|
+
- [WebKit, Safari, iOS] Risolto un problema di visualizzazione grafica di alcuni bottoni che contengono al loro interno un link ad un sito esterno.
|
|
54
|
+
- Quando un evento ha impostata l'opzione "Tutta la giornata", le date sotto il titolo vengono visualizzate in maniera corretta.
|
|
55
|
+
|
|
44
56
|
## Versione 11.24.4 (07/11/2024)
|
|
45
57
|
|
|
46
58
|
### Fix
|
|
@@ -97,7 +109,7 @@
|
|
|
97
109
|
|
|
98
110
|
### Fix
|
|
99
111
|
|
|
100
|
-
- Rimosso il campo "ID lighthouse" dal blocco elenco con variazione Card con Testo Animato perchè entra in contrasto con asseveratore
|
|
112
|
+
- Rimosso il campo "ID lighthouse" dal blocco elenco con variazione Card con Testo Animato perchè entra in contrasto con asseveratore
|
|
101
113
|
|
|
102
114
|
## Versione 11.22.0 (05/09/2024)
|
|
103
115
|
|
|
@@ -2644,6 +2644,11 @@ msgstr ""
|
|
|
2644
2644
|
msgid "modulistica"
|
|
2645
2645
|
msgstr ""
|
|
2646
2646
|
|
|
2647
|
+
#: overrideTranslations
|
|
2648
|
+
# defaultMessage: As per the official information architecture outlined in measure 1.4.1, all forms must be properly uploaded in the designated section within Amministrazione > Documenti e Dati > Modulistica, and linked to the relevant service sheet. It is no longer possible to upload files and attachments directly into this container.
|
|
2649
|
+
msgid "modulistica_restraint"
|
|
2650
|
+
msgstr ""
|
|
2651
|
+
|
|
2647
2652
|
#: components/ItaliaTheme/View/Commons/DownloadFileFormat
|
|
2648
2653
|
# defaultMessage: Scarica il file
|
|
2649
2654
|
msgid "modulo_download_file"
|
|
@@ -2629,6 +2629,11 @@ msgstr "Last update"
|
|
|
2629
2629
|
msgid "modulistica"
|
|
2630
2630
|
msgstr "Forms"
|
|
2631
2631
|
|
|
2632
|
+
#: overrideTranslations
|
|
2633
|
+
# defaultMessage: As per the official information architecture outlined in measure 1.4.1, all forms must be properly uploaded in the designated section within Amministrazione > Documenti e Dati > Modulistica, and linked to the relevant service sheet. It is no longer possible to upload files and attachments directly into this container.
|
|
2634
|
+
msgid "modulistica_restraint"
|
|
2635
|
+
msgstr ""
|
|
2636
|
+
|
|
2632
2637
|
#: components/ItaliaTheme/View/Commons/DownloadFileFormat
|
|
2633
2638
|
# defaultMessage: Scarica il file
|
|
2634
2639
|
msgid "modulo_download_file"
|
|
@@ -2638,6 +2638,11 @@ msgstr "Última actualización"
|
|
|
2638
2638
|
msgid "modulistica"
|
|
2639
2639
|
msgstr "Formularios"
|
|
2640
2640
|
|
|
2641
|
+
#: overrideTranslations
|
|
2642
|
+
# defaultMessage: As per the official information architecture outlined in measure 1.4.1, all forms must be properly uploaded in the designated section within Amministrazione > Documenti e Dati > Modulistica, and linked to the relevant service sheet. It is no longer possible to upload files and attachments directly into this container.
|
|
2643
|
+
msgid "modulistica_restraint"
|
|
2644
|
+
msgstr ""
|
|
2645
|
+
|
|
2641
2646
|
#: components/ItaliaTheme/View/Commons/DownloadFileFormat
|
|
2642
2647
|
# defaultMessage: Scarica il file
|
|
2643
2648
|
msgid "modulo_download_file"
|
|
@@ -2646,6 +2646,11 @@ msgstr "Dernière mise à jour"
|
|
|
2646
2646
|
msgid "modulistica"
|
|
2647
2647
|
msgstr "Formes"
|
|
2648
2648
|
|
|
2649
|
+
#: overrideTranslations
|
|
2650
|
+
# defaultMessage: As per the official information architecture outlined in measure 1.4.1, all forms must be properly uploaded in the designated section within Amministrazione > Documenti e Dati > Modulistica, and linked to the relevant service sheet. It is no longer possible to upload files and attachments directly into this container.
|
|
2651
|
+
msgid "modulistica_restraint"
|
|
2652
|
+
msgstr ""
|
|
2653
|
+
|
|
2649
2654
|
#: components/ItaliaTheme/View/Commons/DownloadFileFormat
|
|
2650
2655
|
# defaultMessage: Scarica il file
|
|
2651
2656
|
msgid "modulo_download_file"
|
|
@@ -2629,6 +2629,11 @@ msgstr "Ultimo aggiornamento"
|
|
|
2629
2629
|
msgid "modulistica"
|
|
2630
2630
|
msgstr "Modulistica"
|
|
2631
2631
|
|
|
2632
|
+
#: overrideTranslations
|
|
2633
|
+
# defaultMessage: As per the official information architecture outlined in measure 1.4.1, all forms must be properly uploaded in the designated section within Amministrazione > Documenti e Dati > Modulistica, and linked to the relevant service sheet. It is no longer possible to upload files and attachments directly into this container.
|
|
2634
|
+
msgid "modulistica_restraint"
|
|
2635
|
+
msgstr "Come da architettura informativa ufficiale prevista dalla misura 1.4.1, tutta la modulistica dovrà essere correttamente caricata nella sezione apposita, all'interno di amministrazione, documenti e dati, modulistica, e relazionata con la scheda servizio. Non è più possibile caricare file ed allegati direttamente in questo contenitore."
|
|
2636
|
+
|
|
2632
2637
|
#: components/ItaliaTheme/View/Commons/DownloadFileFormat
|
|
2633
2638
|
# defaultMessage: Scarica il file
|
|
2634
2639
|
msgid "modulo_download_file"
|
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-
|
|
4
|
+
"POT-Creation-Date: 2024-10-29T14:58:46.664Z\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"
|
|
@@ -2631,6 +2631,11 @@ msgstr ""
|
|
|
2631
2631
|
msgid "modulistica"
|
|
2632
2632
|
msgstr ""
|
|
2633
2633
|
|
|
2634
|
+
#: overrideTranslations
|
|
2635
|
+
# defaultMessage: As per the official information architecture outlined in measure 1.4.1, all forms must be properly uploaded in the designated section within Amministrazione > Documenti e Dati > Modulistica, and linked to the relevant service sheet. It is no longer possible to upload files and attachments directly into this container.
|
|
2636
|
+
msgid "modulistica_restraint"
|
|
2637
|
+
msgstr ""
|
|
2638
|
+
|
|
2634
2639
|
#: components/ItaliaTheme/View/Commons/DownloadFileFormat
|
|
2635
2640
|
# defaultMessage: Scarica il file
|
|
2636
2641
|
msgid "modulo_download_file"
|
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.24.
|
|
5
|
+
"version": "11.24.6",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -153,7 +153,7 @@
|
|
|
153
153
|
"volto-editablefooter": "5.1.7",
|
|
154
154
|
"volto-feedback": "0.3.2",
|
|
155
155
|
"volto-form-block": "3.10.0",
|
|
156
|
-
"volto-gdpr-privacy": "2.2.
|
|
156
|
+
"volto-gdpr-privacy": "2.2.9",
|
|
157
157
|
"volto-google-analytics": "2.0.0",
|
|
158
158
|
"volto-multilingual-widget": "3.2.1",
|
|
159
159
|
"volto-querywidget-with-browser": "0.4.2",
|
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-11-
|
|
230
|
+
releaseDate: '2024-11-22'
|
|
231
231
|
softwareType: standalone/web
|
|
232
|
-
softwareVersion: 11.24.
|
|
232
|
+
softwareVersion: 11.24.6
|
|
233
233
|
url: 'https://github.com/italia/design-comuni-plone-theme'
|
|
234
234
|
usedBy:
|
|
235
235
|
- ASP Comuni Modenesi Area Nord
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useEffect
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import { v4 as uuid } from 'uuid';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
|
|
@@ -12,50 +12,101 @@ const propTypes = {
|
|
|
12
12
|
|
|
13
13
|
const defaultProps = {
|
|
14
14
|
color: '',
|
|
15
|
-
size: '',
|
|
15
|
+
size: '24px',
|
|
16
16
|
icon: '',
|
|
17
17
|
padding: false,
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
+
// No ts means we get many different things here, standardize it
|
|
21
|
+
const SIZE_MAPPINGS = {
|
|
22
|
+
xs: '1rem',
|
|
23
|
+
sm: '1.25rem',
|
|
24
|
+
md: defaultProps.size,
|
|
25
|
+
lg: '1.75rem',
|
|
26
|
+
xl: '2rem',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
function getIconMapSizeConfig(size) {
|
|
30
|
+
const mapKeys = Object.keys(SIZE_MAPPINGS);
|
|
31
|
+
if (mapKeys.includes(size)) return SIZE_MAPPINGS[size];
|
|
32
|
+
return size;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const iconCache = new Map(); // Global cache using Map
|
|
36
|
+
|
|
20
37
|
const Icon = ({ icon, title, className, size }) => {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
38
|
+
const [iconState, setIconState] = useState({
|
|
39
|
+
loading: true,
|
|
40
|
+
icon: undefined,
|
|
41
|
+
// Move to useId in react18
|
|
42
|
+
id: uuid(),
|
|
43
|
+
});
|
|
24
44
|
|
|
25
45
|
useEffect(() => {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
46
|
+
let loadableIcon = iconCache.get(icon);
|
|
47
|
+
// Use the cached icon if available
|
|
48
|
+
if (loadableIcon) {
|
|
49
|
+
setIconState((prev) => ({
|
|
50
|
+
...prev,
|
|
51
|
+
loading: false,
|
|
52
|
+
icon: loadableIcon,
|
|
53
|
+
}));
|
|
54
|
+
} else {
|
|
55
|
+
// Otherwise, dynamically import the icon
|
|
56
|
+
const importIcon = async () => {
|
|
57
|
+
try {
|
|
58
|
+
const { default: namedImport } = await import(
|
|
59
|
+
`bootstrap-italia/src/svg/${icon}.svg`
|
|
60
|
+
);
|
|
61
|
+
iconCache.set(icon, namedImport); // Cache the imported icon
|
|
62
|
+
loadableIcon = namedImport;
|
|
63
|
+
} catch (err) {
|
|
64
|
+
console.error(`Error loading icon: ${icon}`, err);
|
|
65
|
+
} finally {
|
|
66
|
+
setIconState((prev) => ({
|
|
67
|
+
...prev,
|
|
68
|
+
loading: false,
|
|
69
|
+
icon: loadableIcon,
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
importIcon();
|
|
74
|
+
}
|
|
40
75
|
}, [icon]);
|
|
41
76
|
|
|
42
|
-
|
|
43
|
-
|
|
77
|
+
const iconSize = getIconMapSizeConfig(size);
|
|
78
|
+
|
|
79
|
+
// Placeholder that is shown while the icon is loading
|
|
80
|
+
if (iconState.loading) {
|
|
81
|
+
return (
|
|
82
|
+
<span
|
|
83
|
+
style={{
|
|
84
|
+
width: iconSize,
|
|
85
|
+
height: iconSize,
|
|
86
|
+
backgroundColor: 'transparent',
|
|
87
|
+
}}
|
|
88
|
+
className={className}
|
|
89
|
+
/>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Render the icon once it's loaded
|
|
94
|
+
if (iconState.icon) {
|
|
44
95
|
return (
|
|
45
96
|
<svg
|
|
46
|
-
xmlns={
|
|
47
|
-
viewBox={
|
|
48
|
-
width={
|
|
49
|
-
height={
|
|
50
|
-
style={{ height:
|
|
97
|
+
xmlns={iconState.icon.attributes?.xmlns}
|
|
98
|
+
viewBox={iconState.icon.attributes?.viewBox}
|
|
99
|
+
width={iconState.icon.attributes?.width}
|
|
100
|
+
height={iconState.icon.attributes?.height}
|
|
101
|
+
style={{ height: iconSize, width: iconSize }}
|
|
51
102
|
className={className}
|
|
52
103
|
aria-hidden="true"
|
|
53
104
|
dangerouslySetInnerHTML={{
|
|
54
105
|
__html: title
|
|
55
|
-
? `<title id="${
|
|
56
|
-
:
|
|
106
|
+
? `<title id="${iconState.id}">${title}</title>${iconState.icon.content}`
|
|
107
|
+
: iconState.icon.content,
|
|
57
108
|
}}
|
|
58
|
-
aria-labelledby={
|
|
109
|
+
aria-labelledby={iconState.id}
|
|
59
110
|
/>
|
|
60
111
|
);
|
|
61
112
|
}
|
|
@@ -36,12 +36,12 @@ const FontAwesomeIcon = (props) => {
|
|
|
36
36
|
prefixKey === 'fab'
|
|
37
37
|
? 'brands'
|
|
38
38
|
: prefixKey === 'far'
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
? 'regular'
|
|
40
|
+
: prefixKey === 'fas'
|
|
41
|
+
? 'solid'
|
|
42
|
+
: prefixKey != null
|
|
43
|
+
? prefixKey
|
|
44
|
+
: 'solid',
|
|
45
45
|
iconName,
|
|
46
46
|
];
|
|
47
47
|
};
|
|
@@ -34,7 +34,7 @@ const BandoApprofondimenti = ({ content }) => {
|
|
|
34
34
|
/>
|
|
35
35
|
// item={item} viene utilizzato nelle customizzazioni per ottenere altre proprietà
|
|
36
36
|
);
|
|
37
|
-
} else if (item.type === '
|
|
37
|
+
} else if (item.type === 'Collegamento') {
|
|
38
38
|
return (
|
|
39
39
|
<Card
|
|
40
40
|
className="card card-teaser shadow p-4 mt-3 rounded attachment"
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import React, { useEffect } from 'react';
|
|
1
|
+
import React from 'react';
|
|
3
2
|
import { useIntl, defineMessages } from 'react-intl';
|
|
4
|
-
import { getContent, resetContent } from '@plone/volto/actions';
|
|
5
3
|
import { flattenToAppURL } from '@plone/volto/helpers';
|
|
6
4
|
import { OSMMap } from 'volto-venue';
|
|
7
5
|
import PropTypes from 'prop-types';
|
|
@@ -30,9 +28,7 @@ const messages = defineMessages({
|
|
|
30
28
|
});
|
|
31
29
|
|
|
32
30
|
const LocationsMap = ({ center, locations }) => {
|
|
33
|
-
const dispatch = useDispatch();
|
|
34
31
|
const intl = useIntl();
|
|
35
|
-
const fetchedLocations = useSelector((state) => state.content.subrequests);
|
|
36
32
|
const venues = locations.map((location) => {
|
|
37
33
|
let url = flattenToAppURL(location['@id']);
|
|
38
34
|
return {
|
|
@@ -41,18 +37,6 @@ const LocationsMap = ({ center, locations }) => {
|
|
|
41
37
|
};
|
|
42
38
|
});
|
|
43
39
|
|
|
44
|
-
useEffect(() => {
|
|
45
|
-
venues.forEach((loc) => {
|
|
46
|
-
dispatch(getContent(loc.url, null, loc.key));
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
return () =>
|
|
50
|
-
venues.forEach((loc) => {
|
|
51
|
-
dispatch(resetContent(loc.key));
|
|
52
|
-
});
|
|
53
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
54
|
-
}, [dispatch, locations]);
|
|
55
|
-
|
|
56
40
|
const pinContent = (item) => {
|
|
57
41
|
return (
|
|
58
42
|
<div className="map-pin-popup">
|
|
@@ -97,7 +81,9 @@ const LocationsMap = ({ center, locations }) => {
|
|
|
97
81
|
};
|
|
98
82
|
|
|
99
83
|
let venuesData = venues.reduce((acc, val) => {
|
|
100
|
-
let venue =
|
|
84
|
+
let venue = locations.find((el) => {
|
|
85
|
+
return el['@id'].includes(val.url);
|
|
86
|
+
});
|
|
101
87
|
|
|
102
88
|
if (venue?.geolocation?.latitude && venue?.geolocation?.longitude) {
|
|
103
89
|
return [
|
|
@@ -3,12 +3,9 @@
|
|
|
3
3
|
* @module components/theme/View/DocumentoView/Modules
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React
|
|
7
|
-
import { useDispatch, useSelector } from 'react-redux';
|
|
6
|
+
import React from 'react';
|
|
8
7
|
import PropTypes from 'prop-types';
|
|
9
|
-
import { flattenToAppURL } from '@plone/volto/helpers';
|
|
10
8
|
import { UniversalLink } from '@plone/volto/components';
|
|
11
|
-
import { getContent, resetContent } from '@plone/volto/actions';
|
|
12
9
|
|
|
13
10
|
import { Card, CardBody, CardTitle } from 'design-react-kit';
|
|
14
11
|
|
|
@@ -21,20 +18,7 @@ import { DownloadFileFormat } from 'design-comuni-plone-theme/components/ItaliaT
|
|
|
21
18
|
* @returns {string} Markup of the component.
|
|
22
19
|
*/
|
|
23
20
|
const Module = ({ item }) => {
|
|
24
|
-
|
|
25
|
-
const subrequests = useSelector((state) => state.content.subrequests);
|
|
26
|
-
const url = flattenToAppURL(item['@id']);
|
|
27
|
-
const key = 'module_' + url;
|
|
28
|
-
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
dispatch(getContent(url, null, key));
|
|
31
|
-
return () => dispatch(resetContent(key));
|
|
32
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
33
|
-
}, [key]);
|
|
34
|
-
|
|
35
|
-
let modulo = subrequests?.[key]?.data;
|
|
36
|
-
|
|
37
|
-
return modulo ? (
|
|
21
|
+
return item ? (
|
|
38
22
|
<Card
|
|
39
23
|
className="card card-teaser shadow p-4 mt-3 rounded modulo"
|
|
40
24
|
noWrapper={true}
|
|
@@ -42,37 +26,38 @@ const Module = ({ item }) => {
|
|
|
42
26
|
>
|
|
43
27
|
<CardBody tag="div">
|
|
44
28
|
<CardTitle className="h5">
|
|
45
|
-
{
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
{modulo.title ?? modulo.file_principale.filename}
|
|
51
|
-
</a>
|
|
52
|
-
) : modulo['@type'] === 'Link' ? (
|
|
53
|
-
<UniversalLink item={modulo} title={modulo.title}>
|
|
54
|
-
{modulo.title}
|
|
29
|
+
{item.file_principale ? (
|
|
30
|
+
item.title ?? item.file_principale.filename
|
|
31
|
+
) : item['@type'] === 'Link' ? (
|
|
32
|
+
<UniversalLink item={item} title={item.title}>
|
|
33
|
+
{item.title}
|
|
55
34
|
</UniversalLink>
|
|
56
35
|
) : (
|
|
57
|
-
|
|
36
|
+
item.title
|
|
58
37
|
)}
|
|
59
38
|
</CardTitle>
|
|
60
39
|
|
|
61
|
-
{
|
|
40
|
+
{item.description && <p>{item.description}</p>}
|
|
62
41
|
<div className="download-formats">
|
|
63
42
|
<DownloadFileFormat
|
|
64
|
-
file={
|
|
43
|
+
file={item.file_principale}
|
|
65
44
|
showLabel={true}
|
|
45
|
+
title={item.title ?? item.file_principale.filename}
|
|
46
|
+
hideFileFormatLabel={true}
|
|
66
47
|
className="mb-4"
|
|
67
48
|
/>
|
|
68
49
|
<DownloadFileFormat
|
|
69
|
-
file={
|
|
50
|
+
file={item.formato_alternativo_1}
|
|
70
51
|
showLabel={true}
|
|
52
|
+
title={item.title ?? item.formato_alternativo_1.filename}
|
|
53
|
+
hideFileFormatLabel={true}
|
|
71
54
|
className="mb-4"
|
|
72
55
|
/>
|
|
73
56
|
<DownloadFileFormat
|
|
74
|
-
file={
|
|
57
|
+
file={item.formato_alternativo_2}
|
|
75
58
|
showLabel={true}
|
|
59
|
+
title={item.title ?? item.formato_alternativo_2.filename}
|
|
60
|
+
hideFileFormatLabel={true}
|
|
76
61
|
/>
|
|
77
62
|
</div>
|
|
78
63
|
</CardBody>
|
|
@@ -18,7 +18,9 @@ import {
|
|
|
18
18
|
*/
|
|
19
19
|
const Modules = ({ content, title, id = 'documenti' }) => {
|
|
20
20
|
const moduli =
|
|
21
|
-
content.
|
|
21
|
+
content.moduli_del_documento ??
|
|
22
|
+
content.items?.filter((item) => item.id !== 'multimedia') ??
|
|
23
|
+
[];
|
|
22
24
|
|
|
23
25
|
return moduli.length > 0 ? (
|
|
24
26
|
<RichTextSection tag_id={id} title={title}>
|
|
@@ -83,9 +83,7 @@ const PageHeaderEventDates = ({ content, moment, rrule }) => {
|
|
|
83
83
|
!openEnd &&
|
|
84
84
|
!renderOnlyStart &&
|
|
85
85
|
`dal ${Moment(content.start).format('DD-MM-Y')} al ${endDate}`}
|
|
86
|
-
{(
|
|
87
|
-
renderOnlyStart ||
|
|
88
|
-
Moment(content.end).isSame(actualEndDate)) &&
|
|
86
|
+
{(renderOnlyStart || Moment(content.end).isSame(actualEndDate)) &&
|
|
89
87
|
!openEnd &&
|
|
90
88
|
`${Moment(content.start).format('DD-MM-Y')}`}
|
|
91
89
|
{openEnd &&
|
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
* @module components/theme/View/PaginaArgomentoView/PaginaArgomentoView
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import React
|
|
6
|
+
import React from 'react';
|
|
7
7
|
import { useLocation } from 'react-router-dom';
|
|
8
|
-
import { useDispatch, useSelector } from 'react-redux';
|
|
9
8
|
import { Portal } from 'react-portal';
|
|
10
9
|
import cx from 'classnames';
|
|
11
10
|
|
|
@@ -16,7 +15,6 @@ import {
|
|
|
16
15
|
flattenToAppURL,
|
|
17
16
|
hasBlocksData,
|
|
18
17
|
} from '@plone/volto/helpers';
|
|
19
|
-
import { getContent, resetContent } from '@plone/volto/actions';
|
|
20
18
|
import {
|
|
21
19
|
CardCategory,
|
|
22
20
|
Breadcrumbs,
|
|
@@ -44,32 +42,6 @@ import config from '@plone/volto/registry';
|
|
|
44
42
|
const PaginaArgomentoView = ({ content }) => {
|
|
45
43
|
const Image = config.getComponent({ name: 'Image' }).component;
|
|
46
44
|
const location = useLocation();
|
|
47
|
-
const dispatch = useDispatch();
|
|
48
|
-
|
|
49
|
-
const searchResults = useSelector((state) => state.content?.subrequests);
|
|
50
|
-
|
|
51
|
-
// one request is made for every 'unita_amministrative_responsabili' selected
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
if (content?.unita_amministrative_responsabili?.length > 0) {
|
|
54
|
-
content.unita_amministrative_responsabili.forEach((x) => {
|
|
55
|
-
const url = flattenToAppURL(x['@id']);
|
|
56
|
-
const loaded =
|
|
57
|
-
searchResults?.[url]?.loading || searchResults?.[url]?.loaded;
|
|
58
|
-
if (!loaded) {
|
|
59
|
-
dispatch(getContent(url, null, url));
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return () => {
|
|
65
|
-
if (content?.unita_amministrative_responsabili?.length > 0) {
|
|
66
|
-
content.unita_amministrative_responsabili.forEach((x) => {
|
|
67
|
-
dispatch(resetContent(flattenToAppURL(x['@id'])));
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
72
|
-
}, [content]);
|
|
73
45
|
|
|
74
46
|
const rightHeaderHasContent =
|
|
75
47
|
richTextHasContent(content.ulteriori_informazioni) ||
|
|
@@ -99,12 +71,17 @@ const PaginaArgomentoView = ({ content }) => {
|
|
|
99
71
|
|
|
100
72
|
{content?.unita_amministrative_responsabili?.length > 0 &&
|
|
101
73
|
content?.unita_amministrative_responsabili?.map((u, index) => {
|
|
102
|
-
const uo_object =
|
|
103
|
-
searchResults[flattenToAppURL(u['@id'])]?.data;
|
|
74
|
+
const uo_object = u;
|
|
104
75
|
let alt = u.title;
|
|
105
|
-
if (
|
|
76
|
+
if (
|
|
77
|
+
uo_object.image_scales.preview_image.length > 0 &&
|
|
78
|
+
uo_object?.preview_caption
|
|
79
|
+
) {
|
|
106
80
|
alt = uo_object.preview_caption;
|
|
107
|
-
} else if (
|
|
81
|
+
} else if (
|
|
82
|
+
uo_object.image_scales.image.length > 0 &&
|
|
83
|
+
uo_object?.image_caption
|
|
84
|
+
) {
|
|
108
85
|
alt = uo_object.image_caption;
|
|
109
86
|
}
|
|
110
87
|
|
|
@@ -132,7 +109,9 @@ const PaginaArgomentoView = ({ content }) => {
|
|
|
132
109
|
</CardText>
|
|
133
110
|
</CardBody>
|
|
134
111
|
{uo_object &&
|
|
135
|
-
(uo_object.
|
|
112
|
+
(uo_object.image_scales.image.length > 0 ||
|
|
113
|
+
uo_object.image_scales.preview_image.length >
|
|
114
|
+
0) && (
|
|
136
115
|
<div className="image-container me-3">
|
|
137
116
|
<Image
|
|
138
117
|
item={uo_object}
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
// CUSTOMIZATION:
|
|
2
|
+
// - 196-202 - 230-262: added file upload restraint message as per agid regulations
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Contents upload modal.
|
|
6
|
+
* @module components/manage/Contents/ContentsUploadModal
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import React, { Component } from 'react';
|
|
10
|
+
import PropTypes from 'prop-types';
|
|
11
|
+
import { connect } from 'react-redux';
|
|
12
|
+
import { compose } from 'redux';
|
|
13
|
+
import {
|
|
14
|
+
Button,
|
|
15
|
+
Dimmer,
|
|
16
|
+
Header,
|
|
17
|
+
Icon,
|
|
18
|
+
Image,
|
|
19
|
+
Loader,
|
|
20
|
+
Modal,
|
|
21
|
+
Table,
|
|
22
|
+
Segment,
|
|
23
|
+
TableCell,
|
|
24
|
+
} from 'semantic-ui-react';
|
|
25
|
+
import loadable from '@loadable/component';
|
|
26
|
+
import { concat, filter, map } from 'lodash';
|
|
27
|
+
import filesize from 'filesize';
|
|
28
|
+
import { readAsDataURL } from 'promise-file-reader';
|
|
29
|
+
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
|
30
|
+
import { FormattedRelativeDate } from '@plone/volto/components';
|
|
31
|
+
import { createContent, getTypes } from '@plone/volto/actions';
|
|
32
|
+
import { validateFileUploadSize, getBaseUrl } from '@plone/volto/helpers';
|
|
33
|
+
|
|
34
|
+
const Dropzone = loadable(() => import('react-dropzone'));
|
|
35
|
+
|
|
36
|
+
const messages = defineMessages({
|
|
37
|
+
cancel: {
|
|
38
|
+
id: 'Cancel',
|
|
39
|
+
defaultMessage: 'Cancel',
|
|
40
|
+
},
|
|
41
|
+
upload: {
|
|
42
|
+
id: '{count, plural, one {Upload {count} file} other {Upload {count} files}}',
|
|
43
|
+
defaultMessage:
|
|
44
|
+
'{count, plural, one {Upload {count} file} other {Upload {count} files}}',
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const SUBREQUEST = 'batch-upload';
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* ContentsUploadModal class.
|
|
52
|
+
* @class ContentsUploadModal
|
|
53
|
+
* @extends Component
|
|
54
|
+
*/
|
|
55
|
+
class ContentsUploadModal extends Component {
|
|
56
|
+
/**
|
|
57
|
+
* Property types.
|
|
58
|
+
* @property {Object} propTypes Property types.
|
|
59
|
+
* @static
|
|
60
|
+
*/
|
|
61
|
+
static propTypes = {
|
|
62
|
+
createContent: PropTypes.func.isRequired,
|
|
63
|
+
pathname: PropTypes.string.isRequired,
|
|
64
|
+
request: PropTypes.shape({
|
|
65
|
+
loading: PropTypes.bool,
|
|
66
|
+
loaded: PropTypes.bool,
|
|
67
|
+
}).isRequired,
|
|
68
|
+
open: PropTypes.bool.isRequired,
|
|
69
|
+
onOk: PropTypes.func.isRequired,
|
|
70
|
+
onCancel: PropTypes.func.isRequired,
|
|
71
|
+
getTypes: PropTypes.func,
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Constructor
|
|
76
|
+
* @method constructor
|
|
77
|
+
* @param {Object} props Component properties
|
|
78
|
+
* @constructs ContentsUploadModal
|
|
79
|
+
*/
|
|
80
|
+
constructor(props) {
|
|
81
|
+
super(props);
|
|
82
|
+
this.onRemoveFile = this.onRemoveFile.bind(this);
|
|
83
|
+
this.onDrop = this.onDrop.bind(this);
|
|
84
|
+
this.onCancel = this.onCancel.bind(this);
|
|
85
|
+
this.onSubmit = this.onSubmit.bind(this);
|
|
86
|
+
this.state = {
|
|
87
|
+
files: [],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Component will receive props
|
|
93
|
+
* @method componentWillReceiveProps
|
|
94
|
+
* @param {Object} nextProps Next properties
|
|
95
|
+
* @returns {undefined}
|
|
96
|
+
*/
|
|
97
|
+
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
98
|
+
if (this.props.request.loading && nextProps.request.loaded) {
|
|
99
|
+
this.props.onOk();
|
|
100
|
+
this.setState({
|
|
101
|
+
files: [],
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Remove file handler
|
|
108
|
+
* @method onRemoveFile
|
|
109
|
+
* @param {Object} event Event object
|
|
110
|
+
* @returns {undefined}
|
|
111
|
+
*/
|
|
112
|
+
onRemoveFile(event) {
|
|
113
|
+
this.setState({
|
|
114
|
+
files: filter(
|
|
115
|
+
this.state.files,
|
|
116
|
+
(file, index) =>
|
|
117
|
+
index !== parseInt(event.target.getAttribute('value'), 10),
|
|
118
|
+
),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Drop handler
|
|
124
|
+
* @method onDrop
|
|
125
|
+
* @param {array} files File objects
|
|
126
|
+
* @returns {undefined}
|
|
127
|
+
*/
|
|
128
|
+
onDrop = async (files) => {
|
|
129
|
+
const validFiles = [];
|
|
130
|
+
for (let i = 0; i < files.length; i++) {
|
|
131
|
+
if (validateFileUploadSize(files[i], this.props.intl.formatMessage)) {
|
|
132
|
+
await readAsDataURL(files[i]).then((data) => {
|
|
133
|
+
const fields = data.match(/^data:(.*);(.*),(.*)$/);
|
|
134
|
+
files[i].preview = fields[0];
|
|
135
|
+
});
|
|
136
|
+
validFiles.push(files[i]);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
this.setState({
|
|
140
|
+
files: concat(this.state.files, validFiles),
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Cancel handler
|
|
146
|
+
* @method onCancel
|
|
147
|
+
* @returns {undefined}
|
|
148
|
+
*/
|
|
149
|
+
onCancel() {
|
|
150
|
+
this.props.onCancel();
|
|
151
|
+
this.setState({
|
|
152
|
+
files: [],
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Submit handler
|
|
158
|
+
* @method onSubmit
|
|
159
|
+
* @returns {undefined}
|
|
160
|
+
*/
|
|
161
|
+
onSubmit() {
|
|
162
|
+
Promise.all(map(this.state.files, (file) => readAsDataURL(file))).then(
|
|
163
|
+
(files) => {
|
|
164
|
+
this.props.createContent(
|
|
165
|
+
this.props.pathname,
|
|
166
|
+
map(this.state.files, (file, index) => {
|
|
167
|
+
const fields = files[index].match(/^data:(.*);(.*),(.*)$/);
|
|
168
|
+
const image = fields[1].split('/')[0] === 'image';
|
|
169
|
+
return {
|
|
170
|
+
'@type': image ? 'Image' : 'File',
|
|
171
|
+
title: file.name,
|
|
172
|
+
[image ? 'image' : 'file']: {
|
|
173
|
+
data: fields[3],
|
|
174
|
+
encoding: fields[2],
|
|
175
|
+
'content-type': fields[1],
|
|
176
|
+
filename: file.name,
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
}),
|
|
180
|
+
SUBREQUEST,
|
|
181
|
+
);
|
|
182
|
+
},
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
componentDidMount() {
|
|
187
|
+
this.props.getTypes(getBaseUrl(this.props.pathname));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Render method.
|
|
192
|
+
* @method render
|
|
193
|
+
* @returns {string} Markup for the component.
|
|
194
|
+
*/
|
|
195
|
+
render() {
|
|
196
|
+
// as per agid guidelines, files cannot be uploaded in modulistica folder inside ct servizio
|
|
197
|
+
// show restraint and hide upload button when page is called modulistica and when there's a restraint
|
|
198
|
+
// this is enough to identify this only case bc even if another page is called 'modulistica', it will have 'File'
|
|
199
|
+
// as addable type
|
|
200
|
+
const showFileRestraint =
|
|
201
|
+
this.props.pathname.includes('modulistica') &&
|
|
202
|
+
!this.props.types.some((type) => type.id === 'File');
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
this.props.open && (
|
|
206
|
+
<Modal open={this.props.open}>
|
|
207
|
+
<Header>
|
|
208
|
+
<FormattedMessage id="Upload files" defaultMessage="Upload files" />
|
|
209
|
+
</Header>
|
|
210
|
+
<Dimmer active={this.props.request.loading}>
|
|
211
|
+
<Loader>
|
|
212
|
+
<FormattedMessage
|
|
213
|
+
id="Uploading files"
|
|
214
|
+
defaultMessage="Uploading files"
|
|
215
|
+
/>
|
|
216
|
+
</Loader>
|
|
217
|
+
</Dimmer>
|
|
218
|
+
<Modal.Content>
|
|
219
|
+
<Dropzone
|
|
220
|
+
onDrop={this.onDrop}
|
|
221
|
+
className="dropzone"
|
|
222
|
+
noDragEventsBubbling={true}
|
|
223
|
+
multiple={true}
|
|
224
|
+
>
|
|
225
|
+
{({ getRootProps, getInputProps }) => (
|
|
226
|
+
<div {...getRootProps({ className: 'dashed' })}>
|
|
227
|
+
<Segment>
|
|
228
|
+
<Table basic="very">
|
|
229
|
+
<Table.Body>
|
|
230
|
+
{showFileRestraint ? (
|
|
231
|
+
<Table.Row>
|
|
232
|
+
<TableCell>
|
|
233
|
+
<FormattedMessage
|
|
234
|
+
id="modulistica_restraint"
|
|
235
|
+
defaultMessage="As per the official information architecture outlined in measure 1.4.1, all forms must be properly uploaded in the designated section within Amministrazione > Documenti e Dati > Modulistica, and linked to the relevant service sheet. It is no longer possible to upload files and attachments directly into this container."
|
|
236
|
+
/>
|
|
237
|
+
</TableCell>
|
|
238
|
+
</Table.Row>
|
|
239
|
+
) : (
|
|
240
|
+
<Table.Row>
|
|
241
|
+
<Table.Cell>
|
|
242
|
+
<FormattedMessage
|
|
243
|
+
id="Drag and drop files from your computer onto this area or click the “Browse” button."
|
|
244
|
+
defaultMessage="Drag and drop files from your computer onto this area or click the “Browse” button."
|
|
245
|
+
/>
|
|
246
|
+
</Table.Cell>
|
|
247
|
+
<Table.Cell>
|
|
248
|
+
<Button className="ui button primary">
|
|
249
|
+
<FormattedMessage
|
|
250
|
+
id="Browse"
|
|
251
|
+
defaultMessage="Browse"
|
|
252
|
+
/>
|
|
253
|
+
</Button>
|
|
254
|
+
<input
|
|
255
|
+
{...getInputProps({
|
|
256
|
+
type: 'file',
|
|
257
|
+
style: { display: 'none' },
|
|
258
|
+
})}
|
|
259
|
+
/>
|
|
260
|
+
</Table.Cell>
|
|
261
|
+
</Table.Row>
|
|
262
|
+
)}
|
|
263
|
+
</Table.Body>
|
|
264
|
+
</Table>
|
|
265
|
+
</Segment>
|
|
266
|
+
</div>
|
|
267
|
+
)}
|
|
268
|
+
</Dropzone>
|
|
269
|
+
{this.state.files.length > 0 && (
|
|
270
|
+
<Table compact singleLine>
|
|
271
|
+
<Table.Header>
|
|
272
|
+
<Table.Row>
|
|
273
|
+
<Table.HeaderCell width={8}>
|
|
274
|
+
<FormattedMessage
|
|
275
|
+
id="Filename"
|
|
276
|
+
defaultMessage="Filename"
|
|
277
|
+
/>
|
|
278
|
+
</Table.HeaderCell>
|
|
279
|
+
<Table.HeaderCell width={4}>
|
|
280
|
+
<FormattedMessage
|
|
281
|
+
id="Last modified"
|
|
282
|
+
defaultMessage="Last modified"
|
|
283
|
+
/>
|
|
284
|
+
</Table.HeaderCell>
|
|
285
|
+
<Table.HeaderCell width={4}>
|
|
286
|
+
<FormattedMessage
|
|
287
|
+
id="File size"
|
|
288
|
+
defaultMessage="File size"
|
|
289
|
+
/>
|
|
290
|
+
</Table.HeaderCell>
|
|
291
|
+
<Table.HeaderCell width={4}>
|
|
292
|
+
<FormattedMessage id="Preview" defaultMessage="Preview" />
|
|
293
|
+
</Table.HeaderCell>
|
|
294
|
+
<Table.HeaderCell />
|
|
295
|
+
</Table.Row>
|
|
296
|
+
</Table.Header>
|
|
297
|
+
<Table.Body>
|
|
298
|
+
{map(this.state.files, (file, index) => (
|
|
299
|
+
<Table.Row className="upload-row" key={file.name}>
|
|
300
|
+
<Table.Cell>{file.name}</Table.Cell>
|
|
301
|
+
<Table.Cell>
|
|
302
|
+
{file.lastModifiedDate && (
|
|
303
|
+
<FormattedRelativeDate date={file.lastModifiedDate} />
|
|
304
|
+
)}
|
|
305
|
+
</Table.Cell>
|
|
306
|
+
<Table.Cell>
|
|
307
|
+
{filesize(file.size, { round: 0 })}
|
|
308
|
+
</Table.Cell>
|
|
309
|
+
<Table.Cell>
|
|
310
|
+
{file.type.split('/')[0] === 'image' && (
|
|
311
|
+
<Image src={file.preview} height={60} />
|
|
312
|
+
)}
|
|
313
|
+
</Table.Cell>
|
|
314
|
+
<Table.Cell>
|
|
315
|
+
<Icon
|
|
316
|
+
name="close"
|
|
317
|
+
value={index}
|
|
318
|
+
link
|
|
319
|
+
onClick={this.onRemoveFile}
|
|
320
|
+
/>
|
|
321
|
+
</Table.Cell>
|
|
322
|
+
</Table.Row>
|
|
323
|
+
))}
|
|
324
|
+
</Table.Body>
|
|
325
|
+
</Table>
|
|
326
|
+
)}
|
|
327
|
+
</Modal.Content>
|
|
328
|
+
<Modal.Actions>
|
|
329
|
+
{this.state.files.length > 0 && (
|
|
330
|
+
<Button
|
|
331
|
+
basic
|
|
332
|
+
circular
|
|
333
|
+
primary
|
|
334
|
+
floated="right"
|
|
335
|
+
icon="arrow right"
|
|
336
|
+
aria-label={this.props.intl.formatMessage(messages.upload, {
|
|
337
|
+
count: this.state.files.length,
|
|
338
|
+
})}
|
|
339
|
+
onClick={this.onSubmit}
|
|
340
|
+
title={this.props.intl.formatMessage(messages.upload, {
|
|
341
|
+
count: this.state.files.length,
|
|
342
|
+
})}
|
|
343
|
+
size="big"
|
|
344
|
+
/>
|
|
345
|
+
)}
|
|
346
|
+
<Button
|
|
347
|
+
basic
|
|
348
|
+
circular
|
|
349
|
+
secondary
|
|
350
|
+
icon="remove"
|
|
351
|
+
aria-label={this.props.intl.formatMessage(messages.cancel)}
|
|
352
|
+
title={this.props.intl.formatMessage(messages.cancel)}
|
|
353
|
+
floated="right"
|
|
354
|
+
size="big"
|
|
355
|
+
onClick={this.onCancel}
|
|
356
|
+
/>
|
|
357
|
+
</Modal.Actions>
|
|
358
|
+
</Modal>
|
|
359
|
+
)
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export default compose(
|
|
365
|
+
injectIntl,
|
|
366
|
+
connect(
|
|
367
|
+
(state) => ({
|
|
368
|
+
request: state.content.subrequests?.[SUBREQUEST] || {},
|
|
369
|
+
types: filter(state.types.types, 'addable'),
|
|
370
|
+
}),
|
|
371
|
+
{ createContent, getTypes },
|
|
372
|
+
),
|
|
373
|
+
)(ContentsUploadModal);
|
|
@@ -94,4 +94,9 @@ defineMessages({
|
|
|
94
94
|
id: 'form_limit',
|
|
95
95
|
defaultMessage: 'Submission limit',
|
|
96
96
|
},
|
|
97
|
+
modulistica_restraint: {
|
|
98
|
+
id: 'modulistica_restraint',
|
|
99
|
+
defaultMessage:
|
|
100
|
+
'As per the official information architecture outlined in measure 1.4.1, all forms must be properly uploaded in the designated section within Amministrazione > Documenti e Dati > Modulistica, and linked to the relevant service sheet. It is no longer possible to upload files and attachments directly into this container.',
|
|
101
|
+
},
|
|
97
102
|
});
|
|
@@ -152,6 +152,37 @@ iframe {
|
|
|
152
152
|
font-weight: 700;
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
|
+
/*
|
|
156
|
+
Safari rendering issue workaround - B#60364
|
|
157
|
+
Safari rendering fix, icons and fonts coming late means shenanigans for Safari rendering, as
|
|
158
|
+
Safari is lazy and slow in loading fonts and icons dynamically.
|
|
159
|
+
Problem: Safari (tested on Safari 17.6) sometimes fails to calculate the layout correctly
|
|
160
|
+
when dealing with dynamic content such as lazy-loaded icons or fonts, combined with
|
|
161
|
+
`display: inline-block`. This can result in improperly positioned elements
|
|
162
|
+
until the page is re-rendered or refocused.
|
|
163
|
+
|
|
164
|
+
Solution: To fix this issue:
|
|
165
|
+
1. Replace `display: inline-block` with `display: inline-flex`. This ensures Safari
|
|
166
|
+
handles the box model and inline context properly, especially when the element's
|
|
167
|
+
size or alignment depends on dynamic content.
|
|
168
|
+
2. Add `position: relative;` to force a recalculation of layout, resolving rendering quirks.
|
|
169
|
+
|
|
170
|
+
Background: Safari's WebKit engine has known issues with `inline-block` combined
|
|
171
|
+
with delayed content rendering, such as lazy-loaded icons. Switching to `inline-flex`
|
|
172
|
+
better aligns with modern CSS rendering engines, while `position: relative;`
|
|
173
|
+
ensures the layout is recalculated.
|
|
174
|
+
|
|
175
|
+
References:
|
|
176
|
+
- CSS-Tricks: What Forces Layout or Reflow: https://css-tricks.com/what-forces-layout-reflow/
|
|
177
|
+
- WebKit Bug Reports on `inline-block` rendering issues with dynamic content.
|
|
178
|
+
- Testing and observations on Safari 17.6 behavior with lazy-loaded assets.
|
|
179
|
+
*/
|
|
180
|
+
@supports (-webkit-appearance: none) {
|
|
181
|
+
a {
|
|
182
|
+
display: inline-flex; /* Evita problemi con inline-block */
|
|
183
|
+
position: relative; /* Forza Safari a calcolare il layout reflow correttamente */
|
|
184
|
+
}
|
|
185
|
+
}
|
|
155
186
|
}
|
|
156
187
|
|
|
157
188
|
div[class^='draftJsToolbar__toolbar__'] {
|