imio.smartweb.core 1.2.70__py3-none-any.whl → 1.2.75__py3-none-any.whl
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.
- imio/smartweb/core/browser/controlpanel.py +2 -0
- imio/smartweb/core/contents/pages/configure.zcml +1 -0
- imio/smartweb/core/contents/pages/views.py +41 -0
- imio/smartweb/core/contents/sections/contact/utils.py +2 -0
- imio/smartweb/core/contents/sections/contact/view.py +28 -12
- imio/smartweb/core/contents/sections/events/view.py +1 -1
- imio/smartweb/core/contents/sections/news/view.py +1 -1
- imio/smartweb/core/rest/authentic_sources.py +15 -2
- imio/smartweb/core/tests/test_section_contact.py +42 -10
- imio/smartweb/core/vocabularies.py +2 -1
- imio/smartweb/core/webcomponents/build/css/smartweb-webcomponents-compiled.css +1 -1
- imio/smartweb/core/webcomponents/build/js/373.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/486.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/884.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/src/components/Annuaire/ContactContent/ContactContent.jsx +26 -2
- imio/smartweb/core/webcomponents/src/components/Events/EventContent/EventContent.jsx +6 -1
- imio/smartweb/core/webcomponents/src/components/News/NewsCard/NewsCard.jsx +2 -2
- imio/smartweb/core/webcomponents/src/index.scss +9 -0
- {imio.smartweb.core-1.2.70.dist-info → imio.smartweb.core-1.2.75.dist-info}/METADATA +48 -1
- {imio.smartweb.core-1.2.70.dist-info → imio.smartweb.core-1.2.75.dist-info}/RECORD +26 -26
- {imio.smartweb.core-1.2.70.dist-info → imio.smartweb.core-1.2.75.dist-info}/WHEEL +1 -1
- /imio.smartweb.core-1.2.70-py3.12-nspkg.pth → /imio.smartweb.core-1.2.75-py3.12-nspkg.pth +0 -0
- {imio.smartweb.core-1.2.70.dist-info → imio.smartweb.core-1.2.75.dist-info}/LICENSE.GPL +0 -0
- {imio.smartweb.core-1.2.70.dist-info → imio.smartweb.core-1.2.75.dist-info}/LICENSE.rst +0 -0
- {imio.smartweb.core-1.2.70.dist-info → imio.smartweb.core-1.2.75.dist-info}/namespace_packages.txt +0 -0
- {imio.smartweb.core-1.2.70.dist-info → imio.smartweb.core-1.2.75.dist-info}/top_level.txt +0 -0
@@ -171,11 +171,13 @@ class ISmartwebControlPanel(Interface):
|
|
171
171
|
description=_(
|
172
172
|
"For staging : https://conseil.staging.imio.be | for production : https://www.deliberations.be"
|
173
173
|
),
|
174
|
+
default="https://www.deliberations.be",
|
174
175
|
required=False,
|
175
176
|
)
|
176
177
|
|
177
178
|
iadeliberations_api_username = schema.TextLine(
|
178
179
|
title=_("Username to consume I.A. Deliberations API"),
|
180
|
+
default="wsviewersmartweb",
|
179
181
|
required=False,
|
180
182
|
)
|
181
183
|
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
from Acquisition import aq_inner
|
4
|
+
from imio.smartweb.core.config import DIRECTORY_URL
|
4
5
|
from imio.smartweb.core.utils import get_scale_url
|
5
6
|
from imio.smartweb.core.interfaces import IHtmxViewUtils
|
6
7
|
from imio.smartweb.core.interfaces import IViewWithoutLeadImage
|
8
|
+
from imio.smartweb.core.utils import get_json
|
7
9
|
from imio.smartweb.locales import SmartwebMessageFactory as _
|
8
10
|
from Products.CMFPlone.resources import add_bundle_on_request
|
9
11
|
from plone import api
|
@@ -11,11 +13,14 @@ from plone.app.content.browser.contents.rearrange import OrderContentsBaseAction
|
|
11
13
|
from plone.app.content.utils import json_loads
|
12
14
|
from plone.app.contenttypes.browser.folder import FolderView
|
13
15
|
from plone.app.contenttypes.browser.full_view import FullViewItem as BaseFullViewItem
|
16
|
+
from plone.memoize.view import memoize
|
14
17
|
from Products.CMFPlone import utils
|
15
18
|
from Products.CMFPlone.browser.navigation import PhysicalNavigationBreadcrumbs
|
16
19
|
from zope.component import getMultiAdapter
|
17
20
|
from zope.interface import implementer
|
18
21
|
|
22
|
+
import itertools
|
23
|
+
|
19
24
|
|
20
25
|
@implementer(IViewWithoutLeadImage)
|
21
26
|
@implementer(IHtmxViewUtils)
|
@@ -46,6 +51,42 @@ class PagesView(FolderView):
|
|
46
51
|
add_bundle_on_request(self.request, "flexbin")
|
47
52
|
return self.index()
|
48
53
|
|
54
|
+
@memoize
|
55
|
+
def get_page_contacts(self):
|
56
|
+
# TODO We need to check every tests to be sure to avoid caching that
|
57
|
+
# creates false positive assertions
|
58
|
+
sections_contacts = self.context.listFolderContents(
|
59
|
+
contentFilter={
|
60
|
+
"portal_type": [
|
61
|
+
"imio.smartweb.SectionContact",
|
62
|
+
]
|
63
|
+
}
|
64
|
+
)
|
65
|
+
if len(sections_contacts) == 0:
|
66
|
+
return None
|
67
|
+
nested_contact_list = [
|
68
|
+
section_contacts.related_contacts
|
69
|
+
for section_contacts in sections_contacts
|
70
|
+
if section_contacts.related_contacts is not None
|
71
|
+
]
|
72
|
+
if nested_contact_list == []:
|
73
|
+
return None
|
74
|
+
# Make a "set" to simplifying request in url (avoid duplicate uid)
|
75
|
+
# Sometimes we have duplicate uid because some pages were build with contact attributes
|
76
|
+
# in a section and for layout issues,for the same contact, others attributes are in another section.
|
77
|
+
page_contacts = list(
|
78
|
+
set(list(itertools.chain.from_iterable(nested_contact_list)))
|
79
|
+
)
|
80
|
+
uids = "&UID=".join(page_contacts)
|
81
|
+
url = "{}/@search?UID={}&fullobjects=1".format(DIRECTORY_URL, uids)
|
82
|
+
current_lang = api.portal.get_current_language()[:2]
|
83
|
+
if current_lang != "fr":
|
84
|
+
url = f"{url}&translated_in_{current_lang}=1"
|
85
|
+
json_data = get_json(url)
|
86
|
+
if json_data is None or len(json_data.get("items", [])) == 0:
|
87
|
+
return
|
88
|
+
return json_data
|
89
|
+
|
49
90
|
def results(self, **kwargs):
|
50
91
|
"""
|
51
92
|
Gets results for folder listings without taking care of friendly_types
|
@@ -69,6 +69,8 @@ class ContactProperties(ContactSchedule):
|
|
69
69
|
return json.dumps(geo_json)
|
70
70
|
|
71
71
|
def images(self, image_scale, nb_results_by_batch):
|
72
|
+
if "gallery" not in self.context.visible_blocks:
|
73
|
+
return
|
72
74
|
contact_url = self.contact["@id"]
|
73
75
|
query = "@search?portal_type=Image&path.depth=1&metadata_fields=modified"
|
74
76
|
images_url_request = "{}/{}".format(contact_url, query)
|
@@ -4,30 +4,46 @@ from imio.smartweb.core.config import DIRECTORY_URL
|
|
4
4
|
from imio.smartweb.core.contents.sections.contact.utils import ContactProperties
|
5
5
|
from imio.smartweb.core.contents.sections.views import HashableJsonSectionView
|
6
6
|
from imio.smartweb.core.utils import batch_results
|
7
|
-
from imio.smartweb.core.utils import get_json
|
8
7
|
from plone import api
|
8
|
+
from zope.component import queryMultiAdapter
|
9
9
|
|
10
10
|
|
11
11
|
class ContactView(HashableJsonSectionView):
|
12
12
|
"""Contact Section view"""
|
13
13
|
|
14
14
|
def contacts(self):
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
# Firstly, try to get contact from the container view
|
16
|
+
container_view = queryMultiAdapter(
|
17
|
+
(self.context.aq_parent, self.request), name="full_view"
|
18
|
+
)
|
19
|
+
self.json_data = container_view.get_page_contacts()
|
20
|
+
if self.json_data is None or len(self.json_data.get("items", [])) == 0:
|
21
|
+
return []
|
22
|
+
|
23
|
+
container_contacts = self.json_data.get("items")
|
24
|
+
results_items = [
|
25
|
+
contact
|
26
|
+
for contact in container_contacts
|
27
|
+
if contact["UID"] in self.context.related_contacts
|
28
|
+
]
|
29
|
+
index_map = {
|
30
|
+
value: index for index, value in enumerate(self.context.related_contacts)
|
31
|
+
}
|
32
|
+
results_items = sorted(results_items, key=lambda x: index_map[x["UID"]])
|
33
|
+
|
34
|
+
# construct JSON data as before WEBBDC-1265 to avoid hash differences
|
35
|
+
uids = "&UID=".join(self.context.related_contacts)
|
19
36
|
url = "{}/@search?UID={}&fullobjects=1".format(DIRECTORY_URL, uids)
|
20
37
|
current_lang = api.portal.get_current_language()[:2]
|
21
38
|
if current_lang != "fr":
|
22
39
|
url = f"{url}&translated_in_{current_lang}=1"
|
23
|
-
self.json_data =
|
40
|
+
self.json_data = {
|
41
|
+
"@id": url,
|
42
|
+
"items": results_items,
|
43
|
+
"items_total": len(results_items),
|
44
|
+
}
|
24
45
|
self.refresh_modification_date()
|
25
|
-
|
26
|
-
return
|
27
|
-
results = self.json_data.get("items")
|
28
|
-
index_map = {value: index for index, value in enumerate(related_contacts)}
|
29
|
-
results = sorted(results, key=lambda x: index_map[x["UID"]])
|
30
|
-
return batch_results(results, self.context.nb_contact_by_line)
|
46
|
+
return batch_results(results_items, self.context.nb_contact_by_line)
|
31
47
|
|
32
48
|
def get_contact_properties(self, json_dict):
|
33
49
|
return ContactProperties(json_dict, self.context)
|
@@ -51,7 +51,7 @@ class EventsView(CarouselOrTableSectionView, HashableJsonSectionView):
|
|
51
51
|
url = "{}/@events?{}".format(EVENTS_URL, "&".join(params))
|
52
52
|
self.json_data = get_json(url)
|
53
53
|
self.refresh_modification_date()
|
54
|
-
if self.json_data is None or len(self.json_data.get("items", [])) == 0:
|
54
|
+
if self.json_data is None or len(self.json_data.get("items", [])) == 0:
|
55
55
|
return []
|
56
56
|
linking_view_url = self.context.linking_rest_view.to_object.absolute_url()
|
57
57
|
image_scale = self.image_scale
|
@@ -47,7 +47,7 @@ class NewsView(CarouselOrTableSectionView, HashableJsonSectionView):
|
|
47
47
|
url = "{}/@search?{}".format(NEWS_URL, "&".join(params))
|
48
48
|
self.json_data = get_json(url)
|
49
49
|
self.refresh_modification_date()
|
50
|
-
if self.json_data is None or len(self.json_data.get("items", [])) == 0:
|
50
|
+
if self.json_data is None or len(self.json_data.get("items", [])) == 0:
|
51
51
|
return []
|
52
52
|
linking_view_url = self.context.linking_rest_view.to_object.absolute_url()
|
53
53
|
image_scale = self.image_scale
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
|
+
from imio.smartweb.common.utils import is_log_active
|
3
4
|
from imio.smartweb.core.config import DIRECTORY_URL
|
4
5
|
from imio.smartweb.core.config import EVENTS_URL
|
5
6
|
from imio.smartweb.core.config import NEWS_URL
|
@@ -12,9 +13,12 @@ from zope.interface import alsoProvides
|
|
12
13
|
from zope.interface import implementer
|
13
14
|
from zope.publisher.interfaces import IPublishTraverse
|
14
15
|
|
16
|
+
import logging
|
15
17
|
import os
|
16
18
|
import requests
|
17
19
|
|
20
|
+
logger = logging.getLogger("imio.smartweb.core")
|
21
|
+
|
18
22
|
|
19
23
|
@implementer(IPublishTraverse)
|
20
24
|
class BaseRequestForwarder(Service):
|
@@ -38,8 +42,17 @@ class BaseRequestForwarder(Service):
|
|
38
42
|
|
39
43
|
def forward_request(self, url):
|
40
44
|
method = self.request.method
|
41
|
-
token =
|
42
|
-
|
45
|
+
token = None
|
46
|
+
if method == "GET" and self.request.form.get("wcatoken") == "false":
|
47
|
+
headers = {"Accept": "application/json"}
|
48
|
+
else:
|
49
|
+
token = get_wca_token(self.client_id, self.client_secret)
|
50
|
+
headers = {"Accept": "application/json", "Authorization": token}
|
51
|
+
if is_log_active():
|
52
|
+
logger.info("======== Forwarding request to AUTHENTIC SOURCE =========")
|
53
|
+
logger.info(f"url to forward : {url} ({method})")
|
54
|
+
logger.info(f"token : {token}")
|
55
|
+
logger.info(f"headers : {headers}")
|
43
56
|
params = self.request.form
|
44
57
|
if method == "GET":
|
45
58
|
params = self.add_missing_metadatas(params)
|
@@ -8,6 +8,7 @@ from imio.smartweb.common.contact_utils import formatted_schedule
|
|
8
8
|
from imio.smartweb.common.contact_utils import get_schedule_for_today
|
9
9
|
from imio.smartweb.core.contents.sections.contact.utils import ContactProperties
|
10
10
|
from imio.smartweb.core.contents.sections.views import SECTION_ITEMS_HASH_KEY
|
11
|
+
from imio.smartweb.core.tests.utils import clear_cache
|
11
12
|
from imio.smartweb.core.testing import IMIO_SMARTWEB_CORE_FUNCTIONAL_TESTING
|
12
13
|
from imio.smartweb.core.testing import ImioSmartwebTestCase
|
13
14
|
from imio.smartweb.core.tests.utils import get_json
|
@@ -57,7 +58,8 @@ class TestSectionContact(ImioSmartwebTestCase):
|
|
57
58
|
view = queryMultiAdapter((self.page, self.request), name="full_view")
|
58
59
|
self.assertIn("My contact", view())
|
59
60
|
contact_view = queryMultiAdapter((contact, self.request), name="view")
|
60
|
-
self.
|
61
|
+
self.assertEqual(contact_view.contacts(), [])
|
62
|
+
|
61
63
|
authentic_contact_uid = "2dc381f0fb584381b8e4a19c84f53b35"
|
62
64
|
contact.related_contacts = [authentic_contact_uid]
|
63
65
|
contact_search_url = (
|
@@ -69,12 +71,13 @@ class TestSectionContact(ImioSmartwebTestCase):
|
|
69
71
|
authentic_contact_uid
|
70
72
|
)
|
71
73
|
m.get(contact_search_url, exc=requests.exceptions.ConnectTimeout)
|
72
|
-
self.
|
74
|
+
self.assertEqual(contact_view.contacts(), [])
|
73
75
|
m.get(contact_search_url, status_code=404)
|
74
|
-
self.
|
76
|
+
self.assertEqual(contact_view.contacts(), [])
|
75
77
|
m.get(contact_search_url, text=json.dumps(self.json_no_contact))
|
76
|
-
self.
|
78
|
+
self.assertEqual(contact_view.contacts(), [])
|
77
79
|
m.get(contact_search_url, text=json.dumps(self.json_contact))
|
80
|
+
clear_cache(self.request)
|
78
81
|
self.assertIsNotNone(contact_view.contacts())
|
79
82
|
json_contact = ContactProperties(self.json_contact.get("items")[0], contact)
|
80
83
|
self.assertEqual(json_contact.contact_type_class, "contact-type-organization")
|
@@ -113,6 +116,13 @@ class TestSectionContact(ImioSmartwebTestCase):
|
|
113
116
|
m.get(contact_images_url, text=json.dumps(self.json_contact_images))
|
114
117
|
self.assertIn("contact_gallery", view())
|
115
118
|
|
119
|
+
contact.visible_blocks = ["titles"]
|
120
|
+
json_contact = ContactProperties(self.json_contact.get("items")[0], contact)
|
121
|
+
images = json_contact.images(contact.image_scale, contact.nb_results_by_batch)
|
122
|
+
self.assertNotIn("contact_gallery", view())
|
123
|
+
self.assertIsNone(images)
|
124
|
+
|
125
|
+
contact.visible_blocks = ["titles", "gallery"]
|
116
126
|
json_contact = ContactProperties(self.json_contact.get("items")[0], contact)
|
117
127
|
images = json_contact.images(contact.image_scale, contact.nb_results_by_batch)
|
118
128
|
self.assertEqual(len(images[0]), 2)
|
@@ -130,6 +140,18 @@ class TestSectionContact(ImioSmartwebTestCase):
|
|
130
140
|
images = json_contact.images(contact.image_scale, contact.nb_results_by_batch)
|
131
141
|
self.assertIsNone(images)
|
132
142
|
|
143
|
+
@requests_mock.Mocker()
|
144
|
+
def test_sorted_contacts_are_empty(self, m):
|
145
|
+
# TODO Separate test test_sorted_contacts_is_none /
|
146
|
+
# test_sorted_contacts 'cause of Memoize ??!!
|
147
|
+
contact = api.content.create(
|
148
|
+
container=self.page,
|
149
|
+
type="imio.smartweb.SectionContact",
|
150
|
+
title="My contact",
|
151
|
+
)
|
152
|
+
contact_view = queryMultiAdapter((contact, self.request), name="view")
|
153
|
+
self.assertEqual(contact_view.contacts(), [])
|
154
|
+
|
133
155
|
@requests_mock.Mocker()
|
134
156
|
def test_sorted_contacts(self, m):
|
135
157
|
contact = api.content.create(
|
@@ -138,7 +160,6 @@ class TestSectionContact(ImioSmartwebTestCase):
|
|
138
160
|
title="My contact",
|
139
161
|
)
|
140
162
|
contact_view = queryMultiAdapter((contact, self.request), name="view")
|
141
|
-
self.assertIsNone(contact_view.contacts())
|
142
163
|
authentic_contact_uid = [
|
143
164
|
"2dc381f0fb584381b8e4a19c84f53b35",
|
144
165
|
"af7bd1f547034b24a2e0da16c0ba0358",
|
@@ -501,7 +522,9 @@ class TestSectionContact(ImioSmartwebTestCase):
|
|
501
522
|
"afternoonend": "",
|
502
523
|
"comments": "",
|
503
524
|
}
|
525
|
+
clear_cache(self.request)
|
504
526
|
m.get(contact_search_url, text=json.dumps(json_contact_empty_schedule))
|
527
|
+
view = queryMultiAdapter((self.page, self.request), name="full_view")
|
505
528
|
json_contact = ContactProperties(
|
506
529
|
json_contact_empty_schedule.get("items")[0], contact
|
507
530
|
)
|
@@ -549,7 +572,6 @@ class TestSectionContact(ImioSmartwebTestCase):
|
|
549
572
|
|
550
573
|
annotations = IAnnotations(contact)
|
551
574
|
self.assertIsNone(annotations.get(SECTION_ITEMS_HASH_KEY))
|
552
|
-
|
553
575
|
self.assertIsNotNone(contact_view.contacts())
|
554
576
|
hash_1 = annotations.get(SECTION_ITEMS_HASH_KEY)
|
555
577
|
self.assertIsNotNone(hash_1)
|
@@ -557,15 +579,25 @@ class TestSectionContact(ImioSmartwebTestCase):
|
|
557
579
|
|
558
580
|
sleep(1)
|
559
581
|
m.get(contact_search_url, text=json.dumps(self.json_no_contact))
|
560
|
-
self.
|
582
|
+
clear_cache(self.request)
|
583
|
+
contact_view = queryMultiAdapter((contact, self.request), name="view")
|
584
|
+
self.assertEqual(contact_view.contacts(), [])
|
585
|
+
# refresh_modification_date doesn't calculate when json_data is None
|
586
|
+
# For this section, this is the case
|
587
|
+
# For other sections, we get json_data with empty "items"
|
588
|
+
# Refactoring needed to ensure clarity ?
|
561
589
|
next_modification = self.page.ModificationDate()
|
562
590
|
hash_2 = annotations.get(SECTION_ITEMS_HASH_KEY)
|
563
|
-
self.
|
564
|
-
self.
|
591
|
+
self.assertEqual(hash_1, hash_2)
|
592
|
+
self.assertEqual(first_modification, next_modification)
|
565
593
|
|
566
594
|
sleep(1)
|
567
|
-
self.
|
595
|
+
contact_view = queryMultiAdapter((contact, self.request), name="view")
|
596
|
+
self.assertEqual(contact_view.contacts(), [])
|
568
597
|
last_modification = self.page.ModificationDate()
|
569
598
|
hash_3 = annotations.get(SECTION_ITEMS_HASH_KEY)
|
570
599
|
self.assertEqual(hash_2, hash_3)
|
571
600
|
self.assertEqual(next_modification, last_modification)
|
601
|
+
|
602
|
+
# TODO we should test with various contact sections containing
|
603
|
+
# contacts
|
@@ -636,7 +636,8 @@ SendInBlueButtonPosVocabulary = SendInBlueButtonPosVocabularyFactory()
|
|
636
636
|
class RemoteIADeliberationsInstitutionsVocabularyFactory:
|
637
637
|
def __call__(self, context=None):
|
638
638
|
iadeliberation_url = get_iadeliberation_url_from_registry()
|
639
|
-
|
639
|
+
# What a devilish request... Get institutions from deliberations. Come on !
|
640
|
+
url = f"{iadeliberation_url}/@search?portal_type=Institution&metadata_fields=UID&sort_on=sortable_title&b_size=666"
|
640
641
|
try:
|
641
642
|
json_institutions = get_iadeliberation_json(url)
|
642
643
|
return SimpleVocabulary(
|
@@ -1 +1 @@
|
|
1
|
-
.portaltype-imio-smartweb-directoryview #portal-breadcrumbs,.portaltype-imio-smartweb-directoryview #portal-breadcrumbs .breadcrumb,.portaltype-imio-smartweb-directoryview #portal-header{margin-bottom:0!important}.r-wrapper{position:relative}.r-wrapper figure{display:block}.r-actu-wrapper{padding-top:1rem}.r-result{position:relative}@media screen and (min-width:992px){.r-add-contact,.r-add-event,.r-add-news{bottom:0;padding-bottom:1rem;position:absolute;right:0}}.r-add-contact a,.r-add-event a,.r-add-news a{align-items:center;color:#2d2d2d;display:flex;flex-direction:row;gap:7px;text-decoration:none}.r-add-contact a:focus,.r-add-contact a:hover,.r-add-event a:focus,.r-add-event a:hover,.r-add-news a:focus,.r-add-news a:hover{text-decoration:underline}.r-list-item-link{inset:0!important;position:absolute!important}.r-list-item-group{margin:15px 0;position:relative}.r-list-item{align-items:stretch;display:flex;height:100%}.load-more-link{background:#0000;border:none;display:block;margin:0 auto}.r-content-description{font-weight:500}.r-wrapper .r-result-list .r-list-item-group .r-list-item .r-item-text{flex:min-content}.leaflet-popup{padding:0!important}.leaflet-container{opacity:1!important}.r-content-files{margin:2rem 0}.r-content-files-title{margin-bottom:1rem}.r-content-files .r-content-file{margin:1rem 0}.r-content-files .r-content-file-link{border:1px solid #e6e6e6;display:flex;gap:20px;justify-content:space-between;padding:1rem;text-decoration:none}.r-content-files .r-content-file-link:hover{border:1px solid #868686}.r-content-files span{display:block}.r-content-gallery{margin:2rem 0}.r-content-gallery.flexbin>*,.r-content-gallery.flexbin>*>img{height:226px}.lds-roller-container{background:#ffffffd1;bottom:0;left:0;position:absolute;right:0;top:0}.lds-roller{display:inline-block;height:80px;left:50%;position:absolute;top:5rem;transform:translate(-50%,-50%);width:80px;z-index:0}.lds-roller div{animation:lds-roller 1.2s cubic-bezier(.5,0,.5,1) infinite;transform-origin:40px 40px}.lds-roller div:after{background:#333;border-radius:50%;content:" ";display:block;height:7px;margin:-4px 0 0 -4px;position:absolute;width:7px}.lds-roller div:first-child{animation-delay:-36ms}.lds-roller div:first-child:after{left:63px;top:63px}.lds-roller div:nth-child(2){animation-delay:-72ms}.lds-roller div:nth-child(2):after{left:56px;top:68px}.lds-roller div:nth-child(3){animation-delay:-.108s}.lds-roller div:nth-child(3):after{left:48px;top:71px}.lds-roller div:nth-child(4){animation-delay:-.144s}.lds-roller div:nth-child(4):after{left:40px;top:72px}.lds-roller div:nth-child(5){animation-delay:-.18s}.lds-roller div:nth-child(5):after{left:32px;top:71px}.lds-roller div:nth-child(6){animation-delay:-.216s}.lds-roller div:nth-child(6):after{left:24px;top:68px}.lds-roller div:nth-child(7){animation-delay:-.252s}.lds-roller div:nth-child(7):after{left:17px;top:63px}.lds-roller div:nth-child(8){animation-delay:-.288s}.lds-roller div:nth-child(8):after{left:12px;top:56px}@keyframes lds-roller{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.r-content-figure{aspect-ratio:16/9;background-color:#000;position:relative}.r-content-figure-blur{background-position:50%;background-size:cover;height:100%;left:0;opacity:.8;position:absolute;top:0;width:100%}.r-content-figure-img{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);height:100%;object-fit:cover;object-position:center;position:absolute;width:100%}.r-content-img-blur{height:100%;left:0;position:absolute;top:0;width:100%}.img-cover,.r-content-img-blur{background-position:50%;background-size:cover}.img-contain{background-position:50%;background-repeat:no-repeat;background-size:contain;object-fit:contain;object-position:center}.no-search-item-img{background:#000;background-position:50%!important}.no-search-item-img,.r-search-img{background-color:#c9c9c9!important}.portaltype-imio-smartweb-directoryview #portal-breadcrumbs,.portaltype-imio-smartweb-directoryview #portal-header,.portaltype-imio-smartweb-eventsview #portal-breadcrumbs,.portaltype-imio-smartweb-eventsview #portal-header,.portaltype-imio-smartweb-newsview #portal-breadcrumbs,.portaltype-imio-smartweb-newsview #portal-header{margin-bottom:0!important}.edit-rest-elements{align-items:center;display:flex;flex-direction:column;padding:10px;position:absolute;right:5px;top:5px}.edit-rest-elements-content{top:10px}.edit-rest-elements-news{padding:10px}
|
1
|
+
.portaltype-imio-smartweb-directoryview #portal-breadcrumbs,.portaltype-imio-smartweb-directoryview #portal-breadcrumbs .breadcrumb,.portaltype-imio-smartweb-directoryview #portal-header{margin-bottom:0!important}.r-wrapper{position:relative}.r-wrapper figure{display:block}.r-actu-wrapper{padding-top:1rem}.r-result{position:relative}@media screen and (min-width:992px){.r-add-contact,.r-add-event,.r-add-news{bottom:0;padding-bottom:1rem;position:absolute;right:0}}.r-add-contact a,.r-add-event a,.r-add-news a{align-items:center;color:#2d2d2d;display:flex;flex-direction:row;gap:7px;text-decoration:none}.r-add-contact a:focus,.r-add-contact a:hover,.r-add-event a:focus,.r-add-event a:hover,.r-add-news a:focus,.r-add-news a:hover{text-decoration:underline}.r-list-item-link{inset:0!important;position:absolute!important}.r-list-item-group{margin:15px 0;position:relative}.r-list-item{align-items:stretch;display:flex;height:100%}.load-more-link{background:#0000;border:none;display:block;margin:0 auto}.r-content-description{font-weight:500}.r-wrapper .r-result-list .r-list-item-group .r-list-item .r-item-text{flex:min-content}.leaflet-popup{padding:0!important}.leaflet-container{opacity:1!important}.r-content-files{margin:2rem 0}.r-content-files-title{margin-bottom:1rem}.r-content-files .r-content-file{margin:1rem 0}.r-content-files .r-content-file-link{border:1px solid #e6e6e6;display:flex;gap:20px;justify-content:space-between;padding:1rem;text-decoration:none}.r-content-files .r-content-file-link:hover{border:1px solid #868686}.r-content-files .r-content-file-title{align-items:center;display:flex;gap:5px}.r-content-files .r-content-file-title-size{font-size:14px;opacity:.5}.r-content-files span{display:block}.r-content-gallery{margin:2rem 0}.r-content-gallery.flexbin>*,.r-content-gallery.flexbin>*>img{height:226px}.lds-roller-container{background:#ffffffd1;bottom:0;left:0;position:absolute;right:0;top:0}.lds-roller{display:inline-block;height:80px;left:50%;position:absolute;top:5rem;transform:translate(-50%,-50%);width:80px;z-index:0}.lds-roller div{animation:lds-roller 1.2s cubic-bezier(.5,0,.5,1) infinite;transform-origin:40px 40px}.lds-roller div:after{background:#333;border-radius:50%;content:" ";display:block;height:7px;margin:-4px 0 0 -4px;position:absolute;width:7px}.lds-roller div:first-child{animation-delay:-36ms}.lds-roller div:first-child:after{left:63px;top:63px}.lds-roller div:nth-child(2){animation-delay:-72ms}.lds-roller div:nth-child(2):after{left:56px;top:68px}.lds-roller div:nth-child(3){animation-delay:-.108s}.lds-roller div:nth-child(3):after{left:48px;top:71px}.lds-roller div:nth-child(4){animation-delay:-.144s}.lds-roller div:nth-child(4):after{left:40px;top:72px}.lds-roller div:nth-child(5){animation-delay:-.18s}.lds-roller div:nth-child(5):after{left:32px;top:71px}.lds-roller div:nth-child(6){animation-delay:-.216s}.lds-roller div:nth-child(6):after{left:24px;top:68px}.lds-roller div:nth-child(7){animation-delay:-.252s}.lds-roller div:nth-child(7):after{left:17px;top:63px}.lds-roller div:nth-child(8){animation-delay:-.288s}.lds-roller div:nth-child(8):after{left:12px;top:56px}@keyframes lds-roller{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.r-content-figure{aspect-ratio:16/9;background-color:#000;position:relative}.r-content-figure-blur{background-position:50%;background-size:cover;height:100%;left:0;opacity:.8;position:absolute;top:0;width:100%}.r-content-figure-img{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);height:100%;object-fit:cover;object-position:center;position:absolute;width:100%}.r-content-img-blur{height:100%;left:0;position:absolute;top:0;width:100%}.img-cover,.r-content-img-blur{background-position:50%;background-size:cover}.img-contain{background-position:50%;background-repeat:no-repeat;background-size:contain;object-fit:contain;object-position:center}.no-search-item-img{background:#000;background-position:50%!important}.no-search-item-img,.r-search-img{background-color:#c9c9c9!important}.portaltype-imio-smartweb-directoryview #portal-breadcrumbs,.portaltype-imio-smartweb-directoryview #portal-header,.portaltype-imio-smartweb-eventsview #portal-breadcrumbs,.portaltype-imio-smartweb-eventsview #portal-header,.portaltype-imio-smartweb-newsview #portal-breadcrumbs,.portaltype-imio-smartweb-newsview #portal-header{margin-bottom:0!important}.edit-rest-elements{align-items:center;display:flex;flex-direction:column;padding:10px;position:absolute;right:5px;top:5px}.edit-rest-elements-content{top:10px}.edit-rest-elements-news{padding:10px}
|