From 19b584ace89b6dcd5545be2df2593851be9d13d7 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 20 Oct 2025 14:36:47 +0200 Subject: [PATCH 01/10] fix: date in tabella per trasparenza --- .../Blocks/Listing/Table/TableTemplate.jsx | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/components/Blocks/Listing/Table/TableTemplate.jsx b/src/components/Blocks/Listing/Table/TableTemplate.jsx index db21a80b..c9e26e42 100644 --- a/src/components/Blocks/Listing/Table/TableTemplate.jsx +++ b/src/components/Blocks/Listing/Table/TableTemplate.jsx @@ -39,7 +39,7 @@ const TableTemplate = (props) => { // necessario per gli edditor nel momento in cui aggiungono nuove colonne const ct_schema = useSelector((state) => state.ct_schema?.subrequests); - let render_columns = + const render_columns = (columns ?? []).filter((c) => c.field === 'title').length > 0 ? columns : [ @@ -102,21 +102,32 @@ const TableTemplate = (props) => { if (field_properties.widget === 'datetime') { widget_props.format = 'DD/MM/yyyy HH:MM'; } - // per questi campi si è deciso dii non pubblicare ora:minuti - switch (c.field) { - case 'apertura_bando': - case 'chiusura_procedimento_bando': - case 'scadenza_domande_bando': - case 'scadenza_bando': - widget_props.format = 'DD/MM/yyyy'; + // per questi campi si è deciso di non pubblicare ora:minuti + // XXX: queste personalizzazioni sul formato dei datetime, basate sui nomi + // dei field sono da rivedere in modo differente + switch (c.ct) { + case 'ATAvviso': + case 'ATGara': + case 'ATAffidamento': + case 'ATConcorso': break; default: - break; + switch (c.field) { + case 'apertura_bando': + case 'chiusura_procedimento_bando': + case 'scadenza_domande_bando': + case 'scadenza_bando': + widget_props.format = 'DD/MM/yyyy'; + break; + default: + break; + } } // rimuove ora, se non valorizzata if ( field_properties.widget === 'datetime' && - item[c.field]?.indexOf('T00:00') > 0 + (item[c.field]?.indexOf('T00:00') > 0 || + item[c.field]?.indexOf('T23:59') > 0) ) { widget_props.format = 'DD/MM/yyyy'; } From c62a5a10f6caa0cffa508c41fe8a53a34f1678db Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 20 Oct 2025 15:30:30 +0200 Subject: [PATCH 02/10] fix datetime --- src/components/Blocks/Listing/Table/TableTemplate.jsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/Blocks/Listing/Table/TableTemplate.jsx b/src/components/Blocks/Listing/Table/TableTemplate.jsx index c9e26e42..df6838f1 100644 --- a/src/components/Blocks/Listing/Table/TableTemplate.jsx +++ b/src/components/Blocks/Listing/Table/TableTemplate.jsx @@ -100,7 +100,11 @@ const TableTemplate = (props) => { behavior: field_properties.behavior, }; if (field_properties.widget === 'datetime') { - widget_props.format = 'DD/MM/yyyy HH:MM'; + if (item[c.field]?.indexOf('T') > 0) { + widget_props.format = 'DD/MM/yyyy HH:mm'; + } else { + widget_props.format = 'DD/MM/yyyy'; + } } // per questi campi si è deciso di non pubblicare ora:minuti // XXX: queste personalizzazioni sul formato dei datetime, basate sui nomi From 1d55b4817988b8bb88f818dcb564b20ebcdf1898 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 20 Oct 2025 17:13:29 +0200 Subject: [PATCH 03/10] fix: add utc timezone --- src/components/Blocks/Listing/Table/TableTemplate.jsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/Blocks/Listing/Table/TableTemplate.jsx b/src/components/Blocks/Listing/Table/TableTemplate.jsx index df6838f1..cffea63f 100644 --- a/src/components/Blocks/Listing/Table/TableTemplate.jsx +++ b/src/components/Blocks/Listing/Table/TableTemplate.jsx @@ -102,6 +102,12 @@ const TableTemplate = (props) => { if (field_properties.widget === 'datetime') { if (item[c.field]?.indexOf('T') > 0) { widget_props.format = 'DD/MM/yyyy HH:mm'; + item[c.field] = + item[c.field] + + (item[c.field].indexOf('Z') <= 0 && + item[c.field].indexOf('+') <= 0 + ? 'Z' + : ''); } else { widget_props.format = 'DD/MM/yyyy'; } From 1c761c4baa4d12be6da13572105080beac6eeca7 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Tue, 21 Oct 2025 08:13:51 -0300 Subject: [PATCH 04/10] fix: date with timezone --- package.json | 1 + .../Blocks/Listing/Table/TableTemplate.jsx | 3 +- src/components/View/Bando/Dates.jsx | 83 +++++++++++-------- .../theme/Widgets/DatetimeWidget.jsx | 24 ++++++ 4 files changed, 74 insertions(+), 37 deletions(-) create mode 100644 src/customizations/volto/components/theme/Widgets/DatetimeWidget.jsx diff --git a/package.json b/package.json index 65de2f87..1317c586 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "design-react-kit": "5.0.0-10", "htmldiff-js": "1.0.5", "marked": "9.0.0", + "moment-timezone": "0.6.0", "react-focus-lock": "2.12.1", "react-highlight-words": "0.20.0", "react-slick": "0.30.2", diff --git a/src/components/Blocks/Listing/Table/TableTemplate.jsx b/src/components/Blocks/Listing/Table/TableTemplate.jsx index cffea63f..54a3cb31 100644 --- a/src/components/Blocks/Listing/Table/TableTemplate.jsx +++ b/src/components/Blocks/Listing/Table/TableTemplate.jsx @@ -133,7 +133,8 @@ const TableTemplate = (props) => { break; } } - // rimuove ora, se non valorizzata + // rimuove ora, se non valorizzata (XXX: in realtà se la data è UTC + // non fa quello che ci si aspetterebbe) if ( field_properties.widget === 'datetime' && (item[c.field]?.indexOf('T00:00') > 0 || diff --git a/src/components/View/Bando/Dates.jsx b/src/components/View/Bando/Dates.jsx index 36c5edff..173455ba 100644 --- a/src/components/View/Bando/Dates.jsx +++ b/src/components/View/Bando/Dates.jsx @@ -2,8 +2,9 @@ import { defineMessages, useIntl } from 'react-intl'; import React from 'react'; import { Card, CardTitle, CardBody } from 'design-react-kit'; import PropTypes from 'prop-types'; - +import { useSelector } from 'react-redux'; import { viewDate } from 'io-sanita-theme/helpers'; +import moment from 'moment-timezone'; const messages = defineMessages({ effective: { @@ -36,6 +37,8 @@ const messages = defineMessages({ */ const BandoDates = ({ content }) => { const intl = useIntl(); + const site = useSelector((state) => state.site.data); + console.log(site); const effective = content?.effective ? viewDate(intl.locale, content.effective) @@ -88,43 +91,51 @@ const BandoDates = ({ content }) => { return content ? : null; }; -const Dates = ({ dates }) => ( -
- {dates.map((item, index) => { - return ( - item.date && ( -
-
- - {item.date.format('DD')} - - - {item.date.format('MMM')}/{item.date.format('YY')} - -
-
- { + const site = useSelector((state) => state.site.data); + const tz = site?.['plone.portal_timezone'] ?? 'Europe/Rome'; + + return ( +
+ {dates.map((item, index) => { + return ( + item.date && ( +
+
- - - {item.show_hour && <>{item.date.format('HH:mm')} - } - {item.label} - - - + + {moment.tz(item.date, tz).format('DD')} + + + {moment.tz(item.date, tz).format('MMM')}/ + {moment.tz(item.date, tz).format('YY')} + +
+
+ + + + {item.show_hour && ( + <>{moment.tz(item.date, tz).format('HH:mm')} - + )} + {item.label} + + + +
-
- ) - ); - })} -
-); + ) + ); + })} +
+ ); +}; export { Dates }; diff --git a/src/customizations/volto/components/theme/Widgets/DatetimeWidget.jsx b/src/customizations/volto/components/theme/Widgets/DatetimeWidget.jsx new file mode 100644 index 00000000..b102cd4b --- /dev/null +++ b/src/customizations/volto/components/theme/Widgets/DatetimeWidget.jsx @@ -0,0 +1,24 @@ +import React from 'react'; +import cx from 'classnames'; +import moment from 'moment-timezone'; +import { useSelector } from 'react-redux'; +import { toBackendLang } from '@plone/volto/helpers/Utils/Utils'; + +const DatetimeWidget = ({ value, children, className, format = 'lll' }) => { + const lang = useSelector((state) => state.intl.locale); + const tz = useSelector( + (state) => state.site?.data?.['plone.portal_timezone'] ?? 'Europe/Rome', + ); + moment.locale(toBackendLang(lang)); + return value ? ( + + {children + ? children(moment.tz(value, tz).format(format)) + : moment.tz(value, tz).format(format)} + + ) : ( + '' + ); +}; + +export default DatetimeWidget; From da1ea69a2668bc9f3f33ebc9e9d566f0adb6a2d4 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Tue, 21 Oct 2025 08:16:08 -0300 Subject: [PATCH 05/10] chorre: remove console.log --- src/components/View/Bando/Dates.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/View/Bando/Dates.jsx b/src/components/View/Bando/Dates.jsx index 173455ba..95dd02b1 100644 --- a/src/components/View/Bando/Dates.jsx +++ b/src/components/View/Bando/Dates.jsx @@ -38,7 +38,6 @@ const messages = defineMessages({ const BandoDates = ({ content }) => { const intl = useIntl(); const site = useSelector((state) => state.site.data); - console.log(site); const effective = content?.effective ? viewDate(intl.locale, content.effective) From 045ba9967c6cf6f94d8fc6f728ae986e104d91a3 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Tue, 21 Oct 2025 08:26:01 -0300 Subject: [PATCH 06/10] cleanup --- src/components/View/Bando/Dates.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/View/Bando/Dates.jsx b/src/components/View/Bando/Dates.jsx index 95dd02b1..cea0ed24 100644 --- a/src/components/View/Bando/Dates.jsx +++ b/src/components/View/Bando/Dates.jsx @@ -37,7 +37,6 @@ const messages = defineMessages({ */ const BandoDates = ({ content }) => { const intl = useIntl(); - const site = useSelector((state) => state.site.data); const effective = content?.effective ? viewDate(intl.locale, content.effective) From ac057abd09ff30570924cb9b6f8fa07f6f3c1542 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Tue, 21 Oct 2025 17:29:48 +0200 Subject: [PATCH 07/10] Update src/components/Blocks/Listing/Table/TableTemplate.jsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/components/Blocks/Listing/Table/TableTemplate.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Blocks/Listing/Table/TableTemplate.jsx b/src/components/Blocks/Listing/Table/TableTemplate.jsx index 54a3cb31..834f303b 100644 --- a/src/components/Blocks/Listing/Table/TableTemplate.jsx +++ b/src/components/Blocks/Listing/Table/TableTemplate.jsx @@ -104,8 +104,8 @@ const TableTemplate = (props) => { widget_props.format = 'DD/MM/yyyy HH:mm'; item[c.field] = item[c.field] + - (item[c.field].indexOf('Z') <= 0 && - item[c.field].indexOf('+') <= 0 + (item[c.field].indexOf('Z') < 0 && + item[c.field].indexOf('+') < 0 ? 'Z' : ''); } else { From ab02cd2911f1439070b1d7e7a17d7bca9a12363c Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Tue, 21 Oct 2025 17:29:57 +0200 Subject: [PATCH 08/10] Update src/components/Blocks/Listing/Table/TableTemplate.jsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/components/Blocks/Listing/Table/TableTemplate.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Blocks/Listing/Table/TableTemplate.jsx b/src/components/Blocks/Listing/Table/TableTemplate.jsx index 834f303b..77d99da5 100644 --- a/src/components/Blocks/Listing/Table/TableTemplate.jsx +++ b/src/components/Blocks/Listing/Table/TableTemplate.jsx @@ -137,8 +137,8 @@ const TableTemplate = (props) => { // non fa quello che ci si aspetterebbe) if ( field_properties.widget === 'datetime' && - (item[c.field]?.indexOf('T00:00') > 0 || - item[c.field]?.indexOf('T23:59') > 0) + (item[c.field]?.indexOf('T00:00') >= 0 || + item[c.field]?.indexOf('T23:59') >= 0) ) { widget_props.format = 'DD/MM/yyyy'; } From 7676e785148778777a1b54628a9b9fb2ad8e33a9 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 3 Nov 2025 09:19:15 +0100 Subject: [PATCH 09/10] docs --- .../volto/components/theme/Widgets/DatetimeWidget.jsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/customizations/volto/components/theme/Widgets/DatetimeWidget.jsx b/src/customizations/volto/components/theme/Widgets/DatetimeWidget.jsx index b102cd4b..fffdd1c0 100644 --- a/src/customizations/volto/components/theme/Widgets/DatetimeWidget.jsx +++ b/src/customizations/volto/components/theme/Widgets/DatetimeWidget.jsx @@ -1,3 +1,10 @@ +/* + * customization from @plone/volto 18.9.1 + * + * show time using the server timezone + * + */ + import React from 'react'; import cx from 'classnames'; import moment from 'moment-timezone'; From a6bbc6042e9f0f091b0ae33c50e5b5a0da89b724 Mon Sep 17 00:00:00 2001 From: Mauro Amico Date: Mon, 3 Nov 2025 09:42:40 +0100 Subject: [PATCH 10/10] do not change shared state --- .../Blocks/Listing/Table/TableTemplate.jsx | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/components/Blocks/Listing/Table/TableTemplate.jsx b/src/components/Blocks/Listing/Table/TableTemplate.jsx index 77d99da5..1839dbe3 100644 --- a/src/components/Blocks/Listing/Table/TableTemplate.jsx +++ b/src/components/Blocks/Listing/Table/TableTemplate.jsx @@ -87,6 +87,7 @@ const TableTemplate = (props) => { ct_schema?.[c.ct]?.result?.properties?.[c.field] ?? {}; let render_value = JSON.stringify(item[c.field]); + let field_value = item[c.field]; if (field_properties) { const field = { @@ -100,12 +101,12 @@ const TableTemplate = (props) => { behavior: field_properties.behavior, }; if (field_properties.widget === 'datetime') { - if (item[c.field]?.indexOf('T') > 0) { + if (field_value?.indexOf('T') > 0) { widget_props.format = 'DD/MM/yyyy HH:mm'; - item[c.field] = - item[c.field] + - (item[c.field].indexOf('Z') < 0 && - item[c.field].indexOf('+') < 0 + field_value = + field_value + + (field_value.indexOf('Z') < 0 && + field_value.indexOf('+') < 0 ? 'Z' : ''); } else { @@ -137,8 +138,8 @@ const TableTemplate = (props) => { // non fa quello che ci si aspetterebbe) if ( field_properties.widget === 'datetime' && - (item[c.field]?.indexOf('T00:00') >= 0 || - item[c.field]?.indexOf('T23:59') >= 0) + (field_value?.indexOf('T00:00') >= 0 || + field_value?.indexOf('T23:59') >= 0) ) { widget_props.format = 'DD/MM/yyyy'; } @@ -148,7 +149,7 @@ const TableTemplate = (props) => { } render_value = ( - + ); } if (c.field === 'title') { @@ -158,7 +159,7 @@ const TableTemplate = (props) => { href={isEditMode ? '#' : ''} className="img-link" > - {item[c.field]} + {field_value} ); }