@plone/volto 18.0.0-alpha.5 → 18.0.0-alpha.7

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 (248) hide show
  1. package/.release-it.json +2 -3
  2. package/CHANGELOG.md +59 -0
  3. package/locales/ca/LC_MESSAGES/volto.po +930 -933
  4. package/locales/ca.json +1 -1
  5. package/locales/de/LC_MESSAGES/volto.po +930 -931
  6. package/locales/de.json +1 -1
  7. package/locales/en/LC_MESSAGES/volto.po +930 -930
  8. package/locales/en.json +1 -1
  9. package/locales/es/LC_MESSAGES/volto.po +932 -936
  10. package/locales/es.json +1 -1
  11. package/locales/eu/LC_MESSAGES/volto.po +930 -930
  12. package/locales/eu.json +1 -1
  13. package/locales/fi/LC_MESSAGES/volto.po +930 -936
  14. package/locales/fi.json +1 -1
  15. package/locales/fr/LC_MESSAGES/volto.po +930 -940
  16. package/locales/fr.json +1 -1
  17. package/locales/it/LC_MESSAGES/volto.po +930 -930
  18. package/locales/it.json +1 -1
  19. package/locales/ja/LC_MESSAGES/volto.po +930 -933
  20. package/locales/ja.json +1 -1
  21. package/locales/nl/LC_MESSAGES/volto.po +930 -945
  22. package/locales/nl.json +1 -1
  23. package/locales/pt/LC_MESSAGES/volto.po +930 -933
  24. package/locales/pt.json +1 -1
  25. package/locales/pt_BR/LC_MESSAGES/volto.po +930 -934
  26. package/locales/pt_BR.json +1 -1
  27. package/locales/ro/LC_MESSAGES/volto.po +930 -930
  28. package/locales/ro.json +1 -1
  29. package/locales/volto.pot +932 -936
  30. package/locales/zh_CN/LC_MESSAGES/volto.po +930 -930
  31. package/locales/zh_CN.json +1 -1
  32. package/package.json +11 -9
  33. package/src/components/manage/Blocks/Block/EditBlockWrapper.jsx +11 -3
  34. package/src/components/manage/Blocks/Block/StyleWrapper.jsx +7 -1
  35. package/src/components/manage/Blocks/Grid/View.jsx +2 -1
  36. package/src/components/manage/Blocks/Image/View.jsx +2 -1
  37. package/src/components/manage/Blocks/Listing/View.jsx +2 -1
  38. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +46 -4
  39. package/src/components/manage/Blocks/Teaser/DefaultBody.jsx +2 -2
  40. package/src/components/manage/Contents/Contents.jsx +4 -8
  41. package/src/components/manage/Sidebar/SidebarPopup.jsx +1 -1
  42. package/src/components/manage/Sidebar/SidebarPortal.jsx +1 -1
  43. package/src/components/manage/Widgets/ColorPickerWidget.stories.tsx +48 -0
  44. package/src/components/manage/Widgets/{ColorPickerWidget.jsx → ColorPickerWidget.tsx} +40 -23
  45. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +1 -1
  46. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.test.jsx +1 -1
  47. package/src/components/theme/Comments/CommentEditModal.jsx +1 -0
  48. package/src/components/theme/Login/Login.jsx +12 -2
  49. package/src/components/theme/Navigation/Navigation.jsx +34 -32
  50. package/src/components/theme/PreviewImage/PreviewImage.jsx +7 -2
  51. package/src/components/theme/Sitemap/Sitemap.jsx +4 -4
  52. package/src/components/theme/Sitemap/Sitemap.test.jsx +52 -0
  53. package/src/components/theme/Unauthorized/Unauthorized.jsx +12 -11
  54. package/src/config/Blocks.jsx +1 -1
  55. package/src/helpers/Blocks/Blocks.js +64 -1
  56. package/src/helpers/Blocks/Blocks.test.js +77 -0
  57. package/src/helpers/Extensions/withBlockSchemaEnhancer.js +3 -1
  58. package/src/helpers/index.js +1 -0
  59. package/theme/themes/pastanaga/extras/blocks.less +2 -0
  60. package/theme/themes/pastanaga/extras/sidebar.less +2 -1
  61. package/tsconfig.declarations.json +16 -0
  62. package/types/actions/authRole/authRole.d.ts +1 -1
  63. package/types/actions/comments/comments.d.ts +1 -1
  64. package/types/actions/content/content.d.ts +1 -1
  65. package/types/actions/controlpanels/controlpanels.d.ts +2 -2
  66. package/types/actions/index.d.ts +36 -0
  67. package/types/actions/upgrade/upgrade.d.ts +2 -2
  68. package/types/components/index.d.ts +180 -0
  69. package/types/components/manage/Add/Add.d.ts +3 -2
  70. package/types/components/manage/Aliases/Aliases.d.ts +4 -1
  71. package/types/components/manage/AnchorPlugin/components/LinkButton/AddLinkForm.d.ts +3 -2
  72. package/types/components/manage/BlockChooser/BlockChooser.d.ts +2 -1
  73. package/types/components/manage/Blocks/Block/Edit.d.ts +5 -5
  74. package/types/components/manage/Blocks/Block/EditBlockWrapper.d.ts +3 -2
  75. package/types/components/manage/Blocks/Block/Settings.d.ts +3 -2
  76. package/types/components/manage/Blocks/Grid/View.d.ts +1 -1
  77. package/types/components/manage/Blocks/Grid/templates.d.ts +1 -1
  78. package/types/components/manage/Blocks/HeroImageLeft/Edit.d.ts +4 -1
  79. package/types/components/manage/Blocks/Image/Edit.d.ts +3 -2
  80. package/types/components/manage/Blocks/Image/LayoutSchema.d.ts +36 -1
  81. package/types/components/manage/Blocks/Image/View.d.ts +3 -2
  82. package/types/components/manage/Blocks/LeadImage/Edit.d.ts +3 -2
  83. package/types/components/manage/Blocks/LeadImage/LeadImageSidebar.d.ts +5 -4
  84. package/types/components/manage/Blocks/Listing/Edit.d.ts +1 -1
  85. package/types/components/manage/Blocks/Listing/ListingBody.d.ts +3 -2
  86. package/types/components/manage/Blocks/Listing/View.d.ts +1 -1
  87. package/types/components/manage/Blocks/Maps/Edit.d.ts +1 -1
  88. package/types/components/manage/Blocks/Maps/View.d.ts +1 -3
  89. package/types/components/manage/Blocks/Search/SearchBlockView.d.ts +1 -1
  90. package/types/components/manage/Blocks/Search/components/SortOn.d.ts +1 -3
  91. package/types/components/manage/Blocks/Search/components/ViewSwitcher.d.ts +1 -3
  92. package/types/components/manage/Blocks/Search/schema.d.ts +1 -1
  93. package/types/components/manage/Blocks/Search/utils.d.ts +2 -2
  94. package/types/components/manage/Blocks/Teaser/Edit.d.ts +1 -1
  95. package/types/components/manage/Blocks/Teaser/View.d.ts +1 -1
  96. package/types/components/manage/Blocks/Text/Edit.d.ts +3 -5
  97. package/types/components/manage/Blocks/Text/Schema.d.ts +36 -1
  98. package/types/components/manage/Blocks/ToC/Edit.d.ts +2 -2
  99. package/types/components/manage/Blocks/ToC/View.d.ts +3 -2
  100. package/types/components/manage/Blocks/ToC/variations/DefaultTocRenderer.d.ts +3 -2
  101. package/types/components/manage/Blocks/ToC/variations/HorizontalMenu.d.ts +3 -2
  102. package/types/components/manage/Blocks/Video/Body.test.d.ts +1 -0
  103. package/types/components/manage/Blocks/Video/Edit.d.ts +1 -3
  104. package/types/components/manage/Blocks/Video/View.d.ts +1 -1
  105. package/types/components/manage/Contents/Contents.d.ts +5 -4
  106. package/types/components/manage/Contents/ContentsTagsModal.stories.d.ts +0 -1
  107. package/types/components/manage/Contents/ContentsUploadModal.d.ts +4 -1
  108. package/types/components/manage/Controlpanels/AddonsControlpanel.d.ts +4 -1
  109. package/types/components/manage/Controlpanels/Aliases.d.ts +4 -1
  110. package/types/components/manage/Controlpanels/ContentType.d.ts +4 -1
  111. package/types/components/manage/Controlpanels/ContentTypeLayout.d.ts +4 -1
  112. package/types/components/manage/Controlpanels/ContentTypeSchema.d.ts +4 -1
  113. package/types/components/manage/Controlpanels/ContentTypes.d.ts +4 -1
  114. package/types/components/manage/Controlpanels/ContentTypesActions.d.ts +3 -2
  115. package/types/components/manage/Controlpanels/Controlpanel.d.ts +3 -2
  116. package/types/components/manage/Controlpanels/Controlpanels.d.ts +1 -16
  117. package/types/components/manage/Controlpanels/DatabaseInformation.d.ts +4 -1
  118. package/types/components/manage/Controlpanels/Groups/GroupsControlpanel.d.ts +4 -1
  119. package/types/components/manage/Controlpanels/Groups/RenderGroups.d.ts +3 -2
  120. package/types/components/manage/Controlpanels/ModerateComments.d.ts +4 -1
  121. package/types/components/manage/Controlpanels/Relations/RelationsMatrix.d.ts +43 -1
  122. package/types/components/manage/Controlpanels/Rules/AddRule.d.ts +4 -1
  123. package/types/components/manage/Controlpanels/Rules/ConfigureRule.d.ts +4 -1
  124. package/types/components/manage/Controlpanels/Rules/EditRule.d.ts +4 -1
  125. package/types/components/manage/Controlpanels/Rules/Rules.d.ts +4 -1
  126. package/types/components/manage/Controlpanels/Rules/components/VariableModal.d.ts +4 -1
  127. package/types/components/manage/Controlpanels/UndoControlpanel.d.ts +4 -1
  128. package/types/components/manage/Controlpanels/UpgradeControlPanel.d.ts +4 -1
  129. package/types/components/manage/Controlpanels/Users/RenderUsers.d.ts +4 -1
  130. package/types/components/manage/Controlpanels/Users/UsersControlpanel.d.ts +4 -1
  131. package/types/components/manage/Display/Display.d.ts +3 -2
  132. package/types/components/manage/Edit/Edit.d.ts +6 -3
  133. package/types/components/manage/Form/BlocksToolbar.d.ts +5 -2
  134. package/types/components/manage/Form/Field.d.ts +3 -2
  135. package/types/components/manage/Form/Form.d.ts +1 -3
  136. package/types/components/manage/Form/InlineForm.d.ts +3 -2
  137. package/types/components/manage/Form/ModalForm.d.ts +3 -2
  138. package/types/components/manage/History/History.d.ts +3 -2
  139. package/types/components/manage/Multilingual/CompareLanguages.d.ts +2 -1
  140. package/types/components/manage/Multilingual/ManageTranslations.d.ts +43 -1
  141. package/types/components/manage/Pluggable/index.d.ts +8 -7
  142. package/types/components/manage/Preferences/PersonalPreferences.d.ts +4 -1
  143. package/types/components/manage/Rules/Rules.d.ts +4 -1
  144. package/types/components/manage/Sidebar/ObjectBrowser.d.ts +25 -2
  145. package/types/components/manage/Sidebar/ObjectBrowserBody.d.ts +4 -1
  146. package/types/components/manage/Sidebar/Sidebar.d.ts +2 -1
  147. package/types/components/manage/Sidebar/SidebarPortal.d.ts +2 -2
  148. package/types/components/manage/Toolbar/More.d.ts +3 -2
  149. package/types/components/manage/Toolbar/Toolbar.d.ts +4 -1
  150. package/types/components/manage/Toolbar/Types.d.ts +1 -20
  151. package/types/components/manage/Widgets/ArrayWidget.d.ts +5 -4
  152. package/types/components/manage/Widgets/CheckboxWidget.d.ts +3 -2
  153. package/types/components/manage/Widgets/ColorPickerWidget.d.ts +22 -21
  154. package/types/components/manage/Widgets/ColorPickerWidget.stories.d.ts +7 -8
  155. package/types/components/manage/Widgets/DatetimeWidget.d.ts +2 -2
  156. package/types/components/manage/Widgets/FileWidget.d.ts +3 -2
  157. package/types/components/manage/Widgets/FormFieldWrapper.d.ts +3 -2
  158. package/types/components/manage/Widgets/IdWidget.d.ts +4 -1
  159. package/types/components/manage/Widgets/ImageSizeWidget.d.ts +3 -2
  160. package/types/components/manage/Widgets/InternalUrlWidget.d.ts +43 -1
  161. package/types/components/manage/Widgets/NumberWidget.d.ts +3 -2
  162. package/types/components/manage/Widgets/ObjectBrowserWidget.d.ts +9 -9
  163. package/types/components/manage/Widgets/PasswordWidget.d.ts +3 -2
  164. package/types/components/manage/Widgets/QueryWidget.d.ts +4 -4
  165. package/types/components/manage/Widgets/RecurrenceWidget/ByMonthDayField.d.ts +3 -2
  166. package/types/components/manage/Widgets/RecurrenceWidget/ByMonthField.d.ts +3 -2
  167. package/types/components/manage/Widgets/RecurrenceWidget/ByYearField.d.ts +3 -2
  168. package/types/components/manage/Widgets/RecurrenceWidget/EndField.d.ts +3 -2
  169. package/types/components/manage/Widgets/RecurrenceWidget/Occurences.d.ts +3 -2
  170. package/types/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField.d.ts +3 -2
  171. package/types/components/manage/Widgets/ReferenceWidget.d.ts +4 -1
  172. package/types/components/manage/Widgets/RegistryImageWidget.d.ts +3 -2
  173. package/types/components/manage/Widgets/SchemaWidget.d.ts +3 -2
  174. package/types/components/manage/Widgets/SelectAutoComplete.d.ts +5 -4
  175. package/types/components/manage/Widgets/SelectWidget.d.ts +3 -2
  176. package/types/components/manage/Widgets/TextWidget.d.ts +3 -2
  177. package/types/components/manage/Widgets/TextareaWidget.d.ts +3 -2
  178. package/types/components/manage/Widgets/TokenWidget.d.ts +3 -2
  179. package/types/components/manage/Widgets/UrlWidget.d.ts +43 -1
  180. package/types/components/manage/Widgets/WysiwygWidget.d.ts +3 -2
  181. package/types/components/theme/App/App.d.ts +4 -4
  182. package/types/components/theme/AppExtras/AppExtras.d.ts +1 -1
  183. package/types/components/theme/Breadcrumbs/Breadcrumbs.stories.d.ts +3 -2
  184. package/types/components/theme/Error/ErrorBoundary.d.ts +2 -2
  185. package/types/components/theme/Error/ServerError.d.ts +1 -1
  186. package/types/components/theme/Footer/Footer.d.ts +3 -2
  187. package/types/components/theme/Forbidden/Forbidden.d.ts +1 -1
  188. package/types/components/theme/Navigation/ContextNavigation.d.ts +1 -1
  189. package/types/components/theme/NotFound/NotFound.d.ts +1 -1
  190. package/types/components/theme/Pagination/Pagination.d.ts +3 -2
  191. package/types/components/theme/Search/Search.d.ts +6 -3
  192. package/types/components/theme/Sitemap/Sitemap.d.ts +4 -2
  193. package/types/components/theme/TsTest/TsTest.d.ts +11 -0
  194. package/types/components/theme/TsTest/TsTest.test.d.ts +1 -0
  195. package/types/components/theme/Unauthorized/Unauthorized.d.ts +1 -1
  196. package/types/components/theme/View/AlbumView.d.ts +2 -1
  197. package/types/components/theme/View/DefaultView.d.ts +3 -2
  198. package/types/components/theme/View/RenderBlocks.d.ts +1 -1
  199. package/types/components/theme/View/View.d.ts +4 -1
  200. package/types/components/theme/Widgets/ArrayWidget.d.ts +1 -1
  201. package/types/components/theme/Widgets/BooleanWidget.d.ts +3 -2
  202. package/types/components/theme/Widgets/DateWidget.d.ts +1 -1
  203. package/types/components/theme/Widgets/DatetimeWidget.d.ts +1 -1
  204. package/types/components/theme/Widgets/DescriptionWidget.d.ts +1 -1
  205. package/types/components/theme/Widgets/EmailWidget.d.ts +1 -1
  206. package/types/components/theme/Widgets/FileWidget.d.ts +1 -1
  207. package/types/components/theme/Widgets/ImageWidget.d.ts +1 -1
  208. package/types/components/theme/Widgets/PasswordWidget.d.ts +1 -1
  209. package/types/components/theme/Widgets/RelationWidget.d.ts +1 -1
  210. package/types/components/theme/Widgets/RelationsWidget.d.ts +1 -1
  211. package/types/components/theme/Widgets/RichTextWidget.d.ts +1 -1
  212. package/types/components/theme/Widgets/SelectWidget.d.ts +1 -1
  213. package/types/components/theme/Widgets/TextWidget.d.ts +1 -1
  214. package/types/components/theme/Widgets/TitleWidget.d.ts +1 -1
  215. package/types/components/theme/Widgets/TokenWidget.d.ts +1 -1
  216. package/types/components/theme/Widgets/UrlWidget.d.ts +1 -1
  217. package/types/config/Blocks.d.ts +20 -1
  218. package/types/config/Components.d.ts +3 -0
  219. package/types/config/ContentIcons.d.ts +7 -7
  220. package/types/config/ControlPanels.d.ts +21 -21
  221. package/types/config/RichTextEditor/index.d.ts +8 -5
  222. package/types/config/Views.d.ts +40 -11
  223. package/types/config/Widgets.d.ts +58 -4
  224. package/types/error.d.ts +3 -2
  225. package/types/helpers/AsyncConnect/AsyncConnect.d.ts +2 -2
  226. package/types/helpers/Blocks/Blocks.d.ts +3 -1
  227. package/types/helpers/Extensions/withBlockSchemaEnhancer.d.ts +2 -2
  228. package/types/helpers/Helmet/Helmet.d.ts +71 -1
  229. package/types/helpers/Html/Html.d.ts +2 -2
  230. package/types/helpers/LanguageMap/LanguageMap.d.ts +1 -878
  231. package/types/helpers/Loadable/__mocks__/Loadable.d.ts +2 -2
  232. package/types/helpers/MessageLabels/MessageLabels.d.ts +1 -540
  233. package/types/helpers/ScrollToTop/ScrollToTop.d.ts +1 -1
  234. package/types/helpers/UndoManager/useUndoManager.d.ts +4 -4
  235. package/types/helpers/Url/Url.d.ts +3 -3
  236. package/types/helpers/Utils/Date.d.ts +2 -2
  237. package/types/helpers/Utils/usePagination.d.ts +1 -1
  238. package/types/helpers/Utils/usePrevious.d.ts +1 -1
  239. package/types/helpers/index.d.ts +12 -0
  240. package/types/hooks/index.d.ts +2 -1
  241. package/types/middleware/index.d.ts +2 -0
  242. package/types/reducers/blocksClipboard/blocksClipboard.d.ts +1 -1
  243. package/types/reducers/index.d.ts +40 -0
  244. package/types/registry.d.ts +1 -0
  245. package/types/routes.d.ts +31 -3
  246. package/types/server.d.ts +1 -1
  247. package/types/storybook.d.ts +3 -3
  248. package/src/components/manage/Widgets/ColorPickerWidget.stories.jsx +0 -30
