diff --git a/CHANGES.rst b/CHANGES.rst
index 22e3a0dc..cfe14f06 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,7 +1,40 @@
Changelog
=========
-6.1.11 (unreleased)
+6.1.15 (unreleased)
+-------------------
+
+- Nothing changed yet.
+
+
+6.1.14 (2024-02-20)
+-------------------
+
+- Fix in @scadenziario endpoint: return future events if afterToday criteria is set.
+ [cekk]
+- Set base view to News Item, to do not break on Classic Plone.
+ [cekk]
+- Change description for field sede in UnitaOrganizzativa CT.
+- Fixed typo in update_note field description.
+ [eikichi18]
+
+
+
+6.1.13 (2024-02-08)
+-------------------
+
+- Handle missing `show_dynamic_folders_in_footer` in registry entry.
+ [cekk]
+
+
+6.1.12 (2024-02-06)
+-------------------
+
+- Remove un-needed commit in upgrade-step.
+ [cekk]
+
+
+6.1.11 (2024-01-29)
-------------------
- Added new indexer, catalog index and query operation for canale_digitale_link field of Servizio CT
@@ -13,6 +46,11 @@ Changelog
[cekk]
- Add enhancedlinks infos in File field serializer.
[cekk]
+- Add new flag in settings needed to choose to show or not auto-generated footer columns.
+ [cekk]
+- Customize @navigation endpoint to expose also the new flag for frontend.
+ [cekk]
+
6.1.10 (2024-01-16)
-------------------
diff --git a/README.md b/README.md
index c1580770..ab5124c1 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@
- [Design Plone Content-types](#design-plone-content-types)
- [Features](#features)
-- [Compatibilità](#compatibilit%C3%A0)
+- [Compatibilità](#compatibilità)
- [Tipi di contenuto](#tipi-di-contenuto)
- [Elenco tipi implementati](#elenco-tipi-implementati)
- [Bando](#bando)
@@ -30,10 +30,11 @@
- [Campi indicizzati nel SearchableText](#campi-indicizzati-nel-searchabletext-2)
- [Servizio](#servizio)
- [Campi indicizzati nel SearchableText](#campi-indicizzati-nel-searchabletext-3)
- - [Unità Organizzativa](#unit%C3%A0-organizzativa)
+ - [Unità Organizzativa](#unità-organizzativa)
- [Campi indicizzati nel SearchableText](#campi-indicizzati-nel-searchabletext-4)
- [Pannello di controllo](#pannello-di-controllo)
- [Gestione modulistica](#gestione-modulistica)
+- [Viste verifica contentuti](#viste-verifica-contentuti)
- [Data di modifica](#data-di-modifica)
- [Endpoint restapi](#endpoint-restapi)
- [Customizzazione dati relation field](#customizzazione-dati-relation-field)
@@ -421,6 +422,10 @@ Endpoint ed expansion per la modulistica.
Nei content-type CartellaModulistica, tra i vari expansion c'è anche `@modulistica_items`.
Questo è utile per la vista di frontend, in quanto se richiamato, ritorna la struttura di dati da mostrare in visualizzazione.
+## @navigation
+
+Endpoint customizzato da plone.restapi per esporre anche il valore show_in_footer per decidere se disegnare o meno le colonne dinamiche nel footer.
+
# Installazione
Questo prodotto non è stato pensato per funzionare da solo, ma fa parte della suite "design.plone".
diff --git a/setup.py b/setup.py
index 9399e5fa..02c87c81 100644
--- a/setup.py
+++ b/setup.py
@@ -16,7 +16,7 @@
setup(
name="design.plone.contenttypes",
- version="6.1.11.dev0",
+ version="6.1.15.dev0",
description="DesignItalia contenty types",
long_description=long_description,
long_description_content_type="text/markdown",
diff --git a/src/design/plone/contenttypes/behaviors/update_note.py b/src/design/plone/contenttypes/behaviors/update_note.py
index 113fe7f1..9e1d6f5b 100644
--- a/src/design/plone/contenttypes/behaviors/update_note.py
+++ b/src/design/plone/contenttypes/behaviors/update_note.py
@@ -18,7 +18,7 @@ class IUpdateNote(model.Schema):
description=_(
"help_update_note",
default="Inserisci una nota per indicare che il contenuto corrente è stato aggiornato." # noqa
- "Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare " # noqa
+ " Questo testo può essere visualizzato nei blocchi elenco con determinati layout per informare " # noqa
"gli utenti che un determinato contenuto è stato aggiornato. "
"Ad esempio se in un bando sono stati aggiunti dei documenti.",
),
diff --git a/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.newsitem.pt b/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.newsitem.pt
deleted file mode 100644
index 53d14271..00000000
--- a/src/design/plone/contenttypes/browser/overrides/plone.app.contenttypes.browser.templates.newsitem.pt
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/design/plone/contenttypes/controlpanels/settings.py b/src/design/plone/contenttypes/controlpanels/settings.py
index 60beed41..365b8135 100644
--- a/src/design/plone/contenttypes/controlpanels/settings.py
+++ b/src/design/plone/contenttypes/controlpanels/settings.py
@@ -88,6 +88,16 @@ class IDesignPloneSettings(Interface):
default=True,
required=False,
)
+ show_dynamic_folders_in_footer = Bool(
+ title=_("show_dynamic_folders_in_footer_label", default="Footer dinamico"),
+ description=_(
+ "show_dynamic_folders_in_footer_help",
+ default="Se selezionato, il footer verrà popolato automaticamente "
+ "con i contenuti di primo livello non esclusi dalla navigazione.",
+ ),
+ default=True,
+ required=False,
+ )
class DesignPloneControlPanelForm(RegistryEditForm):
diff --git a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py
index 12e1bfad..b54570f1 100644
--- a/src/design/plone/contenttypes/interfaces/unita_organizzativa.py
+++ b/src/design/plone/contenttypes/interfaces/unita_organizzativa.py
@@ -97,10 +97,8 @@ class IUnitaOrganizzativa(model.Schema, IDesignPloneContentType):
description=_(
"sede_help",
default="Seleziona il Luogo in cui questa struttura ha sede. "
- "Se non è presente un contenuto di tipo Luogo a cui far "
- "riferimento, puoi compilare i campi seguenti. Se selezioni un "
- "Luogo, puoi usare comunque i campi seguenti per sovrascrivere "
- "alcune informazioni.",
+ "Se non è presente creare il Luogo nella sezione dedicata "
+ "nell'alberatura del sito.",
),
value_type=RelationChoice(
title=_("Sede"), vocabulary="plone.app.vocabularies.Catalog"
diff --git a/src/design/plone/contenttypes/profiles/default/metadata.xml b/src/design/plone/contenttypes/profiles/default/metadata.xml
index 715b70fe..d0c46e17 100644
--- a/src/design/plone/contenttypes/profiles/default/metadata.xml
+++ b/src/design/plone/contenttypes/profiles/default/metadata.xml
@@ -1,6 +1,6 @@
- 7030
+ 7040
profile-redturtle.bandi:default
profile-collective.venue:default
diff --git a/src/design/plone/contenttypes/profiles/default/types/Document.xml b/src/design/plone/contenttypes/profiles/default/types/Document.xml
index 56036477..30e528d3 100644
--- a/src/design/plone/contenttypes/profiles/default/types/Document.xml
+++ b/src/design/plone/contenttypes/profiles/default/types/Document.xml
@@ -4,6 +4,7 @@
name="Document"
i18n:domain="plone"
>
+
diff --git a/src/design/plone/contenttypes/profiles/default/types/Event.xml b/src/design/plone/contenttypes/profiles/default/types/Event.xml
index 412101c9..5edb1552 100644
--- a/src/design/plone/contenttypes/profiles/default/types/Event.xml
+++ b/src/design/plone/contenttypes/profiles/default/types/Event.xml
@@ -14,6 +14,7 @@
+
diff --git a/src/design/plone/contenttypes/profiles/default/types/News_Item.xml b/src/design/plone/contenttypes/profiles/default/types/News_Item.xml
index 1c0f6d9b..0da6ce08 100644
--- a/src/design/plone/contenttypes/profiles/default/types/News_Item.xml
+++ b/src/design/plone/contenttypes/profiles/default/types/News_Item.xml
@@ -17,6 +17,11 @@
+ view
+
+
+
+
diff --git a/src/design/plone/contenttypes/restapi/services/configure.zcml b/src/design/plone/contenttypes/restapi/services/configure.zcml
index 06d609df..e93dcc9d 100644
--- a/src/design/plone/contenttypes/restapi/services/configure.zcml
+++ b/src/design/plone/contenttypes/restapi/services/configure.zcml
@@ -6,9 +6,11 @@
+
-
+
+
+
+
+
+
+
+
diff --git a/src/design/plone/contenttypes/restapi/services/navigation/get.py b/src/design/plone/contenttypes/restapi/services/navigation/get.py
new file mode 100644
index 00000000..73550281
--- /dev/null
+++ b/src/design/plone/contenttypes/restapi/services/navigation/get.py
@@ -0,0 +1,32 @@
+from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings
+from design.plone.contenttypes.interfaces import IDesignPloneContenttypesLayer
+from plone import api
+from plone.restapi.interfaces import IExpandableElement
+from plone.restapi.services import Service
+from plone.restapi.services.navigation.get import Navigation as BaseNavigation
+from zope.component import adapter
+from zope.interface import implementer
+from zope.interface import Interface
+
+
+@implementer(IExpandableElement)
+@adapter(Interface, IDesignPloneContenttypesLayer)
+class Navigation(BaseNavigation):
+ def __call__(self, expand=False):
+ result = super().__call__(expand=expand)
+ try:
+ show_dynamic_folders_in_footer = api.portal.get_registry_record(
+ "show_dynamic_folders_in_footer",
+ interface=IDesignPloneSettings,
+ default=True,
+ )
+ except KeyError:
+ show_dynamic_folders_in_footer = True
+ result["navigation"]["show_in_footer"] = show_dynamic_folders_in_footer
+ return result
+
+
+class NavigationGet(Service):
+ def reply(self):
+ navigation = Navigation(self.context, self.request)
+ return navigation(expand=True)["navigation"]
diff --git a/src/design/plone/contenttypes/restapi/services/scadenziario/post.py b/src/design/plone/contenttypes/restapi/services/scadenziario/post.py
index 07ba6299..e19720c1 100644
--- a/src/design/plone/contenttypes/restapi/services/scadenziario/post.py
+++ b/src/design/plone/contenttypes/restapi/services/scadenziario/post.py
@@ -158,7 +158,13 @@ def reply(self):
if "start" in query_for_catalog:
start = query_for_catalog["start"]["query"]
if "end" in query_for_catalog:
- end = query_for_catalog["end"]["query"]
+ if query_for_catalog["end"].get("range", "") != "min":
+ # per esempio, è impostato il filtro "con fine evento da domani".
+ # se impostiamo un'end (la data di domani), poi nella generazione delle ricorrenze,
+ # vengono scartati tutti gli eventi che hanno una data di inizio nel futuro
+ # (https://github.com/plone/plone.event/blob/master/plone/event/recurrence.py#L141)
+ # perché la data della ricorrenza è maggiore di "until", che è quello che qui inviamo come end.
+ end = query_for_catalog["end"]["query"]
expanded_events = self.expand_events(events, 3, start, end)
all_results = not_events + expanded_events
diff --git a/src/design/plone/contenttypes/tests/test_custom_service_navigation.py b/src/design/plone/contenttypes/tests/test_custom_service_navigation.py
new file mode 100644
index 00000000..014ad580
--- /dev/null
+++ b/src/design/plone/contenttypes/tests/test_custom_service_navigation.py
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+from design.plone.contenttypes.controlpanels.settings import IDesignPloneSettings
+from design.plone.contenttypes.testing import (
+ DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING,
+)
+from plone import api
+from plone.app.testing import setRoles
+from plone.app.testing import SITE_OWNER_NAME
+from plone.app.testing import SITE_OWNER_PASSWORD
+from plone.app.testing import TEST_USER_ID
+from plone.dexterity.utils import createContentInContainer
+from plone.restapi.testing import RelativeSession
+from transaction import commit
+
+import unittest
+
+
+class CustomNavigationTest(unittest.TestCase):
+ layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING
+
+ def setUp(self):
+ self.app = self.layer["app"]
+ self.portal = self.layer["portal"]
+ self.portal_url = self.portal.absolute_url()
+ self.api_session = RelativeSession(self.portal_url)
+ self.api_session.headers.update({"Accept": "application/json"})
+ self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)
+ setRoles(self.portal, TEST_USER_ID, ["Manager"])
+
+ self.folder = createContentInContainer(
+ self.portal, "Folder", id="folder", title="Some Folder"
+ )
+ self.folder2 = createContentInContainer(
+ self.portal, "Folder", id="folder2", title="Some Folder 2"
+ )
+ self.subfolder1 = createContentInContainer(
+ self.folder, "Folder", id="subfolder1", title="SubFolder 1"
+ )
+ self.subfolder2 = createContentInContainer(
+ self.folder, "Folder", id="subfolder2", title="SubFolder 2"
+ )
+ self.thirdlevelfolder = createContentInContainer(
+ self.subfolder1,
+ "Folder",
+ id="thirdlevelfolder",
+ title="Third Level Folder",
+ )
+ self.fourthlevelfolder = createContentInContainer(
+ self.thirdlevelfolder,
+ "Folder",
+ id="fourthlevelfolder",
+ title="Fourth Level Folder",
+ )
+ createContentInContainer(self.folder, "Document", id="doc1", title="A document")
+ commit()
+
+ def tearDown(self):
+ self.api_session.close()
+
+ def test_return_show_in_footer_info_based_on_registry(self):
+ # by default is True
+ response = self.api_session.get(
+ "/@navigation", params={"expand.navigation.depth": 2}
+ ).json()
+
+ self.assertIn("show_in_footer", response)
+ self.assertTrue(response["show_in_footer"])
+
+ # change it
+ api.portal.set_registry_record(
+ "show_dynamic_folders_in_footer",
+ False,
+ interface=IDesignPloneSettings,
+ )
+ commit()
+
+ response = self.api_session.get(
+ "/@navigation", params={"expand.navigation.depth": 2}
+ ).json()
+
+ self.assertIn("show_in_footer", response)
+ self.assertFalse(response["show_in_footer"])
diff --git a/src/design/plone/contenttypes/tests/test_service_scadenziario.py b/src/design/plone/contenttypes/tests/test_service_scadenziario.py
new file mode 100644
index 00000000..bdc56425
--- /dev/null
+++ b/src/design/plone/contenttypes/tests/test_service_scadenziario.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+from datetime import datetime
+from datetime import timedelta
+from design.plone.contenttypes.testing import (
+ DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING,
+)
+from plone import api
+from plone.app.testing import setRoles
+from plone.app.testing import SITE_OWNER_NAME
+from plone.app.testing import SITE_OWNER_PASSWORD
+from plone.app.testing import TEST_USER_ID
+from plone.restapi.testing import RelativeSession
+from transaction import commit
+
+import unittest
+
+
+class ScadenziarioTest(unittest.TestCase):
+ layer = DESIGN_PLONE_CONTENTTYPES_API_FUNCTIONAL_TESTING
+
+ def setUp(self):
+ self.app = self.layer["app"]
+ self.portal = self.layer["portal"]
+ self.request = self.layer["request"]
+ self.portal_url = self.portal.absolute_url()
+
+ self.api_session = RelativeSession(self.portal_url)
+ self.api_session.headers.update({"Accept": "application/json"})
+ self.api_session.auth = (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)
+
+ setRoles(self.portal, TEST_USER_ID, ["Manager"])
+
+ commit()
+
+ def tearDown(self):
+ self.api_session.close()
+
+ def test_return_future_events_if_query_is_end_after_today(self):
+ now = datetime.now()
+
+ # past event
+ api.content.create(
+ container=self.portal,
+ type="Event",
+ title="Past event",
+ start=now.replace(hour=8) + timedelta(days=-2),
+ end=now.replace(hour=18) + timedelta(days=-2),
+ )
+
+ future_event_1 = api.content.create(
+ container=self.portal,
+ type="Event",
+ title="Future event",
+ start=now.replace(hour=8) + timedelta(days=2),
+ end=now.replace(hour=18) + timedelta(days=4),
+ )
+ future_event_2 = api.content.create(
+ container=self.portal,
+ type="Event",
+ title="Future event that starts in the past",
+ start=now.replace(hour=8) + timedelta(days=-4),
+ end=now.replace(hour=18) + timedelta(days=4),
+ )
+
+ commit()
+
+ response = self.api_session.post(
+ f"{self.portal_url}/@scadenziario",
+ json={
+ "query": [
+ {
+ "i": "end",
+ "o": "plone.app.querystring.operation.date.afterToday",
+ "v": "",
+ }
+ ]
+ },
+ ).json()
+ self.assertEqual(len(response["items"]), 2)
+
+ # results are in asc order
+ self.assertEqual(
+ response["items"][0],
+ future_event_2.start.strftime("%Y/%m/%d"),
+ )
+ self.assertEqual(
+ response["items"][1],
+ future_event_1.start.strftime("%Y/%m/%d"),
+ )
diff --git a/src/design/plone/contenttypes/upgrades/configure.zcml b/src/design/plone/contenttypes/upgrades/configure.zcml
index 0c113620..fc780738 100644
--- a/src/design/plone/contenttypes/upgrades/configure.zcml
+++ b/src/design/plone/contenttypes/upgrades/configure.zcml
@@ -810,12 +810,22 @@
+
+
+
-
+
\ No newline at end of file
diff --git a/src/design/plone/contenttypes/upgrades/upgrades.py b/src/design/plone/contenttypes/upgrades/upgrades.py
index 71c8cd3a..c34b734b 100644
--- a/src/design/plone/contenttypes/upgrades/upgrades.py
+++ b/src/design/plone/contenttypes/upgrades/upgrades.py
@@ -1576,8 +1576,6 @@ def update_pdc_with_pdc_desc(context):
logger.info(f"Set pdc_desc for {pdc.absolute_url()}")
pdc.value_punto_contatto = value_punto_contatto
-
- commit()
logger.info("Ends of update")
@@ -1611,3 +1609,10 @@ def add_canale_digitale_link_index(context):
service.reindexObject(idxs=["canale_digitale_link"])
logger.info(f"Reindexed {service.absolute_url()}")
logger.info("End of update, added index canale_digitale_link")
+
+
+def to_7031(context):
+ portal_types = api.portal.get_tool(name="portal_types")
+ for ptype in ["News Item"]:
+ portal_types[ptype].default_view = "view"
+ portal_types[ptype].view_methods = ["view"]