design-comuni-plone-theme 11.33.1 → 11.34.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.
Files changed (51) hide show
  1. package/.yarn/cache/@tanstack-react-table-npm-8.21.2-f809795b71-3cda97794c.zip +0 -0
  2. package/.yarn/cache/@tanstack-table-core-npm-8.21.2-0f1fa83089-21573388b2.zip +0 -0
  3. package/.yarn/cache/{tar-fs-npm-2.1.3-32d6d6fb31-8dd66c2077.zip → tar-fs-npm-2.1.4-90a454735f-a9e18e2e61.zip} +0 -0
  4. package/.yarn/cache/volto-blocks-widget-npm-3.4.7-1bc2eeb4b5-4350a9c54b.zip +0 -0
  5. package/.yarn/cache/{volto-form-block-npm-3.12.0-0e050cb6bf-878c6f6af8.zip → volto-form-block-npm-3.13.0-f978a02e9c-0ce41843f5.zip} +0 -0
  6. package/.yarn/install-state.gz +0 -0
  7. package/CHANGELOG.md +31 -0
  8. package/RELEASE.md +20 -0
  9. package/locales/de/LC_MESSAGES/volto.po +82 -2
  10. package/locales/en/LC_MESSAGES/volto.po +84 -4
  11. package/locales/es/LC_MESSAGES/volto.po +82 -2
  12. package/locales/fr/LC_MESSAGES/volto.po +82 -2
  13. package/locales/it/LC_MESSAGES/volto.po +84 -4
  14. package/locales/volto.pot +83 -3
  15. package/package.json +3 -3
  16. package/publiccode.yml +2 -2
  17. package/src/actions/contacts.js +13 -0
  18. package/src/actions/index.js +3 -0
  19. package/src/components/ItaliaTheme/Blocks/Common/SearchFilters/DateFilter.jsx +50 -44
  20. package/src/components/ItaliaTheme/Blocks/Common/SearchFilters/SelectFilter.jsx +3 -2
  21. package/src/components/ItaliaTheme/Blocks/Common/SearchFilters/TextFilter.jsx +44 -16
  22. package/src/components/ItaliaTheme/Blocks/Listing/BandiInEvidenceTemplate.jsx +2 -0
  23. package/src/components/ItaliaTheme/Blocks/Listing/CardWithSlideUpTextTemplate.jsx +4 -1
  24. package/src/components/ItaliaTheme/Blocks/Listing/RibbonCardTemplate.jsx +1 -0
  25. package/src/components/ItaliaTheme/Blocks/Listing/SimpleCard/Card/SimpleCardDefault.jsx +1 -0
  26. package/src/components/ItaliaTheme/Blocks/Listing/TemplatesSkeletons/BandiInEvidenceTemplateSkeleton.jsx +2 -0
  27. package/src/components/ItaliaTheme/ContactsBlock/ContactsBlock.jsx +77 -0
  28. package/src/components/ItaliaTheme/View/Commons/PageHeader/PageHeaderTassonomiaArgomenti.jsx +2 -2
  29. package/src/components/ItaliaTheme/index.js +4 -0
  30. package/src/components/ItaliaTheme/manage/Widgets/ConditionallyRequiredDateWidget.jsx +25 -0
  31. package/src/components/ItaliaTheme/manage/Widgets/ContactsWidget/ContactsConfigForm.jsx +90 -0
  32. package/src/components/ItaliaTheme/manage/Widgets/ContactsWidget/ContactsConfigWidget.jsx +394 -0
  33. package/src/components/SelectInput/SelectInput.jsx +7 -2
  34. package/src/config/Widgets/widgets.js +11 -0
  35. package/src/config/italiaConfig.js +3 -1
  36. package/src/customizations/volto/components/theme/Footer/Footer.jsx +8 -1
  37. package/src/customizations/volto-form-block/components/Edit.jsx +100 -49
  38. package/src/customizations/volto-form-block/components/Field.jsx +71 -62
  39. package/src/customizations/volto-form-block/components/FormResult.jsx +25 -18
  40. package/src/customizations/volto-form-block/components/FormView.jsx +192 -194
  41. package/src/customizations/volto-form-block/components/Sidebar.jsx +7 -172
  42. package/src/customizations/volto-form-block/components/View.jsx +9 -5
  43. package/src/overrideTranslations.jsx +7 -2
  44. package/src/reducers/contacts.js +38 -0
  45. package/src/reducers/index.js +2 -0
  46. package/src/theme/ItaliaTheme/Blocks/_form.scss +20 -1
  47. package/src/theme/ItaliaTheme/Blocks/common/_searchBlockFilters.scss +56 -0
  48. package/src/theme/ItaliaTheme/Components/_contactsBlock.scss +40 -0
  49. package/src/theme/ItaliaTheme/Widgets/_contactsConfigWidget.scss +39 -0
  50. package/src/theme/site.scss +2 -0
  51. package/.yarn/cache/volto-blocks-widget-npm-3.4.1-c4d451e2c2-4f5c183698.zip +0 -0