@@ -0,0 +1,48 @@
1
+ import ColorPickerWidget from './ColorPickerWidget';
2
+ import WidgetStory from './story';
3
+ import type { Meta, StoryObj } from '@storybook/react';
4
+
5
+ const meta: Meta<typeof ColorPickerWidget> = {
6
+ title: 'Edit Widgets/ColorPicker',
7
+ component: WidgetStory.bind({
8
+ widget: ColorPickerWidget,
9
+ }),
10
+ decorators: [
11
+ (Story) => (
12
+ <div className="ui segment form attached" style={{ width: '400px' }}>
13
+ <Story />
14
+ </div>
15
+ ),
16
+ ],
17
+ };
18
+
19
+ export default meta;
20
+ type Story = StoryObj<typeof ColorPickerWidget>;
21
+
22
+ export const Default: Story = {
23
+ args: {
24
+ id: 'favoriteColor',
25
+ title: 'Favorite Color',
26
+ colors: [
27
+ { name: 'red', label: 'red' },
28
+ { name: 'yellow', label: 'yellow' },
29
+ { name: 'green', label: 'green' },
30
+ ],
31
+ },
32
+ };
33
+
34
+ export const WithEnhancedStyleConfig: Story = {
35
+ args: {
36
+ id: 'favoriteColor',
37
+ title: 'Favorite Color',
38
+ colors: [
39
+ { name: 'red', label: 'red', style: { '--background-color': 'red' } },
40
+ {
41
+ name: 'yellow',
42
+ label: 'yellow',
43
+ style: { '--background-color': 'yellow' },
44
+ },
45
+ { name: 'green', label: 'green' },
46
+ ],
47
+ },
48
+ };
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import PropTypes from 'prop-types';
3
2
  import { Form } from 'semantic-ui-react';
