@plone/volto 19.0.0-alpha.9 → 19.1.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 (535) hide show
  1. package/.eslintignore +2 -0
  2. package/.eslintrc +26 -15
  3. package/AGENTS.md +47 -0
  4. package/CHANGELOG.md +543 -12
  5. package/README.md +22 -19
  6. package/babel.js +1 -9
  7. package/cypress/support/guillotina.js +1 -0
  8. package/cypress.config.js +1 -0
  9. package/global-test-setup.js +1 -2
  10. package/locales/af/LC_MESSAGES/volto.po +5516 -0
  11. package/locales/af.json +1 -1
  12. package/locales/ar/LC_MESSAGES/volto.po +5516 -0
  13. package/locales/ar.json +1 -1
  14. package/locales/bg/LC_MESSAGES/volto.po +5516 -0
  15. package/locales/bg.json +1 -1
  16. package/locales/bn/LC_MESSAGES/volto.po +5516 -0
  17. package/locales/bn.json +1 -1
  18. package/locales/ca/LC_MESSAGES/volto.po +551 -359
  19. package/locales/ca.json +1 -1
  20. package/locales/cs/LC_MESSAGES/volto.po +5516 -0
  21. package/locales/cs.json +1 -1
  22. package/locales/cy/LC_MESSAGES/volto.po +5516 -0
  23. package/locales/cy.json +1 -1
  24. package/locales/da/LC_MESSAGES/volto.po +5516 -0
  25. package/locales/da.json +1 -1
  26. package/locales/de/LC_MESSAGES/volto.po +222 -29
  27. package/locales/de.json +1 -1
  28. package/locales/el/LC_MESSAGES/volto.po +5516 -0
  29. package/locales/el.json +1 -1
  30. package/locales/en/LC_MESSAGES/volto.po +211 -15
  31. package/locales/en.json +1 -1
  32. package/locales/en_AU/LC_MESSAGES/volto.po +5516 -0
  33. package/locales/en_AU.json +1 -1
  34. package/locales/en_GB/LC_MESSAGES/volto.po +5516 -0
  35. package/locales/en_GB.json +1 -1
  36. package/locales/eo/LC_MESSAGES/volto.po +5516 -0
  37. package/locales/eo.json +1 -1
  38. package/locales/es/LC_MESSAGES/volto.po +336 -145
  39. package/locales/es.json +1 -1
  40. package/locales/et/LC_MESSAGES/volto.po +5516 -0
  41. package/locales/et.json +1 -1
  42. package/locales/eu/LC_MESSAGES/volto.po +413 -222
  43. package/locales/eu.json +1 -1
  44. package/locales/fa/LC_MESSAGES/volto.po +5516 -0
  45. package/locales/fa.json +1 -1
  46. package/locales/fi/LC_MESSAGES/volto.po +212 -20
  47. package/locales/fi.json +1 -1
  48. package/locales/fr/LC_MESSAGES/volto.po +369 -178
  49. package/locales/fr.json +1 -1
  50. package/locales/fu/LC_MESSAGES/volto.po +5516 -0
  51. package/locales/fu.json +1 -1
  52. package/locales/gl/LC_MESSAGES/volto.po +5516 -0
  53. package/locales/gl.json +1 -1
  54. package/locales/he/LC_MESSAGES/volto.po +5516 -0
  55. package/locales/he.json +1 -1
  56. package/locales/hi/LC_MESSAGES/volto.po +220 -23
  57. package/locales/hi.json +1 -1
  58. package/locales/hr/LC_MESSAGES/volto.po +5516 -0
  59. package/locales/hr.json +1 -1
  60. package/locales/hu/LC_MESSAGES/volto.po +5516 -0
  61. package/locales/hu.json +1 -1
  62. package/locales/hy/LC_MESSAGES/volto.po +5516 -0
  63. package/locales/hy.json +1 -1
  64. package/locales/id/LC_MESSAGES/volto.po +5516 -0
  65. package/locales/id.json +1 -1
  66. package/locales/it/LC_MESSAGES/volto.po +236 -39
  67. package/locales/it.json +1 -1
  68. package/locales/ja/LC_MESSAGES/volto.po +254 -61
  69. package/locales/ja.json +1 -1
  70. package/locales/ka/LC_MESSAGES/volto.po +5516 -0
  71. package/locales/ka.json +1 -1
  72. package/locales/kn/LC_MESSAGES/volto.po +5516 -0
  73. package/locales/kn.json +1 -1
  74. package/locales/ko/LC_MESSAGES/volto.po +5516 -0
  75. package/locales/ko.json +1 -1
  76. package/locales/lt/LC_MESSAGES/volto.po +5516 -0
  77. package/locales/lt.json +1 -1
  78. package/locales/lv/LC_MESSAGES/volto.po +5516 -0
  79. package/locales/lv.json +1 -1
  80. package/locales/mi/LC_MESSAGES/volto.po +5516 -0
  81. package/locales/mi.json +1 -1
  82. package/locales/mk/LC_MESSAGES/volto.po +5516 -0
  83. package/locales/mk.json +1 -1
  84. package/locales/my/LC_MESSAGES/volto.po +5516 -0
  85. package/locales/my.json +1 -1
  86. package/locales/nb_NO/LC_MESSAGES/volto.po +5516 -0
  87. package/locales/nb_NO.json +1 -1
  88. package/locales/nl/LC_MESSAGES/volto.po +264 -71
  89. package/locales/nl.json +1 -1
  90. package/locales/nn/LC_MESSAGES/volto.po +5516 -0
  91. package/locales/nn.json +1 -1
  92. package/locales/pl/LC_MESSAGES/volto.po +5516 -0
  93. package/locales/pl.json +1 -1
  94. package/locales/pt/LC_MESSAGES/volto.po +862 -670
  95. package/locales/pt.json +1 -1
  96. package/locales/pt_BR/LC_MESSAGES/volto.po +216 -25
  97. package/locales/pt_BR.json +1 -1
  98. package/locales/rm/LC_MESSAGES/volto.po +5516 -0
  99. package/locales/rm.json +1 -1
  100. package/locales/ro/LC_MESSAGES/volto.po +248 -57
  101. package/locales/ro.json +1 -1
  102. package/locales/ru/LC_MESSAGES/volto.po +211 -19
  103. package/locales/ru.json +1 -1
  104. package/locales/sk/LC_MESSAGES/volto.po +5516 -0
  105. package/locales/sk.json +1 -1
  106. package/locales/sl/LC_MESSAGES/volto.po +5516 -0
  107. package/locales/sl.json +1 -1
  108. package/locales/sm/LC_MESSAGES/volto.po +5516 -0
  109. package/locales/sm.json +1 -1
  110. package/locales/sq/LC_MESSAGES/volto.po +5516 -0
  111. package/locales/sq.json +1 -1
  112. package/locales/sr/LC_MESSAGES/volto.po +5516 -0
  113. package/locales/sr.json +1 -1
  114. package/locales/sr@cyrl/LC_MESSAGES/volto.po +5516 -0
  115. package/locales/sr@cyrl.json +1 -1
  116. package/locales/sr@latn/LC_MESSAGES/volto.po +5516 -0
  117. package/locales/sr@latn.json +1 -1
  118. package/locales/sv/LC_MESSAGES/volto.po +5516 -0
  119. package/locales/sv.json +1 -1
  120. package/locales/ta/LC_MESSAGES/volto.po +5516 -0
  121. package/locales/ta.json +1 -1
  122. package/locales/te/LC_MESSAGES/volto.po +5516 -0
  123. package/locales/te.json +1 -1
  124. package/locales/th/LC_MESSAGES/volto.po +5516 -0
  125. package/locales/th.json +1 -1
  126. package/locales/to/LC_MESSAGES/volto.po +5516 -0
  127. package/locales/to.json +1 -1
  128. package/locales/tr/LC_MESSAGES/volto.po +5516 -0
  129. package/locales/tr.json +1 -1
  130. package/locales/uk/LC_MESSAGES/volto.po +5516 -0
  131. package/locales/uk.json +1 -1
  132. package/locales/vi/LC_MESSAGES/volto.po +5516 -0
  133. package/locales/vi.json +1 -1
  134. package/locales/volto.pot +205 -14
  135. package/locales/zh_CN/LC_MESSAGES/volto.po +211 -19
  136. package/locales/zh_CN.json +1 -1
  137. package/locales/zh_Hant/LC_MESSAGES/volto.po +5516 -0
  138. package/locales/zh_Hant.json +1 -1
  139. package/locales/zh_Hant_HK/LC_MESSAGES/volto.po +5516 -0
  140. package/locales/zh_Hant_HK.json +1 -1
  141. package/package.json +71 -149
  142. package/razzle.config.js +16 -25
  143. package/src/actions/blockTypes/blockTypes.ts +24 -0
  144. package/src/actions/controlpanels/controlpanels.js +7 -12
  145. package/src/actions/controlpanels/controlpanels.test.js +2 -3
  146. package/src/components/manage/Actions/Actions.test.jsx +1 -5
  147. package/src/components/manage/Add/Add.jsx +15 -10
  148. package/src/components/manage/Add/Add.test.jsx +10 -3
  149. package/src/components/manage/Aliases/Aliases.test.jsx +5 -2
  150. package/src/components/manage/BlockChooser/BlockChooser.jsx +8 -10
  151. package/src/components/manage/Blocks/Block/BlocksForm.jsx +10 -7
  152. package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +3 -14
  153. package/src/components/manage/Blocks/Block/Edit.jsx +19 -10
  154. package/src/components/manage/Blocks/Block/Order/Item.jsx +33 -14
  155. package/src/components/manage/Blocks/Block/Order/Item.test.jsx +90 -0
  156. package/src/components/manage/Blocks/Block/Order/Order.jsx +116 -67
  157. package/src/components/manage/Blocks/Block/Order/utilities.js +28 -11
  158. package/src/components/manage/Blocks/Block/Settings.test.jsx +1 -5
  159. package/src/components/manage/Blocks/Grid/View.jsx +14 -11
  160. package/src/components/manage/Blocks/Grid/context.js +3 -0
  161. package/src/components/manage/Blocks/HTML/Edit.test.jsx +1 -5
  162. package/src/components/manage/Blocks/Image/ImageSidebar.test.jsx +2 -5
  163. package/src/components/manage/Blocks/LeadImage/LeadImageSidebar.test.jsx +2 -5
  164. package/src/components/manage/Blocks/Listing/Edit.jsx +1 -0
  165. package/src/components/manage/Blocks/Listing/ListingBody.jsx +4 -0
  166. package/src/components/manage/Blocks/Maps/Body.jsx +37 -0
  167. package/src/components/manage/Blocks/Maps/Edit.jsx +6 -21
  168. package/src/components/manage/Blocks/Maps/MapsSidebar.test.jsx +1 -5
  169. package/src/components/manage/Blocks/Maps/View.jsx +16 -25
  170. package/src/components/manage/Blocks/Search/components/DateRangeFacet.test.jsx +1 -6
  171. package/src/components/manage/Blocks/Search/components/SelectFacet.jsx +22 -1
  172. package/src/components/manage/Blocks/Search/components/SelectFacet.test.jsx +1 -6
  173. package/src/components/manage/Blocks/Search/components/SortOn.jsx +8 -2
  174. package/src/components/manage/Blocks/Search/components/ToggleFacet.jsx +14 -0
  175. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +10 -2
  176. package/src/components/manage/Blocks/Teaser/View.jsx +0 -1
  177. package/src/components/manage/Blocks/Teaser/utils.js +13 -0
  178. package/src/components/manage/Blocks/Teaser/utils.test.js +34 -0
  179. package/src/components/manage/Blocks/Title/Edit.jsx +5 -0
  180. package/src/components/manage/Blocks/Video/Body.jsx +69 -43
  181. package/src/components/manage/Blocks/Video/Body.test.jsx +122 -5
  182. package/src/components/manage/Blocks/Video/Edit.jsx +20 -2
  183. package/src/components/manage/Blocks/Video/Edit.test.jsx +6 -0
  184. package/src/components/manage/Blocks/Video/VideoSidebar.test.jsx +1 -5
  185. package/src/components/manage/Blocks/Video/View.jsx +1 -0
  186. package/src/components/manage/Blocks/Video/View.test.jsx +29 -15
  187. package/src/components/manage/Blocks/Video/schema.js +14 -1
  188. package/src/components/manage/Contents/Contents.jsx +854 -747
  189. package/src/components/manage/Contents/Contents.test.jsx +9 -10
  190. package/src/components/manage/Contents/ContentsBreadcrumbs.jsx +4 -3
  191. package/src/components/manage/Contents/ContentsIndexHeader.jsx +47 -81
  192. package/src/components/manage/Contents/ContentsIndexHeader.test.jsx +10 -3
  193. package/src/components/manage/Contents/ContentsItem.jsx +226 -278
  194. package/src/components/manage/Contents/ContentsItem.test.jsx +10 -6
  195. package/src/components/manage/Contents/ContentsPropertiesModal.test.jsx +1 -5
  196. package/src/components/manage/Contents/ContentsRenameModal.test.jsx +1 -5
  197. package/src/components/manage/Contents/ContentsTagsModal.test.jsx +1 -5
  198. package/src/components/manage/Contents/ContentsWorkflowModal.test.jsx +1 -5
  199. package/src/components/manage/Contents/DropZoneContent.jsx +339 -0
  200. package/src/components/manage/Contents/__mocks__/index.tsx +2 -18
  201. package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +7 -0
  202. package/src/components/manage/Controlpanels/AddonsControlpanel.test.jsx +7 -4
  203. package/src/components/manage/Controlpanels/Aliases.test.jsx +8 -9
  204. package/src/components/manage/Controlpanels/BlockType.tsx +165 -0
  205. package/src/components/manage/Controlpanels/BlockTypes.tsx +145 -0
  206. package/src/components/manage/Controlpanels/ContentType.jsx +131 -222
  207. package/src/components/manage/Controlpanels/ContentType.test.jsx +13 -14
  208. package/src/components/manage/Controlpanels/ContentTypeLayout.test.jsx +12 -9
  209. package/src/components/manage/Controlpanels/ContentTypeSchema.jsx +1 -1
  210. package/src/components/manage/Controlpanels/ContentTypes.jsx +9 -2
  211. package/src/components/manage/Controlpanels/ContentTypes.test.jsx +7 -4
  212. package/src/components/manage/Controlpanels/Controlpanel.jsx +122 -218
  213. package/src/components/manage/Controlpanels/Controlpanel.test.jsx +8 -33
  214. package/src/components/manage/Controlpanels/Controlpanels.jsx +28 -5
  215. package/src/components/manage/Controlpanels/Controlpanels.test.jsx +23 -8
  216. package/src/components/manage/Controlpanels/DatabaseInformation.jsx +9 -0
  217. package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.test.jsx +7 -4
  218. package/src/components/manage/Controlpanels/ModerateComments.jsx +8 -0
  219. package/src/components/manage/Controlpanels/ModerateComments.test.jsx +7 -4
  220. package/src/components/manage/Controlpanels/Relations/Relations.jsx +1 -1
  221. package/src/components/manage/Controlpanels/Rules/AddRule.test.jsx +8 -9
  222. package/src/components/manage/Controlpanels/Rules/ConfigureRule.test.jsx +9 -6
  223. package/src/components/manage/Controlpanels/Rules/EditRule.test.jsx +8 -9
  224. package/src/components/manage/Controlpanels/Rules/Rules.test.jsx +7 -4
  225. package/src/components/manage/Controlpanels/UndoControlpanel.test.jsx +8 -9
  226. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.test.jsx +10 -4
  227. package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +628 -631
  228. package/src/components/manage/Controlpanels/Users/UsersControlpanel.ssr.test.jsx +624 -0
  229. package/src/components/manage/Controlpanels/Users/UsersControlpanel.test.jsx +70 -10
  230. package/src/components/manage/Controlpanels/VersionOverview.jsx +19 -6
  231. package/src/components/manage/Delete/Delete.test.jsx +13 -8
  232. package/src/components/manage/Diff/Diff.jsx +201 -298
  233. package/src/components/manage/Diff/Diff.test.jsx +8 -10
  234. package/src/components/manage/Diff/DiffField.test.jsx +1 -6
  235. package/src/components/manage/Display/Display.test.jsx +2 -11
  236. package/src/components/manage/Edit/Edit.test.jsx +12 -11
  237. package/src/components/manage/Form/BlockDataForm.test.jsx +1 -5
  238. package/src/components/manage/Form/Field.jsx +1 -69
  239. package/src/components/manage/Form/Form.jsx +17 -4
  240. package/src/components/manage/Form/Form.test.jsx +130 -5
  241. package/src/components/manage/Form/InlineForm.test.jsx +1 -5
  242. package/src/components/manage/Form/ModalForm.jsx +175 -97
  243. package/src/components/manage/Form/ModalForm.test.jsx +27 -5
  244. package/src/components/manage/Form/__mocks__/index.tsx +9 -27
  245. package/src/components/manage/History/History.jsx +209 -300
  246. package/src/components/manage/History/History.test.jsx +20 -9
  247. package/src/components/manage/LinksToItem/LinksToItem.test.jsx +7 -4
  248. package/src/components/manage/Multilingual/CompareLanguages.jsx +6 -6
  249. package/src/components/manage/Multilingual/CreateTranslation.jsx +16 -13
  250. package/src/components/manage/Multilingual/ManageTranslations.jsx +5 -5
  251. package/src/components/manage/Multilingual/ManageTranslations.test.jsx +15 -12
  252. package/src/components/manage/Multilingual/TranslationObject.jsx +11 -8
  253. package/src/components/manage/Preferences/ChangePassword.test.jsx +8 -9
  254. package/src/components/manage/Preferences/PersonalPreferences.jsx +8 -5
  255. package/src/components/manage/Preferences/PersonalPreferences.test.jsx +10 -23
  256. package/src/components/manage/Rules/Rules.test.jsx +5 -2
  257. package/src/components/manage/Sharing/Sharing.jsx +21 -15
  258. package/src/components/manage/Sharing/Sharing.test.jsx +9 -6
  259. package/src/components/manage/Sidebar/ObjectBrowser.jsx +10 -0
  260. package/src/components/manage/Sidebar/ObjectBrowserBody.jsx +25 -5
  261. package/src/components/manage/Sidebar/ObjectBrowserBody.test.jsx +52 -0
  262. package/src/components/manage/Sidebar/Sidebar.jsx +2 -0
  263. package/src/components/manage/Sidebar/Sidebar.test.jsx +4 -1
  264. package/src/components/manage/Sidebar/SidebarPortal.test.tsx +42 -0
  265. package/src/components/manage/Sidebar/SidebarPortal.tsx +48 -0
  266. package/src/components/manage/TemplateChooser/TemplateChooser.test.jsx +1 -0
  267. package/src/components/manage/Toast/Toast.jsx +32 -0
  268. package/src/components/manage/Toast/Toast.test.jsx +9 -5
  269. package/src/components/manage/Toolbar/PersonalTools.test.jsx +15 -0
  270. package/src/components/manage/Toolbar/Toolbar.jsx +109 -12
  271. package/src/components/manage/Toolbar/Toolbar.test.jsx +15 -10
  272. package/src/components/manage/Toolbar/Types.crash.test.jsx +48 -0
  273. package/src/components/manage/Toolbar/Types.jsx +6 -4
  274. package/src/components/manage/UniversalLink/UniversalLink.test.jsx +16 -0
  275. package/src/components/manage/UniversalLink/UniversalLink.tsx +1 -0
  276. package/src/components/manage/Widgets/AlignWidget.stories.jsx +9 -0
  277. package/src/components/manage/Widgets/AlignWidget.test.tsx +95 -0
  278. package/src/components/manage/Widgets/{AlignWidget.jsx → AlignWidget.tsx} +23 -7
  279. package/src/components/manage/Widgets/ArrayWidget.jsx +111 -88
  280. package/src/components/manage/Widgets/ArrayWidget.test.jsx +1 -12
  281. package/src/components/manage/Widgets/BlockAlignment.stories.tsx +104 -0
  282. package/src/components/manage/Widgets/BlockAlignment.test.tsx +104 -0
  283. package/src/components/manage/Widgets/BlockAlignment.tsx +88 -0
  284. package/src/components/manage/Widgets/BlockWidth.stories.tsx +69 -0
  285. package/src/components/manage/Widgets/BlockWidth.test.tsx +62 -0
  286. package/src/components/manage/Widgets/BlockWidth.tsx +101 -0
  287. package/src/components/manage/Widgets/ButtonsWidget.stories.jsx +61 -0
  288. package/src/components/manage/Widgets/ButtonsWidget.test.tsx +138 -0
  289. package/src/components/manage/Widgets/ButtonsWidget.tsx +195 -0
  290. package/src/components/manage/Widgets/CheckboxGroupWidget.test.jsx +1 -6
  291. package/src/components/manage/Widgets/DatetimeWidget.jsx +98 -54
  292. package/src/components/manage/Widgets/DatetimeWidget.test.jsx +56 -6
  293. package/src/components/manage/Widgets/FileWidget.jsx +7 -0
  294. package/src/components/manage/Widgets/FormFieldWrapper.jsx +143 -163
  295. package/src/components/manage/Widgets/ImageWidget.jsx +18 -5
  296. package/src/components/manage/Widgets/ObjectBrowserWidget.jsx +6 -0
  297. package/src/components/manage/Widgets/ObjectListWidget.test.jsx +2 -11
  298. package/src/components/manage/Widgets/ObjectWidget.test.jsx +1 -5
  299. package/src/components/manage/Widgets/QueryWidget.jsx +137 -9
  300. package/src/components/manage/Widgets/QuerystringWidget.test.jsx +3 -1
  301. package/src/components/manage/Widgets/RadioGroupWidget.test.jsx +1 -6
  302. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +1 -6
  303. package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField.jsx +56 -50
  304. package/src/components/manage/Widgets/RegistryImageWidget.jsx +1 -1
  305. package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +1 -0
  306. package/src/components/manage/Widgets/SchemaWidget.test.jsx +1 -6
  307. package/src/components/manage/Widgets/SchemaWidgetFieldset.test.jsx +1 -6
  308. package/src/components/manage/Widgets/SelectAutoComplete.test.jsx +1 -6
  309. package/src/components/manage/Widgets/SelectStyling.jsx +52 -20
  310. package/src/components/manage/Widgets/SelectWidget.test.jsx +1 -6
  311. package/src/components/manage/Widgets/Size.stories.tsx +69 -0
  312. package/src/components/manage/Widgets/Size.test.tsx +59 -0
  313. package/src/components/manage/Widgets/Size.tsx +78 -0
  314. package/src/components/manage/Widgets/TextWidget.jsx +4 -0
  315. package/src/components/manage/Widgets/TimeWidget.test.jsx +1 -6
  316. package/src/components/manage/Widgets/TokenWidget.jsx +142 -186
  317. package/src/components/manage/Widgets/TokenWidget.test.jsx +1 -6
  318. package/src/components/manage/Widgets/UrlWidget.jsx +47 -18
  319. package/src/components/manage/Widgets/VocabularyTermsWidget.test.jsx +2 -11
  320. package/src/components/manage/Widgets/__mocks__/index.tsx +33 -51
  321. package/src/components/manage/Widgets/index.tsx +21 -0
  322. package/src/components/manage/Workflow/Workflow.test.jsx +2 -11
  323. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.jsx +1 -0
  324. package/src/components/theme/AlternateHrefLangs/AlternateHrefLangs.test.jsx +30 -0
  325. package/src/components/theme/App/App.jsx +5 -1
  326. package/src/components/theme/App/App.test.jsx +13 -10
  327. package/src/components/theme/Comments/CommentEditModal.test.jsx +1 -5
  328. package/src/components/theme/Comments/Comments.test.jsx +2 -11
  329. package/src/components/theme/ConnectionRefused/ConnectionRefused.jsx +3 -2
  330. package/src/components/theme/ContactForm/ContactForm.test.jsx +14 -13
  331. package/src/components/theme/Image/Image.jsx +14 -5
  332. package/src/components/theme/Image/Image.test.jsx +247 -146
  333. package/src/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.tsx +7 -0
  334. package/src/components/theme/LanguageSelector/LanguageSelector.tsx +3 -3
  335. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +42 -12
  336. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.test.jsx +6 -3
  337. package/src/components/theme/PasswordReset/PasswordReset.jsx +108 -191
  338. package/src/components/theme/PasswordReset/RequestPasswordReset.test.jsx +1 -5
  339. package/src/components/theme/Register/Register.test.jsx +1 -5
  340. package/src/components/theme/Search/Search.jsx +230 -327
  341. package/src/components/theme/Search/Search.test.jsx +14 -14
  342. package/src/components/theme/Sitemap/Sitemap.jsx +22 -30
  343. package/src/components/theme/Sitemap/Sitemap.stories.jsx +82 -0
  344. package/src/components/theme/Sitemap/Sitemap.test.jsx +18 -0
  345. package/src/components/theme/SlotRenderer/SlotRenderer.tsx +12 -6
  346. package/src/components/theme/Unauthorized/Unauthorized.jsx +27 -24
  347. package/src/components/theme/Unauthorized/Unauthorized.test.jsx +31 -2
  348. package/src/components/theme/VideoEmbed/VideoEmbed.jsx +100 -0
  349. package/src/components/theme/View/EventDatesInfo.test.jsx +1 -6
  350. package/src/components/theme/View/EventView.stories.jsx +89 -0
  351. package/src/components/theme/View/EventView.test.jsx +1 -6
  352. package/src/components/theme/View/FileView.stories.jsx +50 -0
  353. package/src/components/theme/View/ImageView.jsx +2 -1
  354. package/src/components/theme/View/ImageView.test.jsx +3 -0
  355. package/src/components/theme/View/LinkView.stories.jsx +57 -0
  356. package/src/components/theme/View/ListingView.stories.jsx +70 -0
  357. package/src/components/theme/View/NewsItemView.stories.jsx +58 -0
  358. package/src/components/theme/View/RenderBlocks.jsx +8 -10
  359. package/src/components/theme/View/RenderBlocks.stories.jsx +112 -0
  360. package/src/components/theme/View/RenderBlocks.test.jsx +14 -4
  361. package/src/components/theme/View/SummaryView.stories.jsx +71 -0
  362. package/src/components/theme/View/TabularView.stories.jsx +66 -0
  363. package/src/components/theme/View/View.jsx +8 -1
  364. package/src/components/theme/View/View.test.jsx +37 -24
  365. package/src/components/theme/Widgets/DateWidget.jsx +4 -5
  366. package/src/components/theme/Widgets/DatetimeWidget.jsx +4 -5
  367. package/src/components/theme/Widgets/ImageWidget.test.jsx +31 -11
  368. package/src/components/theme/Widgets/RichTextWidget.jsx +1 -1
  369. package/src/config/Blocks.jsx +3 -0
  370. package/src/config/ControlPanels.js +2 -0
  371. package/src/config/Loadables.jsx +1 -5
  372. package/src/config/Widgets.jsx +7 -0
  373. package/src/config/index.js +10 -1
  374. package/src/config/slots.js +19 -0
  375. package/src/config/validation.ts +8 -0
  376. package/src/constants/ActionTypes.js +1 -0
  377. package/src/express-middleware/devproxy.js +3 -1
  378. package/src/express-middleware/files.js +1 -0
  379. package/src/express-middleware/files.test.js +59 -0
  380. package/src/express-middleware/images.js +1 -0
  381. package/src/express-middleware/images.test.js +50 -0
  382. package/src/helpers/Api/Api.js +2 -2
  383. package/src/helpers/AuthToken/AuthToken.js +1 -6
  384. package/src/helpers/Blocks/Blocks.js +113 -28
  385. package/src/helpers/Blocks/Blocks.test.js +100 -0
  386. package/src/helpers/Content/Content.js +23 -0
  387. package/src/helpers/Content/Content.test.js +39 -0
  388. package/src/helpers/Extensions/withBlockSchemaEnhancer.jsx +4 -1
  389. package/src/helpers/FormValidation/FormValidation.test.js +31 -0
  390. package/src/helpers/FormValidation/validators.ts +52 -6
  391. package/src/helpers/I18n/I18n.test.ts +44 -0
  392. package/src/helpers/I18n/I18n.ts +31 -0
  393. package/src/helpers/Loadable/__mocks__/Loadable.jsx +7 -22
  394. package/src/helpers/MessageLabels/MessageLabels.js +5 -0
  395. package/src/helpers/Robots/Robots.js +1 -1
  396. package/src/helpers/Robots/Robots.test.js +34 -0
  397. package/src/helpers/Url/Url.js +1 -0
  398. package/src/helpers/Utils/Date.js +26 -1
  399. package/src/helpers/Utils/Date.test.js +237 -0
  400. package/src/helpers/Utils/Utils.jsx +17 -0
  401. package/src/helpers/Utils/Utils.test.jsx +39 -0
  402. package/src/helpers/Utils/withSaveAsDraft.jsx +33 -9
  403. package/src/helpers/index.js +1 -0
  404. package/src/hooks/user/useUser.js +1 -1
  405. package/src/internalChecks.test.ts +11 -0
  406. package/src/middleware/api.js +14 -5
  407. package/src/reducers/blockTypes/blockTypes.js +38 -0
  408. package/src/reducers/content/content.js +3 -18
  409. package/src/reducers/diff/diff.js +5 -1
  410. package/src/reducers/diff/diff.test.js +60 -4
  411. package/src/reducers/index.js +2 -0
  412. package/src/reducers/querystring/querystring.js +8 -1
  413. package/src/reducers/users/users.js +1 -1
  414. package/src/routes.js +10 -0
  415. package/src/server.jsx +14 -6
  416. package/src/start-client.jsx +21 -3
  417. package/test-addons-loader.js +3 -0
  418. package/test-setup-globals.js +56 -2
  419. package/theme/themes/default/elements/segment.variables +9 -16
  420. package/theme/themes/default/globals/site.variables +3 -3
  421. package/theme/themes/pastanaga/collections/form.overrides +22 -1
  422. package/theme/themes/pastanaga/elements/button.overrides +30 -3
  423. package/theme/themes/pastanaga/elements/segment.variables +1 -4
  424. package/theme/themes/pastanaga/extras/block-types.less +17 -0
  425. package/theme/themes/pastanaga/extras/contents.less +63 -4
  426. package/theme/themes/pastanaga/extras/main.less +16 -4
  427. package/theme/themes/pastanaga/extras/toolbar.less +10 -5
  428. package/theme/themes/pastanaga/extras/videoembed.less +22 -0
  429. package/theme/themes/pastanaga/extras/widgets.less +79 -0
  430. package/theme/themes/pastanaga/globals/site.variables +0 -3
  431. package/tsconfig.declarations.json +1 -1
  432. package/tsconfig.json +1 -1
  433. package/types/actions/blockTypes/blockTypes.d.ts +7 -0
  434. package/types/components/index.d.ts +1 -1
  435. package/types/components/manage/Blocks/Block/Order/Item.test.d.ts +1 -0
  436. package/types/components/manage/Blocks/Block/Order/utilities.d.ts +2 -1
  437. package/types/components/manage/Blocks/Grid/context.d.ts +1 -0
  438. package/types/components/manage/Blocks/Maps/Body.d.ts +9 -0
  439. package/types/components/manage/Blocks/Maps/View.d.ts +1 -1
  440. package/types/components/manage/Blocks/Teaser/utils.d.ts +5 -0
  441. package/types/components/manage/Blocks/Video/Body.d.ts +4 -2
  442. package/types/components/manage/Blocks/Video/schema.d.ts +4 -0
  443. package/types/components/manage/Contents/Contents.d.ts +1 -1
  444. package/types/components/manage/Contents/ContentsIndexHeader.d.ts +6 -11
  445. package/types/components/manage/Contents/ContentsItem.d.ts +3 -10
  446. package/types/components/manage/Contents/DropZoneContent.d.ts +2 -0
  447. package/types/components/manage/Contents/__mocks__/index.d.ts +2 -2
  448. package/types/components/manage/Controlpanels/BlockType.d.ts +7 -0
  449. package/types/components/manage/Controlpanels/BlockTypes.d.ts +7 -0
  450. package/types/components/manage/Controlpanels/ContentType.d.ts +2 -2
  451. package/types/components/manage/Controlpanels/Controlpanel.d.ts +2 -5
  452. package/types/components/manage/Controlpanels/Relations/RelationsMatrix.d.ts +1 -1
  453. package/types/components/manage/Controlpanels/Users/UsersControlpanel.ssr.test.d.ts +1 -0
  454. package/types/components/manage/Controlpanels/VersionOverview.d.ts +2 -1
  455. package/types/components/manage/Controlpanels/index.d.ts +3 -2
  456. package/types/components/manage/Diff/Diff.d.ts +7 -2
  457. package/types/components/manage/Form/__mocks__/index.d.ts +8 -8
  458. package/types/components/manage/Multilingual/ManageTranslations.d.ts +1 -1
  459. package/types/components/manage/Sidebar/ObjectBrowser.d.ts +1 -1
  460. package/types/components/manage/Sidebar/ObjectBrowserBody.test.d.ts +1 -0
  461. package/types/components/manage/Sidebar/SidebarPortal.d.ts +7 -15
  462. package/types/components/manage/Toolbar/Types.crash.test.d.ts +1 -0
  463. package/types/components/manage/Widgets/AlignWidget.d.ts +8 -10
  464. package/types/components/manage/Widgets/AlignWidget.stories.d.ts +1 -0
  465. package/types/components/manage/Widgets/BlockAlignment.d.ts +7 -0
  466. package/types/components/manage/Widgets/BlockAlignment.stories.d.ts +8 -0
  467. package/types/components/manage/Widgets/BlockWidth.d.ts +7 -0
  468. package/types/components/manage/Widgets/BlockWidth.stories.d.ts +6 -0
  469. package/types/components/manage/Widgets/ButtonsWidget.d.ts +48 -1
  470. package/types/components/manage/Widgets/ButtonsWidget.stories.d.ts +3 -0
  471. package/types/components/manage/Widgets/FormFieldWrapper.d.ts +28 -5
  472. package/types/components/manage/Widgets/ImageWidget.d.ts +1 -1
  473. package/types/components/manage/Widgets/InternalUrlWidget.d.ts +1 -1
  474. package/types/components/manage/Widgets/ObjectBrowserWidget.d.ts +2 -0
  475. package/types/components/manage/Widgets/QueryWidget.d.ts +5 -2
  476. package/types/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField.d.ts +22 -5
  477. package/types/components/manage/Widgets/SelectStyling.d.ts +1 -0
  478. package/types/components/manage/Widgets/Size.d.ts +7 -0
  479. package/types/components/manage/Widgets/Size.stories.d.ts +6 -0
  480. package/types/components/manage/Widgets/UrlWidget.d.ts +1 -1
  481. package/types/components/manage/Widgets/__mocks__/index.d.ts +33 -33
  482. package/types/components/manage/Widgets/index.d.ts +11 -6
  483. package/types/components/theme/ConnectionRefused/ConnectionRefused.d.ts +2 -2
  484. package/types/components/theme/InjectPloneComponentsCSS/InjectPloneComponentsCSS.d.ts +3 -0
  485. package/types/components/theme/PasswordReset/PasswordReset.d.ts +6 -2
  486. package/types/components/theme/Search/Search.d.ts +1 -1
  487. package/types/components/theme/Sitemap/Sitemap.stories.d.ts +13 -0
  488. package/types/components/theme/SlotRenderer/SlotRenderer.d.ts +4 -5
  489. package/types/components/theme/Unauthorized/Unauthorized.d.ts +2 -2
  490. package/types/components/theme/VideoEmbed/VideoEmbed.d.ts +2 -0
  491. package/types/components/theme/View/EventView.stories.d.ts +19 -0
  492. package/types/components/theme/View/FileView.stories.d.ts +18 -0
  493. package/types/components/theme/View/LinkView.stories.d.ts +18 -0
  494. package/types/components/theme/View/ListingView.stories.d.ts +24 -0
  495. package/types/components/theme/View/NewsItemView.stories.d.ts +23 -0
  496. package/types/components/theme/View/RenderBlocks.stories.d.ts +23 -0
  497. package/types/components/theme/View/SummaryView.stories.d.ts +23 -0
  498. package/types/components/theme/View/TabularView.stories.d.ts +23 -0
  499. package/types/config/ControlPanels.d.ts +1 -0
  500. package/types/config/Views.d.ts +1 -1
  501. package/types/config/Widgets.d.ts +6 -0
  502. package/types/config/slots.d.ts +7 -0
  503. package/types/constants/ActionTypes.d.ts +1 -0
  504. package/types/helpers/Blocks/Blocks.d.ts +4 -0
  505. package/types/helpers/Content/Content.d.ts +7 -0
  506. package/types/helpers/Extensions/withBlockSchemaEnhancer.d.ts +4 -5
  507. package/types/helpers/FormValidation/validators.d.ts +18 -1
  508. package/types/helpers/I18n/I18n.d.ts +20 -0
  509. package/types/helpers/Loadable/__mocks__/Loadable.d.ts +2 -2
  510. package/types/helpers/MessageLabels/MessageLabels.d.ts +100 -94
  511. package/types/helpers/Utils/Utils.d.ts +1 -0
  512. package/types/helpers/index.d.ts +1 -0
  513. package/types/reducers/blockTypes/blockTypes.d.ts +16 -0
  514. package/types/reducers/index.d.ts +2 -0
  515. package/types/routes.d.ts +7 -5
  516. package/vitest.config.mjs +84 -42
  517. package/webpack-plugins/webpack-less-plugin.js +1 -1
  518. package/webpack-plugins/webpack-scss-plugin.js +172 -0
  519. package/jest-addons-loader.js +0 -3
  520. package/jest-extender-plugin.js +0 -39
  521. package/jest-setup-afterenv.js +0 -2
  522. package/jest-svgsystem-transform.js +0 -10
  523. package/patches/patchit.sh +0 -2
  524. package/patches/razzle-jest.patch +0 -10
  525. package/src/components/manage/Contents/__mocks__/index.vitest.tsx +0 -5
  526. package/src/components/manage/Form/__mocks__/index.vitest.tsx +0 -73
  527. package/src/components/manage/Sidebar/SidebarPortal.jsx +0 -47
  528. package/src/components/manage/Sidebar/SidebarPortal.test.jsx +0 -26
  529. package/src/components/manage/Widgets/AlignWidget.test.jsx +0 -59
  530. package/src/components/manage/Widgets/ButtonsWidget.jsx +0 -41
  531. package/src/components/manage/Widgets/ButtonsWidget.test.jsx +0 -70
  532. package/src/components/manage/Widgets/__mocks__/index.vitest.tsx +0 -41
  533. package/src/helpers/Loadable/__mocks__/Loadable.vitest.jsx +0 -39
  534. package/test-setup-globals-vitest.js +0 -46
  535. package/theme/themes/pastanaga/extras/utils.less +0 -63