@@ -0,0 +1,394 @@
1
+ import { useState } from 'react';
2
+ import { useIntl, defineMessages } from 'react-intl';
3
+ import {
4
+ Icon,
5
+ Grid,
6
+ Menu,
7
+ Form,
8
+ Button,
9
+ Segment,
10
+ Header,
11
+ } from 'semantic-ui-react';
12
+
13
+ import Component from '@plone/volto/components/theme/Component/Component';
14
+ import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
15
+ import { TextWidget } from '@plone/volto/components';
16
+ import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
17
+
18
+ const messages = defineMessages({
19
+ add_contacts_path: {
20
+ id: 'add_contacts_path',
21
+ defaultMessage: 'Add contacts path',
22
+ },
23
+ root_path: {
24
+ id: 'root_path',
25
+ defaultMessage: 'Root path',
26
+ },
27
+ delete_button: {
28
+ id: 'delete_button',
29
+ defaultMessage: 'Delete',
30
+ },
31
+ contact_items_header: {
32
+ id: 'contact_items_header',
33
+ defaultMessage: 'Contact items',
34
+ },
35
+ move_menu_item_up: {
36
+ id: 'move_menu_item_up',
37
+ defaultMessage: 'Move menu item up',
38
+ },
39
+ move_menu_item_down: {
40
+ id: 'move_menu_item_down',
41
+ defaultMessage: 'Move menu item down',
42
+ },
43
+ add_contacts_item: {
44
+ id: 'add_contacts_item',
45
+ defaultMessage: 'Add contacts item',
46
+ },
47
+ empty_active_contacts_item: {
48
+ id: 'empty_active_contacts_item',
49
+ defaultMessage: 'Add a contact item',
50
+ },
51
+ empty_active_contacts_path: {
52
+ id: 'empty_active_contacts_path',
53
+ defaultMessage: 'Add a contacts path',
54
+ },
55
+ icon_list_help_text: {
56
+ id: 'icon_list_help_text',
57
+ defaultMessage: 'For a complete list of icon names, see:',
58
+ },
59
+ });
60
+
61
+ const defaultContactsItem = (title) => ({
62
+ title,
63
+ icon: '',
64
+ contact: '',
65
+ });
66
+
67
+ const defaultRootContacts = (title) => ({
68
+ rootPath: '/',
69
+ items: [defaultContactsItem(title)],
70
+ });
71
+
72
+ const defaultContactsConfiguration = [defaultRootContacts(`Tab 0`)];
73
+
74
+ const ContactsConfigWidget = ({ id, title, value, onChange }) => {
75
+ const intl = useIntl();
76
+
77
+ const [contactsConfiguration, setContactsConfiguration] = useState(
78
+ value ? JSON.parse(value) : defaultContactsConfiguration,
79
+ );
80
+ const [activeContact, setActiveContact] = useState(0);
81
+ const [activeContactItem, setActiveContactItem] = useState(0);
82
+
83
+ const handleChangeConfiguration = (value) => {
84
+ setContactsConfiguration(value);
85
+ onChange(id, JSON.stringify(value));
86
+ };
87
+
88
+ const addContactsPath = (e) => {
89
+ e.preventDefault();
90
+ const contactItemsNumber = contactsConfiguration.length;
91
+ const contactItem = `/tab${contactItemsNumber}`;
92
+ let newContactsConfiguration = [
93
+ ...contactsConfiguration,
94
+ {
95
+ ...defaultRootContacts(`Tab ${contactItemsNumber}`),
96
+ rootPath: contactItem,
97
+ },
98
+ ];
99
+
100
+ handleChangeConfiguration(newContactsConfiguration);
101
+ setActiveContact(newContactsConfiguration.length - 1);
102
+ };
103
+
104
+ const onChangeContactsPath = (index, menu) => {
105
+ let newContactsConfiguration = [...contactsConfiguration];
106
+ newContactsConfiguration[index] = menu;
107
+
108
+ handleChangeConfiguration(newContactsConfiguration);
109
+ };
110
+
111
+ const deleteContactsPath = (e, index) => {
112
+ e.preventDefault();
113
+ let newContactsConfiguration = [...contactsConfiguration];
114
+ newContactsConfiguration.splice(index, 1);
115
+
116
+ if (activeContact === index) {
117
+ setTimeout(() => setActiveContact(index > 0 ? index - 1 : 0), 0);
118
+ }
119
+
120
+ handleChangeConfiguration(newContactsConfiguration);
121
+ };
122
+
123
+ const moveContactsItem = (e, pathIndex, contactsItemIndex, direction) => {
124
+ e.preventDefault();
125
+ const up = direction === 'up';
126
+ let newContactsConfiguration = [...contactsConfiguration];
127
+
128
+ let contactsItem =
129
+ newContactsConfiguration[pathIndex].items[contactsItemIndex];
130
+ newContactsConfiguration[pathIndex].items.splice(contactsItemIndex, 1);
131
+ newContactsConfiguration[pathIndex].items.splice(
132
+ contactsItemIndex + (up ? -1 : 1),
133
+ 0,
134
+ contactsItem,
135
+ );
136
+
137
+ handleChangeConfiguration(newContactsConfiguration);
138
+ };
139
+
140
+ const addContactItem = (e, pathIndex) => {
141
+ e.preventDefault();
142
+ let newContactsConfiguration = [...contactsConfiguration];
143
+ newContactsConfiguration[pathIndex].items = [
144
+ ...newContactsConfiguration[pathIndex].items,
145
+ defaultContactsItem(
146
+ `New ${newContactsConfiguration[pathIndex].items.length}`,
147
+ ),
148
+ ];
149
+
150
+ setActiveContactItem(newContactsConfiguration[pathIndex].items.length - 1);
151
+ handleChangeConfiguration(newContactsConfiguration);
152
+ };
153
+
154
+ const onChangeContactsItem = (pathIndex, contactItemIndex, contactItem) => {
155
+ let newContactsConfiguration = [...contactsConfiguration];
156
+ newContactsConfiguration[pathIndex].items[contactItemIndex] = contactItem;
157
+
158
+ handleChangeConfiguration(newContactsConfiguration);
159
+ };
160
+
161
+ const deleteContactsItem = (e, pathIndex, index) => {
162
+ e.preventDefault();
163
+ let newContactsConfiguration = [...contactsConfiguration];
164
+ newContactsConfiguration[pathIndex].items.splice(index, 1);
165
+
166
+ if (activeContactItem === index) {
167
+ setTimeout(() => setActiveContactItem(index > 0 ? index - 1 : 0), 0);
168
+ }
169
+
170
+ handleChangeConfiguration(newContactsConfiguration);
171
+ };
172
+
173
+ return (
174
+ <div className="contacts-configuration-widget">
175
+ <Form.Field inline id={id}>
176
+ <Grid>
177
+ <Grid.Row>
178
+ <Grid.Column width="12">
179
+ <div className="wrapper">
180
+ <label htmlFor="contacts-configuration">{title}</label>
181
+ </div>
182
+ </Grid.Column>
183
+ <Grid.Column width="12" className="contacts-configuration-widget">
184
+ <div id="contacts-configuration">
185
+ <Menu pointing secondary className="contacts-path-menu">
186
+ {contactsConfiguration.map((contact, idx) => (
187
+ <Menu.Item
188
+ key={`contacts-path-${idx}`}
189
+ name={contact.rootPath}
190
+ active={activeContact === idx}
191
+ onClick={() => {
192
+ setActiveContact(idx);
193
+ setActiveContactItem(0);
194
+ }}
195
+ >
196
+ <span>{flattenToAppURL(contact.rootPath)}</span>
197
+ </Menu.Item>
198
+ ))}
199
+ <Menu.Item
200
+ active={false}
201
+ name={intl.formatMessage(messages.add_contacts_path)}
202
+ onClick={addContactsPath}
203
+ >
204
+ <Icon name="plus" />
205
+ </Menu.Item>
206
+ </Menu>
207
+ <Segment>
208
+ {activeContact > -1 &&
209
+ activeContact < contactsConfiguration.length ? (
210
+ <Grid>
211
+ <Grid.Column
212
+ width={12}
213
+ className="contact-rootpath-segment"
214
+ >
215
+ <TextWidget
216
+ id="rootPath"
217
+ title={intl.formatMessage(messages.root_path)}
218
+ required
219
+ value={flattenToAppURL(
220
+ contactsConfiguration[activeContact].rootPath,
221
+ )}
222
+ onChange={(id, value) => {
223
+ onChangeContactsPath(activeContact, {
224
+ ...contactsConfiguration[activeContact],
225
+ rootPath: value?.length > 0 ? value : '/',
226
+ });
227
+ }}
228
+ />
229
+ <Form.Field
230
+ inline
231
+ className="delete wide"
232
+ id="contactpath-delete"
233
+ >
234
+ <Grid>
235
+ <Grid.Row stretched>
236
+ <Grid.Column width={12}>
237
+ <div className="delete-button">
238
+ <Button
239
+ icon="trash"
240
+ negative
241
+ onClick={(e) =>
242
+ deleteContactsPath(e, activeContact)
243
+ }
244
+ id="delete-contactspath"
245
+ content={intl.formatMessage(
246
+ messages.delete_button,
247
+ )}
248
+ />
249
+ </div>
250
+ </Grid.Column>
251
+ </Grid.Row>
252
+ </Grid>
253
+ </Form.Field>
254
+ </Grid.Column>
255
+ <Grid.Column width={4}>
256
+ <Header as="h2" className="contacts-items-header">
257
+ {intl.formatMessage(messages.contact_items_header)}
258
+ </Header>
259
+ <Menu
260
+ fluid
261
+ vertical
262
+ tabular
263
+ className="contact-items-menu"
264
+ >
265
+ {contactsConfiguration[activeContact].items?.map(
266
+ (contactItem, idx) => (
267
+ <Menu.Item
268
+ key={`contacts-item-${idx}`}
269
+ name={contactItem.title}
270
+ active={activeContactItem === idx}
271
+ onClick={() => setActiveContactItem(idx)}
272
+ >
273
+ <Button.Group vertical className="move-buttons">
274
+ <Button
275
+ disabled={idx === 0}
276
+ size="tiny"
277
+ icon={<Icon name="arrow left" />}
278
+ title={intl.formatMessage(
279
+ messages.move_menu_item_up,
280
+ )}
281
+ onClick={(e) =>
282
+ moveContactsItem(
283
+ e,
284
+ activeContact,
285
+ idx,
286
+ 'up',
287
+ )
288
+ }
289
+ />
290
+ <Button
291
+ disabled={
292
+ idx ===
293
+ contactsConfiguration[activeContact].items
294
+ .length -
295
+ 1
296
+ }
297
+ size="tiny"
298
+ icon={<Icon name="arrow right" />}
299
+ title={intl.formatMessage(
300
+ messages.move_menu_item_down,
301
+ )}
302
+ onClick={(e) =>
303
+ moveContactsItem(
304
+ e,
305
+ activeContact,
306
+ idx,
307
+ 'down',
308
+ )
309
+ }
310
+ />
311
+ </Button.Group>
312
+ <span className="item-title">
313
+ {contactItem.title}
314
+ </span>
315
+ </Menu.Item>
316
+ ),
317
+ )}
318
+ <Menu.Item
319
+ name={intl.formatMessage(
320
+ messages.add_contacts_item,
321
+ )}
322
+ onClick={(e) => addContactItem(e, activeContact)}
323
+ >
324
+ <Icon name="plus" />
325
+ </Menu.Item>
326
+ </Menu>
327
+ </Grid.Column>
328
+ <Grid.Column stretched width={8}>
329
+ <div className="help-text">
330
+ {intl.formatMessage(messages.icon_list_help_text)}
331
+ <ul>
332
+ <li>
333
+ <UniversalLink href="https://italia.github.io/bootstrap-italia/docs/utilities/icone/#lista-delle-icone-disponibili">
334
+ Bootstrap Italia
335
+ </UniversalLink>
336
+ </li>
337
+ <li>
338
+ <UniversalLink href="https://fontawesome.com/v5/search?ic=free&o=r">
339
+ Fontawesome
340
+ </UniversalLink>
341
+ </li>
342
+ </ul>
343
+ </div>
344
+ {activeContactItem > -1 &&
345
+ activeContactItem <
346
+ contactsConfiguration[activeContact].items.length ? (
347
+ <Component
348
+ componentName="ContactsConfigForm"
349
+ id={`${activeContact}-${activeContactItem}`}
350
+ contactItem={
351
+ contactsConfiguration[activeContact].items[
352
+ activeContactItem
353
+ ]
354
+ }
355
+ onChange={(contact) =>
356
+ onChangeContactsItem(
357
+ activeContact,
358
+ activeContactItem,
359
+ contact,
360
+ )
361
+ }
362
+ deleteContactItem={(e) =>
363
+ deleteContactsItem(
364
+ e,
365
+ activeContact,
366
+ activeContactItem,
367
+ )
368
+ }
369
+ />
370
+ ) : (
371
+ <span>
372
+ {intl.formatMessage(
373
+ messages.empty_active_contacts_item,
374
+ )}
375
+ </span>
376
+ )}
377
+ </Grid.Column>
378
+ </Grid>
379
+ ) : (
380
+ <span>
381
+ {intl.formatMessage(messages.empty_active_contacts_path)}
382
+ </span>
383
+ )}
384
+ </Segment>
385
+ </div>
386
+ </Grid.Column>
387
+ </Grid.Row>
388
+ </Grid>
389
+ </Form.Field>
390
+ </div>
391
+ );
392
+ };
393
+
394
+ export default ContactsConfigWidget;
@@ -324,9 +324,14 @@ const SelectInput = ({
324
324
  const labelDefined =
325
325
  label || intl.formatMessage(messages.SelectInput_default_label);
326
326
  const Select = reactSelect.default;
327
+
327
328
  return (
328
329
  <div className="bootstrap-select-wrapper">
329
- {label && <label htmlFor={!labelledby ? id : undefined}>{label}</label>}
330
+ {label && (
331
+ <label className="active" htmlFor={!labelledby ? id : undefined}>
332
+ {label}
333
+ </label>
334
+ )}
330
335
  <Select
331
336
  components={{
332
337
  MenuList,
@@ -338,7 +343,7 @@ const SelectInput = ({
338
343
  IndicatorSeparator: null,
339
344
  ...components,
340
345
  }}
341
- id={id}
346
+ inputId={id}
342
347
  value={value}
343
348
  onChange={onChange}
344
349
  options={options}
@@ -24,6 +24,9 @@ import {
24
24
  BlocksViewWidget,
25
25
  PDCViewWidget,
26
26
  DataGridWidget,
27
+ ContactsConfigWidget,
28
+ ContactsConfigForm,
29
+ ConditionallyRequiredDateWidget,
27
30
  } from 'design-comuni-plone-theme/components/ItaliaTheme';
28
31
  import LuoghiCorrelatiEventoWidget from 'design-comuni-plone-theme/components/ItaliaTheme/manage/Widgets/LuoghiCorrelatiEventoWidget';
29
32
 
@@ -40,6 +43,10 @@ const getItaliaWidgets = (config) => {
40
43
  name: 'SubFooterConfigurationForm',
41
44
  component: SubFooterConfigurationForm,
42
45
  });
46
+ config.registerComponent({
47
+ name: 'ContactsConfigForm',
48
+ component: ContactsConfigForm,
49
+ });
43
50
 
44
51
  return {
45
52
  id: {
@@ -59,6 +66,9 @@ const getItaliaWidgets = (config) => {
59
66
  props, //per il content-type FaqFolder
60
67
  ) => <IconWidget {...props} defaultOptions={defaultIconWidgetOptions} />,
61
68
  cookie_consent_configuration: MultilingualWidget(),
69
+ data_inizio_incarico: (props) => (
70
+ <ConditionallyRequiredDateWidget {...props} />
71
+ ),
62
72
  data_conclusione_incarico: (props) => (
63
73
  <DatetimeWidget {...props} dateOnly={true} />
64
74
  ),
@@ -88,6 +98,7 @@ const getItaliaWidgets = (config) => {
88
98
  ),
89
99
  subsite_social_links: SubsiteSocialLinksWidget,
90
100
  canale_digitale: CanaleDigitaleWidget,
101
+ contact_configuration: ContactsConfigWidget,
91
102
  },
92
103
  widget: {
93
104
  ...config.widgets.widget,
@@ -296,11 +296,13 @@ export default function applyConfig(voltoConfig) {
296
296
  enableNoFeedbackFormFor: false,
297
297
  enableFeedbackFormCaptcha: false,
298
298
  enableVoltoFormBlockCaptcha: true,
299
+ enableContactsBlock: false,
299
300
  splitMegamenuColumns: true, //se impostato a false, non spezza le colonne con intestazioni nel megamenu
300
301
  footerNavigationDepth: 2, //valori possibili: [1,2]. Se impostato ad 1 non verranno mostrati nel footer i link agli elementi contenuti nelle sezioni di primo livello.
301
302
  markSpecialLinks: true, // se impostato a false, non marca con icona i link esterni
302
303
  markFooterLinks: true, // se impostato a true, viene aggiunta un'icona ai link del footer per renderli riconoscibili
303
304
  showContentDateInListingFor: ['Modulo', 'Documento'], // elenco dei content types per i quali mostrare la data di pubblicazione/modifica in listing
305
+ displayThankYouInAlertMessageFormBlock: false, // imposta a true quando vuoi mostrare il ThankYou message con l'alert del limite di iscrizioni
304
306
  fallbackImageSrc: FALLBACK_IMAGE_SRC,
305
307
  fallbackImageSrcMaxW: FALLBACK_IMAGE_SRC_MAX_W,
306
308
  },
@@ -387,8 +389,8 @@ export default function applyConfig(voltoConfig) {
387
389
  //se si aggiunge un nuovo blocco, verificare che in edit non ci siano bottoni che provocano il submit della form. Se succede, gestirli con e.prevenDefault() e.stopPropagation().
388
390
  // Se sono bottoni semantic basta mettere type="button"
389
391
  ],
390
-
391
392
  showRestricted: false,
393
+ voltoVersion: '17',
392
394
  };
393
395
 
394
396
  config.settings.nonContentRoutes = config.settings.nonContentRoutes.filter(
@@ -13,8 +13,12 @@ import {
13
13
  SubsiteFooter,
14
14
  } from 'design-comuni-plone-theme/components/ItaliaTheme/';
15
15
 
16
- import { FeedbackForm } from 'design-comuni-plone-theme/components/ItaliaTheme';
16
+ import {
17
+ FeedbackForm,
18
+ ContactsBlock,
19
+ } from 'design-comuni-plone-theme/components/ItaliaTheme';
17
20
  import config from '@plone/volto/registry';
21
+
18
22
  /**
19
23
  * Footer component class.
20
24
  * @class Footer
@@ -34,8 +38,11 @@ const Footer = () => {
34
38
  config.settings.siteProperties.enableFeedbackForm
35
39
  : true;
36
40
 
41
+ const showContactsBlock = config.settings.siteProperties.enableContactsForm;
42
+
37
43
  return (
38
44
  <>
45
+ {showContactsBlock && <ContactsBlock />}
39
46
  {showFeedbackForm && (
40
47
  <div className="public-ui" id="customer-satisfaction-form">
41
48
  <FeedbackForm />