4
3
  import { Grid, Button } from 'semantic-ui-react';
4
+ import { isEqual } from 'lodash';
5
5
  import { defineMessages, useIntl } from 'react-intl';
6
6
 
7
7
  const messages = defineMessages({
@@ -11,7 +11,31 @@ const messages = defineMessages({
11
11
  },
12
12
  });
13
13
 
14
- const ColorPickerWidget = (props) => {
14
+ type Color =
15
+ | {
16
+ name: string;
17
+ label: string;
18
+ style: Record<`--${string}`, string>;
19
+ }
20
+ | {
21
+ name: string;
22
+ label: string;
23
+ style: undefined;
24
+ };
25
+
26
+ export type ColorPickerWidgetProps = {
27
+ id: string;
28
+ title: string;
29
+ value: string;
30
+ default: string;
31
+ required: boolean;
32
+ missing_value: unknown;
33
+ className: string;
34
+ onChange: (id: string, value: any) => void;
35
+ colors: Color[];
36
+ };
37
+
38
+ const ColorPickerWidget = (props: ColorPickerWidgetProps) => {
15
39
  const { id, title, required, value, onChange, colors, className } = props;
16
40
 
17
41
  const intl = useIntl();
@@ -30,6 +54,7 @@ const ColorPickerWidget = (props) => {
30
54
  className={className}
31
55
  id={'field-' + id}
32
56
  >
57
+ {/* @ts-ignore */}
33
58
  <Grid>
34
59
  <Grid.Row>
35
60
  <Grid.Column
@@ -44,21 +69,29 @@ const ColorPickerWidget = (props) => {
44
69
 
45
70
  <div className="buttons">
46
71
  {colors.map((color) => {
72
+ let colorValue: string | Color['style'];
73
+ const colorName = color.name;
74
+ if (color.style !== undefined) {
75
+ colorValue = color.style;
76
+ } else {
77
+ colorValue = color.name;
78
+ }
47
79
  return (
48
80
  <Button
49
- key={id + color.name}
50
- className={color.name}
81
+ key={id + colorName}
82
+ className={colorName}
51
83
  onClick={(e) => {
52
84
  e.preventDefault();
53
85
  e.stopPropagation();
54
86
  onChange(
55
87
  id,
56
- value === color.name
88
+ value === colorValue
57
89
  ? props.missing_value
58
- : color.name,
90
+ : colorValue,
59
91
  );
60
92
  }}
61
- active={value === color.name}
93
+ style={color.style}
94
+ active={isEqual(value, colorValue)}
62
95
  circular
63
96
  aria-label={color.label}
64
97
  title={color.label}
@@ -74,20 +107,4 @@ const ColorPickerWidget = (props) => {
74
107
  ) : null;
75
108
  };
76
109
 
77
- ColorPickerWidget.propTypes = {
78
- id: PropTypes.string.isRequired,
79
- title: PropTypes.string.isRequired,
80
- required: PropTypes.bool,
81
- value: PropTypes.string,
82
- onChange: PropTypes.func,
83
- colors: PropTypes.array,
84
- };
85
-
86
- ColorPickerWidget.defaultProps = {
87
- required: false,
88
- value: null,
89
- onChange: null,
90
- colors: [],
91
- };
92
-
93
110
  export default ColorPickerWidget;
@@ -746,7 +746,7 @@ class RecurrenceWidget extends Component {
746
746
  id={`${fieldSet || 'field'}-${id}`}
747
747
  >
748
748
  <Grid>
749
- <Grid.Row stretched>
749
+ <Grid.Row stretched verticalAlign="middle">
750
750
  <Grid.Column width="4">
751
751
  <div className="wrapper">
752
752
  <label htmlFor={`field-${id}`}>{title}</label>
@@ -14,7 +14,7 @@ beforeAll(
14
14
 
15
15
  const mockStore = configureStore();
16
16
 
17
- test('renders a recurrence widget component', async () => {
17
+ test('renders a recurrence widget component with aligned columns', async () => {
18
18
  const store = mockStore({
19
19
  intl: {
20
20
  locale: 'en',
@@ -60,6 +60,7 @@ const CommentEditModal = (props) => {
60
60
  text: {
61
61
  title: intl.formatMessage(messages.comment),
62
62
  type: 'string',
63
+ widget: 'textarea',
63
64
  description: '',
64
65
  },
65
66
  },
@@ -77,8 +77,9 @@ const Login = (props) => {
77
77
  qs.parse(props.location?.search ?? location.search).return_url ||
78
78
  location.pathname.replace(/\/login\/?$/, '').replace(/\/logout\/?$/, '') ||
79
79
  '/';
80
+
80
81
  useEffect(() => {
81
- if (token && !props.isLogout) {
82
+ if (token && !(props.isLogout || location?.state?.isLogout)) {
82
83
  history.push(returnUrl || '/');
83
84
  if (toast.isActive('loggedOut')) {
84
85
  toast.dismiss('loggedOut');
@@ -108,7 +109,16 @@ const Login = (props) => {
108
109
  dispatch(resetLoginRequest());
109
110
  }
110
111
  };
111
- }, [dispatch, token, error, intl, history, returnUrl, props.isLogout]);
112
+ }, [
113
+ dispatch,
114
+ token,
115
+ error,
116
+ intl,
117
+ history,
118
+ returnUrl,
119
+ props.isLogout,
120
+ location?.state?.isLogout,
121
+ ]);
112
122
 
113
123
  const onLogin = (event) => {
114
124
  dispatch(
@@ -48,40 +48,42 @@ const Navigation = (props) => {
48
48
  }
49
49
  setisMobileMenuOpen(false);
50
50
  };
51
-
52
51
  return (
53
52
  <nav className="navigation" id="navigation" aria-label="Site">
54
- <div className="hamburger-wrapper mobile tablet only">
55
- <button
56
- className={cx('hamburger hamburger--spin', {
57
- 'is-active': isMobileMenuOpen,
58
- })}
59
- aria-label={
60
- isMobileMenuOpen
61
- ? intl.formatMessage(messages.closeMobileMenu, {
62
- type: type,
63
- })
64
- : intl.formatMessage(messages.openMobileMenu, {
65
- type: type,
66
- })
67
- }
68
- title={
69
- isMobileMenuOpen
70
- ? intl.formatMessage(messages.closeMobileMenu, {
71
- type: type,
72
- })
73
- : intl.formatMessage(messages.openMobileMenu, {
74
- type: type,
75
- })
76
- }
77
- type="button"
78
- onClick={toggleMobileMenu}
79
- >
80
- <span className="hamburger-box">
81
- <span className="hamburger-inner" />
82
- </span>
83
- </button>
84
- </div>
53
+ {items?.length ? (
54
+ <div className="hamburger-wrapper mobile tablet only">
55
+ <button
56
+ className={cx('hamburger hamburger--spin', {
57
+ 'is-active': isMobileMenuOpen,
58
+ })}
59
+ aria-label={
60
+ isMobileMenuOpen
61
+ ? intl.formatMessage(messages.closeMobileMenu, {
62
+ type: type,
63
+ })
64
+ : intl.formatMessage(messages.openMobileMenu, {
65
+ type: type,
66
+ })
67
+ }
68
+ title={
69
+ isMobileMenuOpen
70
+ ? intl.formatMessage(messages.closeMobileMenu, {
71
+ type: type,
72
+ })
73
+ : intl.formatMessage(messages.openMobileMenu, {
74
+ type: type,
75
+ })
76
+ }
77
+ type="button"
78
+ onClick={toggleMobileMenu}
79
+ >
80
+ <span className="hamburger-box">
81
+ <span className="hamburger-inner" />
82
+ </span>
83
+ </button>
84
+ </div>
85
+ ) : null}
86
+
85
87
  <Menu
86
88
  stackable
87
89
  pointing
@@ -11,12 +11,17 @@ function PreviewImage({ item, alt, image_field, showDefault = true, ...rest }) {
11
11
  const Image = config.getComponent({ name: 'Image' }).component;
12
12
 
13
13
  const image = (
14
- <Image item={item} image_field={image_field} alt={alt} {...rest} />
14
+ <Image
15
+ item={item}
16
+ image_field={image_field || item.image_field}
17
+ alt={alt}
18
+ {...rest}
19
+ />
15
20
  );
16
21
 
17
22
  if (!image && !showDefault) return null;
18
23
 
19
- if (image) {
24
+ if (image_field || item?.image_field) {
20
25
  return image;
21
26
  } else {
22
27
  return (
@@ -33,16 +33,16 @@ export function getSitemapPath(pathname = '', lang) {
33
33
  function Sitemap(props) {
34
34
  const {
35
35
  location: { pathname },
36
- language,
36
+ lang,
37
37
  getNavigation,
38
38
  } = props;
39
39
 
40
40
  useEffect(() => {
41
41
  const { settings } = config;
42
- const lang = settings.isMultilingual ? `${toBackendLang(language)}` : null;
43
- const path = getSitemapPath(pathname, lang);
42
+ const language = settings.isMultilingual ? `${toBackendLang(lang)}` : null;
43
+ const path = getSitemapPath(pathname, language);
44
44
  getNavigation(path, 4);
45
- }, [pathname, language, getNavigation]);
45
+ }, [pathname, lang, getNavigation]);
46
46
 
47
47
  const renderItems = (items) => {
48
48
  return (
@@ -3,6 +3,7 @@ import renderer from 'react-test-renderer';
3
3
  import configureStore from 'redux-mock-store';
4
4
  import { Provider } from 'react-intl-redux';
5
5
  import { MemoryRouter } from 'react-router-dom';
6
+ import config from '@plone/volto/registry';
6
7
 
7
8
  import { __test__ as Sitemap, getSitemapPath } from './Sitemap';
8
9
 
@@ -55,6 +56,57 @@ describe('Sitemap', () => {
55
56
  });
56
57
  });
57
58
 
59
+ describe('Sitemap in a multilingual site', () => {
60
+ beforeEach(() => {
61
+ config.settings.isMultilingual = true;
62
+ config.settings.supportedLanguages = ['en', 'es'];
63
+ });
64
+ it('renders a sitemap component', () => {
65
+ const store = mockStore({
66
+ navigation: {
67
+ url: 'http://localhost:8080/Plone/en/@navigation',
68
+ items: [
69
+ {
70
+ url: 'http://localhost:8080/Plone/en/page-1',
71
+ description: '',
72
+ items: [
73
+ {
74
+ url: 'http://localhost:8080/Plone/en/page-1/page-1-2',
75
+ description: '',
76
+ title: 'Page 1-2',
77
+ },
78
+ {
79
+ url: 'http://localhost:8080/Plone/en/page-1/page-1-3',
80
+ description: '',
81
+ title: 'Page 1-3',
82
+ },
83
+ ],
84
+ title: 'Page 1-3',
85
+ },
86
+ {
87
+ url: 'http://localhost:8080/Plone/en/page-2',
88
+ description: '',
89
+ title: 'Page 2',
90
+ },
91
+ ],
92
+ },
93
+ intl: {
94
+ locale: 'en',
95
+ messages: {},
96
+ },
97
+ });
98
+ const component = renderer.create(
99
+ <Provider store={store}>
100
+ <MemoryRouter>
101
+ <Sitemap location={{ pathname: '/en/' }} />
102
+ </MemoryRouter>
103
+ </Provider>,
104
+ );
105
+ const json = component.toJSON();
106
+ expect(json).toMatchSnapshot();
107
+ });
108
+ });
109
+
58
110
  describe('getSitemapPath', () => {
59
111
  it('accepts empty path', () => {
60
112
  expect(getSitemapPath('', null)).toBe('');
@@ -1,8 +1,3 @@
1
- /**
2
- * @module components/theme/Unauthorized/Unauthorized
3
- */
4
-
5
- import React from 'react';
6
1
  import { FormattedMessage } from 'react-intl';
7
2
  import { Link } from 'react-router-dom';
8
3
  import { Container } from 'semantic-ui-react';
@@ -11,11 +6,6 @@ import { useLocation } from 'react-router-dom';
11
6
  import { withServerErrorCode } from '@plone/volto/helpers/Utils/Utils';
12
7
  import { getBaseUrl } from '@plone/volto/helpers';
13
8
 
14
- /**
15
- * unauthorized function.
16
- * @function Unauthorized
17
- * @returns {string} Markup of the unauthorized page.
18
- */
19
9
  const Unauthorized = () => {
20
10
  const error_message = useSelector((state) => state.apierror?.message);
21
11
  let location = useLocation();
@@ -32,7 +22,18 @@ const Unauthorized = () => {
32
22
  defaultMessage="You are trying to access a protected resource, please {login} first."
33
23
  values={{
34
24
  login: (
35
- <Link to={`${getBaseUrl(location.pathname)}/login`}>
25
+ <Link
26
+ to={{
27
+ pathname: `${getBaseUrl(location.pathname)}/login`,
28
+ state: {
29
+ // This is needed to cover the use case of being logged in in
30
+ // another backend (eg. in development), having a token for
31
+ // localhost and try to use it, the login route has to know that
32
+ // it's the same as it comes from a logout
33
+ isLogout: true,
34
+ },
35
+ }}
36
+ >
36
37
  <FormattedMessage id="log in" defaultMessage="log in" />
37
38
  </Link>
38
39
  ),
@@ -451,7 +451,7 @@ const blocksConfig = {
451
451
  },
452
452
  {
453
453
  id: 'daterangeFacet',
454
- title: 'Date range',
454
+ title: 'Date Range',
455
455
  view: DateRangeFacet,
456
456
  isDefault: false,
457
457
  stateToValue: DateRangeFacet.stateToValue,
@@ -563,7 +563,7 @@ export const styleToClassName = (key, value, prefix = '') => {
563
563
  };
564
564
 
565
565
  export const buildStyleClassNamesFromData = (obj = {}, prefix = '') => {
566
- // styles has the form:
566
+ // style wrapper object has the form:
567
567
  // const styles = {
568
568
  // color: 'red',
569
569
  // backgroundColor: '#AABBCC',
@@ -571,6 +571,7 @@ export const buildStyleClassNamesFromData = (obj = {}, prefix = '') => {
571
571
  // Returns: ['has--color--red', 'has--backgroundColor--AABBCC']
572
572
 
573
573
  return Object.entries(obj)
574
+ .filter(([k, v]) => !k.startsWith('--'))
574
575
  .reduce(
575
576
  (acc, [k, v]) => [
576
577
  ...acc,
@@ -602,6 +603,68 @@ export const buildStyleClassNamesExtenders = ({
602
603
  );
603
604
  };
604
605
 
606
+ /**
607
+ * Converts a name+value style pair (ex: color/red) to a pair of [k, v],
608
+ * such as ["color", "red"] so it can be converted back to an object.
609
+ * For now, only covering the 'CSSProperty' use case.
610
+ */
611
+ export const styleDataToStyleObject = (key, value, prefix = '') => {
612
+ if (prefix) {
613
+ return [`--${prefix}${key.replace('--', '')}`, value];
614
+ } else {
615
+ return [key, value];
616
+ }
617
+ };
618
+
619
+ /**
620
+ * Generate styles object from data
621
+ *
622
+ * @function buildStyleObjectFromData
623
+ * @param {Object} obj A style wrapper object data
624
+ * @param {string} prefix The prefix (could be dragged from a recursive call, initially empty)
625
+ * @return {Object} The style object ready to be passed as prop
626
+ */
627
+ export const buildStyleObjectFromData = (obj = {}, prefix = '') => {
628
+ // style wrapper object has the form:
629
+ // const styles = {
630
+ // color: 'red',
631
+ // '--background-color': '#AABBCC',
632
+ // }
633
+ // Returns: {'--background-color: '#AABBCC'}
634
+
635
+ return Object.fromEntries(
636
+ Object.entries(obj)
637
+ .filter(([k, v]) => k.startsWith('--') || isObject(v))
638
+ .reduce(
639
+ (acc, [k, v]) => [
640
+ ...acc,
641
+ // Kept for easy debugging
642
+ // ...(() => {
643
+ // if (isObject(v)) {
644
+ // return Object.entries(
645
+ // buildStyleObjectFromData(
646
+ // v,
647
+ // `${k.endsWith(':noprefix') ? '' : `${prefix}${k}--`}`,
648
+ // ),
649
+ // );
650
+ // }
651
+ // return [styleDataToStyleObject(k, v, prefix)];
652
+ // })(),
653
+ ...(isObject(v)
654
+ ? Object.entries(
655
+ buildStyleObjectFromData(
656
+ v,
657
+ `${k.endsWith(':noprefix') ? '' : `${prefix}${k}--`}`, // We don't add a prefix if the key ends with the marker suffix
658
+ ),
659
+ )
660
+ : [styleDataToStyleObject(k, v, prefix)]),
661
+ ],
662
+ [],
663
+ )
664
+ .filter((v) => !!v),
665
+ );
666
+ };
667
+
605
668
  /**
606
669
  * Return previous/next blocks given the content object and the current block id
607
670
  *
@@ -18,6 +18,7 @@ import {
18
18
  applySchemaDefaults,
19
19
  buildStyleClassNamesFromData,
20
20
  buildStyleClassNamesExtenders,
21
+ buildStyleObjectFromData,
21
22
  getPreviousNextBlock,
22
23
  blocksFormGenerator,
23
24
  findBlocks,
@@ -1066,6 +1067,82 @@ describe('Blocks', () => {
1066
1067
  };
1067
1068
  expect(buildStyleClassNamesFromData(styles)).toEqual([]);
1068
1069
  });
1070
+
1071
+ it('It does not output any className for style converter values', () => {
1072
+ const styles = {
1073
+ color: 'red',
1074
+ '--background-color': '#FFF',
1075
+ };
1076
+ expect(buildStyleClassNamesFromData(styles)).toEqual(['has--color--red']);
1077
+ });
1078
+
1079
+ it.skip('It does not output any className for unknown converter values', () => {
1080
+ const styles = {
1081
+ color: 'red',
1082
+ 'backgroundColor:style': '#FFF',
1083
+ };
1084
+ expect(buildStyleClassNamesFromData(styles)).toEqual(['has--color--red']);
1085
+ });
1086
+ });
1087
+
1088
+ describe('buildStyleObjectFromData', () => {
1089
+ it('Understands style converter for style values, no styles found', () => {
1090
+ const styles = {
1091
+ color: 'red',
1092
+ backgroundColor: '#FFF',
1093
+ };
1094
+ expect(buildStyleObjectFromData(styles)).toEqual({});
1095
+ });
1096
+
1097
+ it('Understands style converter for style values', () => {
1098
+ const styles = {
1099
+ color: 'red',
1100
+ '--background-color': '#FFF',
1101
+ };
1102
+ expect(buildStyleObjectFromData(styles)).toEqual({
1103
+ '--background-color': '#FFF',
1104
+ });
1105
+ });
1106
+
1107
+ it('Supports multiple nested levels', () => {
1108
+ const styles = {
1109
+ '--color': 'red',
1110
+ backgroundColor: '#AABBCC',
1111
+ nested: {
1112
+ l1: 'white',
1113
+ '--foo': 'white',
1114
+ level2: {
1115
+ '--foo': '#fff',
1116
+ bar: '#000',
1117
+ },
1118
+ },
1119
+ };
1120
+ expect(buildStyleObjectFromData(styles)).toEqual({
1121
+ '--color': 'red',
1122
+ '--nested--foo': 'white',
1123
+ '--nested--level2--foo': '#fff',
1124
+ });
1125
+ });
1126
+
1127
+ it('Supports multiple nested levels and optional inclusion of the name of the level', () => {
1128
+ const styles = {
1129
+ '--color': 'red',
1130
+ backgroundColor: '#AABBCC',
1131
+ 'nested:noprefix': {
1132
+ l1: 'white',
1133
+ '--foo': 'white',
1134
+ level2: {
1135
+ '--foo': '#fff',
1136
+ bar: '#000',
1137
+ },
1138
+ },
1139
+ };
1140
+ expect(buildStyleObjectFromData(styles)).toEqual({
1141
+ '--color': 'red',
1142
+ '--foo': 'white',
1143
+ '--level2--foo': '#fff',
1144
+ });
1145
+ });
1069
1146
  });
1070
1147
 
1071
1148
  describe('getPreviousNextBlock', () => {
@@ -47,7 +47,7 @@ export const addExtensionFieldToSchema = ({
47
47
  items,
48
48
  intl,
49
49
  title,
50
- description,
50
+ description = '',
51
51
  insertFieldToOrder = _addField,
52
52
  }) => {
53
53
  const _ = intl.formatMessage;
@@ -64,6 +64,8 @@ export const addExtensionFieldToSchema = ({
64
64
 
65
65
  schema.properties[name] = {
66
66
  title: _(title),
67
+ // TODO: is description sensible in here? The argument is not used anywhere
68
+ // description: _(description),
67
69
  choices: items?.map(({ id, title }) => [
68
70
  id,
69
71
  _({ id: title, defaultMessage: title }),
@@ -58,6 +58,7 @@ export {
58
58
  blocksFormGenerator,
59
59
  buildStyleClassNamesFromData,
60
60
  buildStyleClassNamesExtenders,
61
+ buildStyleObjectFromData,
61
62
  getPreviousNextBlock,
62
63
  findBlocks,
63
64
  } from '@plone/volto/helpers/Blocks/Blocks';
@@ -784,10 +784,12 @@ body.has-toolbar.has-sidebar-collapsed .ui.wrapper > .ui.inner.block.full {
784
784
  // reseting the default Accordion behavior
785
785
  display: initial;
786
786
  }
787
+
787
788
  .ui.form .ui.input input {
788
789
  //reset for semantic-ui outline:none
789
790
  border-width: @1px;
790
791
  border-color: transparent;
792
+
791
793
  &:focus {
792
794
  border-color: @focusedFormBorderColor;
793
795
  }