@@ -3,11 +3,10 @@
3
3
  * @module components/manage/Widgets/TokenWidget
4
4
  */
5
5
 
6
- import React, { Component } from 'react';
6
+ import React, { useEffect, useMemo } from 'react';
7
7
  import PropTypes from 'prop-types';
8
- import { compose } from 'redux';
9
- import { connect } from 'react-redux';
10
- import { defineMessages, injectIntl } from 'react-intl';
8
+ import { useSelector, useDispatch } from 'react-redux';
9
+ import { defineMessages, useIntl } from 'react-intl';
11
10
  import {
12
11
  getVocabFromHint,
13
12
  getVocabFromField,
@@ -48,192 +47,149 @@ const messages = defineMessages({
48
47
  * @class TokenWidget
49
48
  * @extends Component
50
49
  */
51
- class TokenWidget extends Component {
52
- /**
53
- * Property types.
54
- * @property {Object} propTypes Property types.
55
- * @static
56
- */
57
- static propTypes = {
58
- id: PropTypes.string.isRequired,
59
- title: PropTypes.string.isRequired,
60
- description: PropTypes.string,
61
- required: PropTypes.bool,
62
- error: PropTypes.arrayOf(PropTypes.string),
63
- getVocabulary: PropTypes.func.isRequired,
64
- choices: PropTypes.arrayOf(PropTypes.object),
65
- vocabLoading: PropTypes.bool,
66
- vocabLoaded: PropTypes.bool,
67
- items: PropTypes.shape({
68
- vocabulary: PropTypes.object,
69
- }),
70
- widgetOptions: PropTypes.shape({
71
- vocabulary: PropTypes.object,
72
- }),
73
- value: PropTypes.arrayOf(PropTypes.string),
74
- onChange: PropTypes.func.isRequired,
75
- wrapped: PropTypes.bool,
76
- placeholder: PropTypes.string,
77
- };
78
-
79
- /**
80
- * Default properties
81
- * @property {Object} defaultProps Default properties.
82
- * @static
83
- */
84
- static defaultProps = {
85
- description: null,
86
- required: false,
87
- items: {
88
- vocabulary: null,
89
- },
90
- widgetOptions: {
91
- vocabulary: null,
92
- },
93
- error: [],
94
- choices: [],
95
- value: null,
96
- };
97
-
98
- /**
99
- * Constructor
100
- * @method constructor
101
- * @param {Object} props Component properties
102
- * @constructs Actions
103
- */
104
- constructor(props) {
105
- super(props);
106
- this.handleChange = this.handleChange.bind(this);
107
- }
108
-
109
- /**
110
- * Component did mount
111
- * @method componentDidMount
112
- * @returns {undefined}
113
- */
114
- componentDidMount() {
115
- if (!this.props.choices?.length) {
116
- this.props.getVocabulary({
117
- vocabNameOrURL: this.props.vocabBaseUrl,
118
- size: -1,
119
- subrequest: this.props.lang,
120
- });
50
+ const TokenWidget = (props) => {
51
+ const {
52
+ id,
53
+ onChange,
54
+ value,
55
+ placeholder,
56
+ reactSelectCreateable,
57
+ isDisabled,
58
+ fieldSet,
59
+ } = props;
60
+
61
+ const intl = useIntl();
62
+ const dispatch = useDispatch();
63
+
64
+ const vocabBaseUrl =
65
+ getVocabFromHint(props) ||
66
+ getVocabFromField(props) ||
67
+ getVocabFromItems(props);
68
+
69
+ const lang = useSelector((state) => state.intl.locale);
70
+
71
+ const vocabState = useSelector((state) => {
72
+ if (!vocabBaseUrl) return null;
73
+ return state.vocabularies?.[vocabBaseUrl]?.subrequests?.[lang];
74
+ });
75
+
76
+ const choices = useMemo(() => {
77
+ if (vocabState?.items) {
78
+ return vocabState.items.map((item) => ({
79
+ label: item.label || item.value,
80
+ value: item.value,
81
+ }));
121
82
  }
122
- }
83
+ return [];
84
+ }, [vocabState]);
123
85
 
124
- componentDidUpdate() {
86
+ const vocabLoading = vocabState?.loading;
87
+ const vocabLoaded = vocabState?.loaded;
88
+
89
+ useEffect(() => {
125
90
  if (
126
- !this.props.choices?.length &&
127
- this.props.vocabLoading === undefined &&
128
- !this.props.vocabLoaded
91
+ !choices?.length &&
92
+ vocabLoading === undefined &&
93
+ !vocabLoaded &&
94
+ vocabBaseUrl
129
95
  ) {
130
- this.props.getVocabulary({
131
- vocabNameOrURL: this.props.vocabBaseUrl,
132
- size: -1,
133
- subrequest: this.props.lang,
134
- });
96
+ dispatch(
97
+ getVocabulary({
98
+ vocabNameOrURL: vocabBaseUrl,
99
+ size: -1,
100
+ subrequest: lang,
101
+ }),
102
+ );
135
103
  }
136
- }
137
-
138
- /**
139
- * Handle the field change, store it in the local state and back to simple
140
- * array of tokens for correct serialization
141
- * @method handleChange
142
- * @param {array} selectedOption The selected options (already aggregated).
143
- * @returns {undefined}
144
- */
145
- handleChange(selectedOption) {
146
- this.props.onChange(
147
- this.props.id,
104
+ }, [
105
+ choices?.length,
106
+ vocabLoading,
107
+ vocabLoaded,
108
+ vocabBaseUrl,
109
+ lang,
110
+ dispatch,
111
+ ]);
112
+
113
+ const handleChange = (selectedOption) => {
114
+ onChange(
115
+ id,
148
116
  selectedOption ? selectedOption.map((item) => item.label) : null,
149
117
  );
150
- }
151
-
152
- /**
153
- * Render method.
154
- * @method render
155
- * @returns {string} Markup for the component.
156
- */
157
- render() {
158
- const selectedOption = this.props.value
159
- ? this.props.value.map((item) => ({ label: item, value: item }))
160
- : [];
161
-
162
- const defaultOptions = (this.props.choices || [])
163
- .filter(
164
- (item) => !selectedOption.find(({ label }) => label === item.label),
165
- )
166
- .map((item) => ({
167
- label: item.label || item.value,
168
- value: item.value,
169
- }));
170
- const CreatableSelect = this.props.reactSelectCreateable.default;
171
-
172
- return (
173
- <FormFieldWrapper {...this.props}>
174
- <CreatableSelect
175
- id={`field-${this.props.id}`}
176
- aria-labelledby={`fieldset-${this.props.fieldSet}-field-label-${this.props.id}`}
177
- key={this.props.id}
178
- menuShouldScrollIntoView={false}
179
- isDisabled={this.props.isDisabled}
180
- className="react-select-container"
181
- classNamePrefix="react-select"
182
- defaultOptions={defaultOptions}
183
- options={defaultOptions}
184
- styles={customSelectStyles}
185
- theme={selectTheme}
186
- components={{
187
- MultiValueContainer,
188
- ClearIndicator,
189
- DropdownIndicator,
190
- Option,
191
- }}
192
- isMulti
193
- value={selectedOption || []}
194
- onChange={this.handleChange}
195
- placeholder={
196
- this.props.placeholder ??
197
- this.props.intl.formatMessage(messages.select)
198
- }
199
- noOptionsMessage={() =>
200
- this.props.intl.formatMessage(messages.no_options)
201
- }
202
- />
203
- </FormFieldWrapper>
204
- );
205
- }
206
- }
207
-
208
- export default compose(
209
- injectIntl,
210
- injectLazyLibs(['reactSelectCreateable']),
211
- connect(
212
- (state, props) => {
213
- const vocabBaseUrl =
214
- getVocabFromHint(props) ||
215
- getVocabFromField(props) ||
216
- getVocabFromItems(props);
217
-
218
- const vocabState =
219
- state.vocabularies?.[vocabBaseUrl]?.subrequests?.[state.intl.locale];
220
-
221
- if (vocabState) {
222
- return {
223
- choices: vocabState.items
224
- ? vocabState.items.map((item) => ({
225
- label: item.label || item.value,
226
- value: item.value,
227
- }))
228
- : [],
229
- vocabLoading: vocabState.loading,
230
- vocabLoaded: vocabState.loaded,
231
- vocabBaseUrl,
232
- lang: state.intl.locale,
233
- };
234
- }
235
- return { vocabBaseUrl, lang: state.intl.locale };
236
- },
237
- { getVocabulary },
238
- ),
239
- )(TokenWidget);
118
+ };
119
+
120
+ const selectedOption = value
121
+ ? value.map((item) => ({ label: item, value: item }))
122
+ : [];
123
+
124
+ const defaultOptions = (choices || [])
125
+ .filter((item) => !selectedOption.find(({ label }) => label === item.label))
126
+ .map((item) => ({
127
+ label: item.label || item.value,
128
+ value: item.value,
129
+ }));
130
+ const CreatableSelect = reactSelectCreateable.default;
131
+
132
+ return (
133
+ <FormFieldWrapper {...props}>
134
+ <CreatableSelect
135
+ id={`field-${id}`}
136
+ aria-labelledby={`fieldset-${fieldSet}-field-label-${id}`}
137
+ key={id}
138
+ menuShouldScrollIntoView={false}
139
+ isDisabled={isDisabled}
140
+ className="react-select-container"
141
+ classNamePrefix="react-select"
142
+ defaultOptions={defaultOptions}
143
+ options={defaultOptions}
144
+ styles={customSelectStyles}
145
+ theme={selectTheme}
146
+ components={{
147
+ MultiValueContainer,
148
+ ClearIndicator,
149
+ DropdownIndicator,
150
+ Option,
151
+ }}
152
+ isMulti
153
+ value={selectedOption || []}
154
+ onChange={handleChange}
155
+ placeholder={placeholder ?? intl.formatMessage(messages.select)}
156
+ noOptionsMessage={() => intl.formatMessage(messages.no_options)}
157
+ />
158
+ </FormFieldWrapper>
159
+ );
160
+ };
161
+
162
+ TokenWidget.propTypes = {
163
+ id: PropTypes.string.isRequired,
164
+ title: PropTypes.string.isRequired,
165
+ description: PropTypes.string,
166
+ required: PropTypes.bool,
167
+ error: PropTypes.arrayOf(PropTypes.string),
168
+ choices: PropTypes.arrayOf(PropTypes.object),
169
+ items: PropTypes.shape({
170
+ vocabulary: PropTypes.object,
171
+ }),
172
+ widgetOptions: PropTypes.shape({
173
+ vocabulary: PropTypes.object,
174
+ }),
175
+ value: PropTypes.arrayOf(PropTypes.string),
176
+ onChange: PropTypes.func.isRequired,
177
+ wrapped: PropTypes.bool,
178
+ placeholder: PropTypes.string,
179
+ };
180
+
181
+ TokenWidget.defaultProps = {
182
+ description: null,
183
+ required: false,
184
+ items: {
185
+ vocabulary: null,
186
+ },
187
+ widgetOptions: {
188
+ vocabulary: null,
189
+ },
190
+ error: [],
191
+ choices: [],
192
+ value: null,
193
+ };
194
+
195
+ export default injectLazyLibs(['reactSelectCreateable'])(TokenWidget);
@@ -7,12 +7,7 @@ import TokenWidget from './TokenWidget';
7
7
 
8
8
  const mockStore = configureStore();
9
9
 
10
- vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
11
- return await import(
12
- '@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
13
- );
14
- });
15
-
10
+ vi.mock('@plone/volto/helpers/Loadable/Loadable');
16
11
  beforeAll(async () => {
17
12
  const { __setLoadables } = await import(
18
13
  '@plone/volto/helpers/Loadable/Loadable'
@@ -2,7 +2,6 @@
2
2
  * UrlWidget component.
3
3
  * @module components/manage/Widgets/UrlWidget
4
4
  */
5
-
6
5
  import React, { useState } from 'react';
7
6
  import PropTypes from 'prop-types';
8
7
  import { Input, Button } from 'semantic-ui-react';
@@ -14,10 +13,10 @@ import {
14
13
  flattenToAppURL,
15
14
  URLUtils,
16
15
  } from '@plone/volto/helpers/Url/Url';
16
+ import { defineMessages, useIntl } from 'react-intl';
17
17
  import withObjectBrowser from '@plone/volto/components/manage/Sidebar/ObjectBrowser';
18
18
  import clearSVG from '@plone/volto/icons/clear.svg';
19
19
  import navTreeSVG from '@plone/volto/icons/nav.svg';
20
-
21
20
  /** Widget to edit urls
22
21
  *
23
22
  * This is the default widget used for the `remoteUrl` field. You can also use
@@ -30,6 +29,24 @@ import navTreeSVG from '@plone/volto/icons/nav.svg';
30
29
  * }
31
30
  * ```
32
31
  */
32
+ const messages = defineMessages({
33
+ urlMissing: {
34
+ id: 'URL is missing',
35
+ defaultMessage: 'URL is missing',
36
+ },
37
+ urlInvalid: {
38
+ id: 'URL is invalid',
39
+ defaultMessage: 'URL is invalid',
40
+ },
41
+ clearUrl: {
42
+ id: 'Clear URL',
43
+ defaultMessage: 'Clear URL',
44
+ },
45
+ openUrlBrowser: {
46
+ id: 'Open URL browser',
47
+ defaultMessage: 'Open URL browser',
48
+ },
49
+ });
33
50
  export const UrlWidget = (props) => {
34
51
  const {
35
52
  id,
@@ -40,9 +57,10 @@ export const UrlWidget = (props) => {
40
57
  maxLength,
41
58
  placeholder,
42
59
  isDisabled,
60
+ required,
43
61
  } = props;
44
62
  const inputId = `field-${id}`;
45
-
63
+ const intl = useIntl();
46
64
  const [value, setValue] = useState(flattenToAppURL(props.value));
47
65
  const [isInvalid, setIsInvalid] = useState(false);
48
66
  /**
@@ -54,24 +72,20 @@ export const UrlWidget = (props) => {
54
72
  const clear = () => {
55
73
  setValue('');
56
74
  onChange(id, undefined);
75
+ setIsInvalid(false);
57
76
  };
58
-
59
77
  const onChangeValue = (_value) => {
60
78
  let newValue = _value;
61
79
  if (newValue?.length > 0) {
62
80
  if (isInvalid && URLUtils.isUrl(URLUtils.normalizeUrl(newValue))) {
63
81
  setIsInvalid(false);
64
82
  }
65
-
66
83
  if (isInternalURL(newValue)) {
67
84
  newValue = flattenToAppURL(newValue);
68
85
  }
69
86
  }
70
-
71
87
  setValue(newValue);
72
-
73
88
  newValue = isInternalURL(newValue) ? addAppURL(newValue) : newValue;
74
-
75
89
  if (!isInternalURL(newValue) && newValue.length > 0) {
76
90
  const checkedURL = URLUtils.checkAndNormalizeUrl(newValue);
77
91
  newValue = checkedURL.url;
@@ -79,10 +93,15 @@ export const UrlWidget = (props) => {
79
93
  setIsInvalid(true);
80
94
  }
81
95
  }
82
-
83
96
  onChange(id, newValue === '' ? undefined : newValue);
84
97
  };
85
-
98
+ // A11y: if the field is required and the user leaves it empty, we mark it as missing
99
+ const handleBlur = ({ target }) => {
100
+ if (required && (!target.value || target.value === '')) {
101
+ setIsInvalid(true);
102
+ }
103
+ onBlur(id, target.value === '' ? undefined : target.value);
104
+ };
86
105
  return (
87
106
  <FormFieldWrapper {...props} className="url wide">
88
107
  <div className="wrapper">
@@ -90,25 +109,38 @@ export const UrlWidget = (props) => {
90
109
  id={inputId}
91
110
  name={id}
92
111
  type="url"
112
+ required={required}
113
+ aria-required={required}
114
+ aria-invalid={isInvalid}
115
+ aria-errormessage={isInvalid ? `${inputId}-error` : undefined}
116
+ onBlur={handleBlur}
93
117
  value={value || ''}
94
118
  disabled={isDisabled}
95
119
  placeholder={placeholder}
96
120
  onChange={({ target }) => onChangeValue(target.value)}
97
- onBlur={({ target }) =>
98
- onBlur(id, target.value === '' ? undefined : target.value)
99
- }
100
121
  onClick={() => onClick()}
101
122
  minLength={minLength || null}
102
123
  maxLength={maxLength || null}
103
124
  error={isInvalid}
104
125
  />
126
+ {isInvalid && (
127
+ <span
128
+ id={`${inputId}-error`}
129
+ role="alert"
130
+ className="visually-hidden"
131
+ >
132
+ {value?.length > 0
133
+ ? intl.formatMessage(messages.urlInvalid)
134
+ : intl.formatMessage(messages.urlMissing)}
135
+ </span>
136
+ )}
105
137
  {value?.length > 0 ? (
106
138
  <Button.Group>
107
139
  <Button
108
140
  type="button"
109
141
  basic
110
142
  className="cancel"
111
- aria-label="clearUrlBrowser"
143
+ aria-label={intl.formatMessage(messages.clearUrl)}
112
144
  onClick={(e) => {
113
145
  e.preventDefault();
114
146
  e.stopPropagation();
@@ -124,7 +156,7 @@ export const UrlWidget = (props) => {
124
156
  type="button"
125
157
  basic
126
158
  icon
127
- aria-label="openUrlBrowser"
159
+ aria-label={intl.formatMessage(messages.openUrlBrowser)}
128
160
  onClick={(e) => {
129
161
  e.preventDefault();
130
162
  e.stopPropagation();
@@ -145,7 +177,6 @@ export const UrlWidget = (props) => {
145
177
  </FormFieldWrapper>
146
178
  );
147
179
  };
148
-
149
180
  /**
150
181
  * Property types
151
182
  * @property {Object} propTypes Property types.
@@ -166,7 +197,6 @@ UrlWidget.propTypes = {
166
197
  openObjectBrowser: PropTypes.func.isRequired,
167
198
  placeholder: PropTypes.string,
168
199
  };
169
-
170
200
  /**
171
201
  * Default properties.
172
202
  * @property {Object} defaultProps Default properties.
@@ -183,5 +213,4 @@ UrlWidget.defaultProps = {
183
213
  minLength: null,
184
214
  maxLength: null,
185
215
  };
186
-
187
216
  export default withObjectBrowser(UrlWidget);
@@ -4,17 +4,8 @@ import configureStore from 'redux-mock-store';
4
4
  import { Provider } from 'react-intl-redux';
5
5
  import VocabularyTermsWidget from './VocabularyTermsWidget';
6
6
 
7
- vi.mock('@plone/volto/helpers/Loadable/Loadable', async () => {
8
- return await import(
9
- '@plone/volto/helpers/Loadable/__mocks__/Loadable.vitest.jsx'
10
- );
11
- });
12
- vi.mock('@plone/volto/components/manage/Form', async () => {
13
- return await import(
14
- '@plone/volto/components/manage/Form/__mocks__/index.vitest.tsx'
15
- );
16
- });
17
-
7
+ vi.mock('@plone/volto/helpers/Loadable/Loadable');
8
+ vi.mock('@plone/volto/components/manage/Form');
18
9
  beforeAll(async () => {
19
10
  const { __setLoadables } = await import(
20
11
  '@plone/volto/helpers/Loadable/Loadable'
@@ -1,59 +1,41 @@
1
- /* TODO: When the Volto Team removes Jest configuration support from Volto core, update this file with the Vitest version of the mock.
2
- Then, in the tests, we need to replace:
3
-
4
- vi.mock('@plone/volto/components/manage/Widgets', async () => {
5
- return await import(
6
- '@plone/volto/components/manage/Widgets/__mocks__/index.vitest.tsx'
7
- );
8
- });
9
-
10
- with the following:
11
-
12
- vi.mock('@plone/volto/components/manage/Widgets');
13
-
14
- Finally, remove this comment.
15
- */
16
-
17
- export const AlignWidget = jest.fn(() => <div id="AlignWidget" />);
18
- export const ButtonsWidget = jest.fn(() => <div id="ButtonsWidget" />);
19
- export const ArrayWidget = jest.fn(() => <div id="ArrayWidget" />);
20
- export const CheckboxWidget = jest.fn(() => <div id="CheckboxWidget" />);
21
- export const FileWidget = jest.fn(() => <div id="FileWidget" />);
22
- export const IdWidget = jest.fn(() => <div id="IdWidget" />);
23
- export const PasswordWidget = jest.fn(() => <div id="PasswordWidget" />);
24
- export const QueryWidget = jest.fn(() => <div id="QueryWidget" />);
25
- export const QuerySortOnWidget = jest.fn(() => <div id="QuerySortOnWidget" />);
26
- export const QuerystringWidget = jest.fn(() => <div id="QuerystringWidget" />);
27
- export const SchemaWidget = jest.fn(() => <div id="SchemaWidget" />);
28
- export const SelectWidget = jest.fn(() => <div id="SelectWidget" />);
29
- export const TextareaWidget = jest.fn(() => <div id="TextareaWidget" />);
30
- export const TextWidget = jest.fn(() => <div id="TextWidget" />);
31
- export const TokenWidget = jest.fn(() => <div id="TokenWidget" />);
32
- export const WysiwygWidget = jest.fn(() => <div id="WysiwygWidget" />);
33
- export const UrlWidget = jest.fn(() => <div id="UrlWidget" />);
34
- export const InternalUrlWidget = jest.fn(() => <div id="InternalUrlWidget" />);
35
- export const EmailWidget = jest.fn(() => <div id="EmailWidget" />);
36
- export const NumberWidget = jest.fn(() => <div id="NumberWidget" />);
37
- export const ImageSizeWidget = jest.fn(() => <div id="ImageSizeWidget" />);
38
- export const RegistryImageWidget = jest.fn(() => (
1
+ export const AlignWidget = vi.fn(() => <div id="AlignWidget" />);
2
+ export const ButtonsWidget = vi.fn(() => <div id="ButtonsWidget" />);
3
+ export const ArrayWidget = vi.fn(() => <div id="ArrayWidget" />);
4
+ export const CheckboxWidget = vi.fn(() => <div id="CheckboxWidget" />);
5
+ export const FileWidget = vi.fn(() => <div id="FileWidget" />);
6
+ export const IdWidget = vi.fn(() => <div id="IdWidget" />);
7
+ export const PasswordWidget = vi.fn(() => <div id="PasswordWidget" />);
8
+ export const QueryWidget = vi.fn(() => <div id="QueryWidget" />);
9
+ export const QuerySortOnWidget = vi.fn(() => <div id="QuerySortOnWidget" />);
10
+ export const QuerystringWidget = vi.fn(() => <div id="QuerystringWidget" />);
11
+ export const SchemaWidget = vi.fn(() => <div id="SchemaWidget" />);
12
+ export const SelectWidget = vi.fn(() => <div id="SelectWidget" />);
13
+ export const TextareaWidget = vi.fn(() => <div id="TextareaWidget" />);
14
+ export const TextWidget = vi.fn(() => <div id="TextWidget" />);
15
+ export const TokenWidget = vi.fn(() => <div id="TokenWidget" />);
16
+ export const WysiwygWidget = vi.fn(() => <div id="WysiwygWidget" />);
17
+ export const UrlWidget = vi.fn(() => <div id="UrlWidget" />);
18
+ export const InternalUrlWidget = vi.fn(() => <div id="InternalUrlWidget" />);
19
+ export const EmailWidget = vi.fn(() => <div id="EmailWidget" />);
20
+ export const NumberWidget = vi.fn(() => <div id="NumberWidget" />);
21
+ export const ImageSizeWidget = vi.fn(() => <div id="ImageSizeWidget" />);
22
+ export const RegistryImageWidget = vi.fn(() => (
39
23
  <div id="RegistryImageWidget" />
40
24
  ));
41
- export const ReferenceWidget = jest.fn(() => <div id="ReferenceWidget" />);
42
- export const ObjectBrowserWidget = jest.fn(() => (
25
+ export const ReferenceWidget = vi.fn(() => <div id="ReferenceWidget" />);
26
+ export const ObjectBrowserWidget = vi.fn(() => (
43
27
  <div id="ObjectBrowserWidget" />
44
28
  ));
45
- export const ObjectWidget = jest.fn(() => <div id="ObjectWidget" />);
46
- export const ObjectListWidget = jest.fn(() => <div id="ObjectListWidget" />);
47
- export const VocabularyTermsWidget = jest.fn(() => (
29
+ export const ObjectWidget = vi.fn(() => <div id="ObjectWidget" />);
30
+ export const ObjectListWidget = vi.fn(() => <div id="ObjectListWidget" />);
31
+ export const VocabularyTermsWidget = vi.fn(() => (
48
32
  <div id="VocabularyTermsWidget" />
49
33
  ));
50
- export const SelectMetadataWidget = jest.fn(() => (
34
+ export const SelectMetadataWidget = vi.fn(() => (
51
35
  <div id="SelectMetadataWidget" />
52
36
  ));
53
- export const SelectAutoComplete = jest.fn(() => (
54
- <div id="SelectAutoComplete" />
55
- ));
56
- export const ColorPickerWidget = jest.fn(() => <div id="ColorPickerWidget" />);
57
- export const DatetimeWidget = jest.fn(() => <div id="DatetimeWidget" />);
58
- export const RecurrenceWidget = jest.fn(() => <div id="RecurrenceWidget" />);
59
- export const FormFieldWrapper = jest.fn(() => <div id="FormFieldWrapper" />);
37
+ export const SelectAutoComplete = vi.fn(() => <div id="SelectAutoComplete" />);
38
+ export const ColorPickerWidget = vi.fn(() => <div id="ColorPickerWidget" />);
39
+ export const DatetimeWidget = vi.fn(() => <div id="DatetimeWidget" />);
40
+ export const RecurrenceWidget = vi.fn(() => <div id="RecurrenceWidget" />);
41
+ export const FormFieldWrapper = vi.fn(() => <div id="FormFieldWrapper" />);