io-sanita-theme 2.5.2 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.6.0](https://github.com/RedTurtle/io-sanita-theme/compare/2.5.3...2.6.0) (2025-03-11)
4
+
5
+ ### Features
6
+
7
+ * added all listing variation to Search block ([100880f](https://github.com/RedTurtle/io-sanita-theme/commit/100880f76bcccab88f4055eef6a8a996bc4bc108))
8
+
9
+ ### Bug Fixes
10
+
11
+ * a11y Bando and Event dates ([233d8d1](https://github.com/RedTurtle/io-sanita-theme/commit/233d8d10bd6e6c606fbc79f2b7f4c46196cf5b2a))
12
+
13
+ ## [2.5.3](https://github.com/RedTurtle/io-sanita-theme/compare/2.5.2...2.5.3) (2025-03-05)
14
+
15
+ ### Bug Fixes
16
+
17
+ * scroll bhv in paginations ([00b84e9](https://github.com/RedTurtle/io-sanita-theme/commit/00b84e9e2d8386552632fa92b968e59485638d1d))
18
+
3
19
  ## [2.5.2](https://github.com/RedTurtle/io-sanita-theme/compare/2.5.1...2.5.2) (2025-03-05)
4
20
 
5
21
  ### Bug Fixes
package/RELEASE.md CHANGED
@@ -41,6 +41,12 @@
41
41
  - ...
42
42
  -->
43
43
 
44
+ ## Versione x.x.x (x/x/x)
45
+
46
+ ### Novità
47
+
48
+ - ora nel blocco Cerca, è possibile selezionare tutte le variazioni del blocco elenco come aspetto dei risultati.
49
+
44
50
  ## Versione 2.5.0 (05/03/2025)
45
51
 
46
52
  ### Novità
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "io-sanita-theme",
3
- "version": "2.5.2",
3
+ "version": "2.6.0",
4
4
  "description": "io-sanita-theme: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "license": "MIT",
@@ -10,6 +10,7 @@ import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
10
10
  import { BandiTemplate } from 'io-sanita-theme/components/Blocks';
11
11
  import { Pagination } from 'io-sanita-theme/components';
12
12
  import { resetQuerystringResults } from 'io-sanita-theme/actions';
13
+ import { scrollIntoView } from 'io-sanita-theme/helpers';
13
14
 
14
15
  const messages = defineMessages({
15
16
  find: {
@@ -146,8 +147,9 @@ const Body = ({ data, id, inEditMode, path, onChangeBlock, blocksConfig }) => {
146
147
  );
147
148
 
148
149
  function handleQueryPaginationChange(e, { activePage }) {
149
- resultsRef.current.scrollIntoView({ behavior: 'smooth' });
150
- const current = activePage?.children ?? 1;
150
+ scrollIntoView({ ref: resultsRef.current });
151
+
152
+ const current = activePage?.children ?? activePage ?? 1;
151
153
  setCurrentPage(current);
152
154
  doRequest(current);
153
155
  }
@@ -14,6 +14,7 @@ import SearchFilters from './SearchFilters';
14
14
 
15
15
  /* Style */
16
16
  import './search-farmacia.scss';
17
+ import { scrollIntoView } from 'io-sanita-theme/helpers';
17
18
 
18
19
  const messages = defineMessages({
19
20
  results: {
@@ -205,7 +206,7 @@ const Body = ({ isEditMode, data, id }) => {
205
206
  activeScroll = true,
206
207
  ) => {
207
208
  if (resultsRef.current && activeScroll) {
208
- resultsRef.current.scrollIntoView({ behavior: 'smooth' });
209
+ scrollIntoView({ ref: resultsRef.current });
209
210
  }
210
211
  setCurrentPage(activePage || 1);
211
212
  };
@@ -15,6 +15,7 @@ import {
15
15
  SortByWidget,
16
16
  LinkedHeadline,
17
17
  } from 'io-sanita-theme/components';
18
+ import { scrollIntoView } from 'io-sanita-theme/helpers';
18
19
 
19
20
  const messages = defineMessages({
20
21
  results: {
@@ -190,7 +191,7 @@ const Body = ({ data, id, path, properties, inEditMode }) => {
190
191
  activeScroll = true,
191
192
  ) => {
192
193
  if (resultsRef.current && activeScroll) {
193
- resultsRef.current.scrollIntoView({ behavior: 'smooth' });
194
+ scrollIntoView({ ref: resultsRef.current });
194
195
  }
195
196
  const current = activePage ?? 1;
196
197
  setCurrentPage(current);
@@ -237,6 +238,7 @@ const Body = ({ data, id, path, properties, inEditMode }) => {
237
238
  (data.portal_type === 'Servizio'
238
239
  ? intl.formatMessage(messages.searchable_text_default_label_servizi)
239
240
  : intl.formatMessage(messages.searchable_text_default_label_procedura));
241
+
240
242
  return (
241
243
  <div className="block iosanita-block-search servizi-procedure">
242
244
  <div className="full-width bg-primary-lightest py-4">
@@ -30,6 +30,7 @@ export const CardSimple = ({
30
30
  titleTag = 'h5',
31
31
  titleDataElement,
32
32
  highlight, //se si vuole evidenziare un testo, ad esempio nei risultati delle ricerche
33
+ badgeText,
33
34
  }) => {
34
35
  const intl = useIntl();
35
36
  const date =
@@ -61,11 +62,13 @@ export const CardSimple = ({
61
62
  ) : (
62
63
  item.description
63
64
  );
65
+
66
+ const display_badge = isServizioOnline || badgeText?.length > 0;
64
67
  return (
65
68
  <Card className={`shadow rounded no-after card-simple ${className ?? ''}`}>
66
69
  <CardBody>
67
70
  <div className="card-body-main">
68
- <CardTitle tag={titleTag} className={isServizioOnline ? 'mb-1' : ''}>
71
+ <CardTitle tag={titleTag} className={display_badge ? 'mb-1' : ''}>
69
72
  {item['@id'] ? (
70
73
  <UniversalLink
71
74
  item={!isEditMode ? item : null}
@@ -80,11 +83,13 @@ export const CardSimple = ({
80
83
  )}
81
84
  </CardTitle>
82
85
 
83
- {/* Chip servizio attivo */}
84
- {isServizioOnline && (
86
+ {/* Chip badge: servizio attivo per servizi o badge con badgeText */}
87
+ {display_badge && (
85
88
  <div className={showDescription ? 'mb-3' : ''}>
86
89
  <Badge color="info">
87
- {intl.formatMessage(messages.servizioOnline)}
90
+ {isServizioOnline
91
+ ? intl.formatMessage(messages.servizioOnline)
92
+ : badgeText}
88
93
  </Badge>
89
94
  </div>
90
95
  )}
@@ -90,11 +90,14 @@ const BandoDates = ({ content }) => {
90
90
  return (
91
91
  item.date && (
92
92
  <div className="point-list" key={index}>
93
- <div className="point-list-aside point-list-warning">
94
- <span className="point-date text-monospace">
93
+ <div
94
+ className="point-list-aside point-list-warning"
95
+ aria-label={item.date.format('DD MMMM Y')}
96
+ >
97
+ <span className="point-date text-monospace" aria-hidden={true}>
95
98
  {item.date.format('DD')}
96
99
  </span>
97
- <span className="point-month text-monospace">
100
+ <span className="point-month text-monospace" aria-hidden={true}>
98
101
  {item.date.format('MMM')}/{item.date.format('YY')}
99
102
  </span>
100
103
  </div>
@@ -80,13 +80,20 @@ const Dates = ({ content, show_image, moment: momentlib, rrule }) => {
80
80
  <>
81
81
  <div className="point-list-wrapper my-4 mb-5">
82
82
  <div className="point-list">
83
- <div className="point-list-aside point-list-primary fw-normal">
84
- <span className="point-date font-monospace">
83
+ <div
84
+ className="point-list-aside point-list-primary fw-normal"
85
+ aria-label={start.format('DD MMMM Y')}
86
+ >
87
+ <span className="point-date font-monospace" aria-hidden={true}>
85
88
  {start.format('DD')}
86
89
  </span>
87
- <span className="point-month font-monospace">{start.format('MMMM')}</span>
90
+ <span className="point-month font-monospace" aria-hidden={true}>
91
+ {start.format('MMMM')}
92
+ </span>
88
93
  {!start.isSame(end, 'year') && (
89
- <span className="point-month font-monospace">{start.format('YYYY')}</span>
94
+ <span className="point-month font-monospace" aria-hidden={true}>
95
+ {start.format('YYYY')}
96
+ </span>
90
97
  )}
91
98
  </div>
92
99
  <div className="point-list-content">
@@ -111,15 +118,18 @@ const Dates = ({ content, show_image, moment: momentlib, rrule }) => {
111
118
  </div>
112
119
  {!openEnd && (
113
120
  <div className="point-list">
114
- <div className="point-list-aside point-list-primary fw-normal">
115
- <span className="point-date font-monospace">
121
+ <div
122
+ className="point-list-aside point-list-primary fw-normal"
123
+ aria-label={end.format('DD MMMM Y')}
124
+ >
125
+ <span className="point-date font-monospace" aria-hidden={true}>
116
126
  {end.format('DD')}
117
127
  </span>
118
- <span className="point-month font-monospace">
128
+ <span className="point-month font-monospace" aria-hidden={true}>
119
129
  {end.format('MMMM')}
120
130
  </span>
121
131
  {!end.isSame(start, 'year') && (
122
- <span className="point-month font-monospace">
132
+ <span className="point-month font-monospace" aria-hidden={true}>
123
133
  {end.format('YYYY')}
124
134
  </span>
125
135
  )}
@@ -149,7 +159,7 @@ const Dates = ({ content, show_image, moment: momentlib, rrule }) => {
149
159
  {additionalDates.length > 0 && (
150
160
  <div className="mt-4">
151
161
  <h5>{intl.formatMessage(messages.additional_dates)}</h5>
152
- {additionalDates.map((additionalDate,i) => (
162
+ {additionalDates.map((additionalDate, i) => (
153
163
  <div className="font-serif" key={i}>
154
164
  {viewDate(intl.locale, additionalDate, 'dddd DD MMMM YYYY')}
155
165
  </div>
@@ -159,8 +169,8 @@ const Dates = ({ content, show_image, moment: momentlib, rrule }) => {
159
169
  {exdates.length > 0 && (
160
170
  <div className="mt-4">
161
171
  <h5>{intl.formatMessage(messages.excluded_dates)}</h5>
162
- {exdates.map((exDate,i) => (
163
- <div className="font-serif" key={'exdate'+i}>
172
+ {exdates.map((exDate, i) => (
173
+ <div className="font-serif" key={'exdate' + i}>
164
174
  {viewDate(intl.locale, exDate, 'dddd DD MMMM YYYY')}
165
175
  </div>
166
176
  ))}
@@ -15,6 +15,7 @@ import {
15
15
  AccordionHeader,
16
16
  } from 'design-react-kit';
17
17
  import config from '@plone/volto/registry';
18
+ import { scrollIntoView, getMainOffset } from 'io-sanita-theme/helpers';
18
19
  import './_sideMenu.scss';
19
20
 
20
21
  const messages = defineMessages({
@@ -91,14 +92,6 @@ const SideMenu = ({ data, content_uid }) => {
91
92
  headers?.[0]?.title ??
92
93
  intl.formatMessage(messages.progressBar);
93
94
 
94
- const getMainOffset = () => {
95
- return isClient
96
- ? document.querySelector('.it-header-wrapper.it-header-sticky')
97
- ?.clientHeight + 20
98
- : 0;
99
- };
100
- const mainOffset = getMainOffset();
101
-
102
95
  const handleScroll = useCallback(() => {
103
96
  const windowHeight = window.innerHeight * 0.1;
104
97
  const mainOffset = getMainOffset();
@@ -161,16 +154,8 @@ const SideMenu = ({ data, content_uid }) => {
161
154
  // Scroll to section
162
155
  // setTimeout hack should wait for rerender after setIsNavOpen
163
156
  setTimeout(() => {
164
- // document.getElementById(id)?.scrollIntoView?.({
165
- // behavior: 'smooth',
166
- // block: 'start',
167
- // });
168
-
169
- window.scrollTo({
170
- behavior: 'smooth',
171
- top: document.querySelector('#' + id).offsetTop - mainOffset,
172
- });
173
- }, 0);
157
+ scrollIntoView({ id });
158
+ });
174
159
  };
175
160
 
176
161
  const progressValue = useMemo(() => {
@@ -180,6 +165,8 @@ const SideMenu = ({ data, content_uid }) => {
180
165
  : 0;
181
166
  }, [scrollY, isClient]);
182
167
 
168
+ const mainOffset = getMainOffset();
169
+
183
170
  return headers?.length > 0 ? (
184
171
  <div
185
172
  className="navbar-wrapper page-side-menu affix-top"
@@ -74,6 +74,11 @@ export const applyIoSanitaBlocksConfig = (config) => {
74
74
  delete config.blocks.blocksConfig.teaser;
75
75
  delete config.blocks.blocksConfig.leadimage;
76
76
 
77
+ const listingVariations = [
78
+ ...config.blocks.blocksConfig.listing.variations,
79
+ ...getIoSanitaListingVariations(config),
80
+ ];
81
+
77
82
  config.blocks.blocksConfig = {
78
83
  ...config.blocks.blocksConfig,
79
84
 
@@ -81,10 +86,7 @@ export const applyIoSanitaBlocksConfig = (config) => {
81
86
  ...config.blocks.blocksConfig.listing,
82
87
  showLinkMore: true,
83
88
  blockSchema: schemaListing,
84
- variations: [
85
- ...config.blocks.blocksConfig.listing.variations,
86
- ...getIoSanitaListingVariations(config),
87
- ],
89
+ variations: listingVariations,
88
90
  listing_bg_colors: [], //{name:'blue', label:'Blu'},{name:'light-blue', label:'Light blue'},{name:'sidebar-background', label:'Grey'}
89
91
  listing_items_colors: [], //{name:'blue', label:'Blu'},{name:'light-blue', label:'Light blue'},{name:'sidebar-background', label:'Grey'}
90
92
  getAsyncData: null, // questo disabilita il ssr dei listing perché rallenta vistosamente la pagina
@@ -280,7 +282,9 @@ export const applyIoSanitaBlocksConfig = (config) => {
280
282
  },
281
283
  search: {
282
284
  ...config.blocks.blocksConfig.search,
283
- templates: ['simpleCard', 'simpleListTemplate'],
285
+ templates: [
286
+ ...listingVariations.map((v) => v.id).filter((v) => v !== 'carousel'),
287
+ ],
284
288
  },
285
289
  searchMap: {
286
290
  id: 'searchMap',
@@ -26,7 +26,10 @@ import {
26
26
  ListingContainer,
27
27
  //getPathFiltersButtons,
28
28
  } from 'io-sanita-theme/components/Blocks';
29
- import { checkRichTextHasContent } from 'io-sanita-theme/helpers';
29
+ import {
30
+ checkRichTextHasContent,
31
+ scrollIntoView,
32
+ } from 'io-sanita-theme/helpers';
30
33
  import config from '@plone/volto/registry';
31
34
 
32
35
  const Headline = ({ headlineTag, id, data = {}, listingItems, isEditMode }) => {
@@ -207,8 +210,8 @@ const ListingBody = withQuerystringResults((props) => {
207
210
  }
208
211
 
209
212
  if (!isEditMode && page != currentPage) {
210
- listingRef.current.scrollIntoView({
211
- behavior: 'smooth',
213
+ scrollIntoView({
214
+ ref: listingRef.current,
212
215
  });
213
216
  }
214
217
  onPaginationChange(e, {
@@ -1,4 +1,5 @@
1
1
  import React, { useEffect, useState, createRef } from 'react';
2
+ import { scrollIntoView } from 'io-sanita-theme/helpers';
2
3
 
3
4
  export const useClientPagination = ({ items, b_size = 4 }) => {
4
5
  const [currentPage, setCurrentPage] = useState(1);
@@ -16,9 +17,7 @@ export const useClientPagination = ({ items, b_size = 4 }) => {
16
17
  const onPaginationChange = (activePage) => {
17
18
  let page = activePage;
18
19
  if (page != currentPage && ref?.current) {
19
- ref.current.scrollIntoView({
20
- behavior: 'smooth',
21
- });
20
+ scrollIntoView({ ref: ref.current });
22
21
  }
23
22
  setCurrentPage(page);
24
23
  };
@@ -81,3 +81,6 @@ export { getComponentWithFallback } from 'io-sanita-theme/helpers/registry';
81
81
  export SchemaOrg, {
82
82
  SchemaOrgUtils,
83
83
  } from 'io-sanita-theme/helpers/SchemaOrg/SchemaOrg';
84
+
85
+ //scroll
86
+ export { scrollIntoView, getMainOffset } from 'io-sanita-theme/helpers/scroll';
@@ -0,0 +1,22 @@
1
+ /* scrollIntoView:
2
+ pass ref prop (reactRef) or html id if item
3
+ */
4
+ export const getMainOffset = () => {
5
+ return __CLIENT__
6
+ ? document.querySelector('.it-header-wrapper.it-header-sticky')
7
+ ?.clientHeight + 20
8
+ : 0;
9
+ };
10
+
11
+ export const scrollIntoView = ({ ref, id, behavior = 'smooth' }) => {
12
+ const mainOffset = getMainOffset();
13
+
14
+ const top = id
15
+ ? document.querySelector('#' + id).offsetTop - mainOffset
16
+ : ref.getBoundingClientRect().top + window.scrollY - mainOffset;
17
+
18
+ window.scrollTo({
19
+ behavior,
20
+ top: top,
21
+ });
22
+ };