@plone/volto 17.0.0-alpha.1 → 17.0.0-alpha.10

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 (179) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/CHANGELOG.md +396 -16
  3. package/CONTRIBUTING.md +1 -1
  4. package/README.md +12 -15
  5. package/addon-registry.js +34 -0
  6. package/create-theme-addons-loader.js +79 -0
  7. package/cypress/support/commands.js +25 -0
  8. package/locales/ca/LC_MESSAGES/volto.po +187 -6
  9. package/locales/ca.json +1 -1
  10. package/locales/de/LC_MESSAGES/volto.po +206 -25
  11. package/locales/de.json +1 -1
  12. package/locales/en/LC_MESSAGES/volto.po +186 -5
  13. package/locales/en.json +1 -1
  14. package/locales/es/LC_MESSAGES/volto.po +187 -6
  15. package/locales/es.json +1 -1
  16. package/locales/eu/LC_MESSAGES/volto.po +187 -6
  17. package/locales/eu.json +1 -1
  18. package/locales/fi/LC_MESSAGES/volto.po +4792 -0
  19. package/locales/fi.json +1 -1
  20. package/locales/fr/LC_MESSAGES/volto.po +187 -6
  21. package/locales/fr.json +1 -1
  22. package/locales/it/LC_MESSAGES/volto.po +187 -6
  23. package/locales/it.json +1 -1
  24. package/locales/ja/LC_MESSAGES/volto.po +187 -6
  25. package/locales/ja.json +1 -1
  26. package/locales/nl/LC_MESSAGES/volto.po +842 -649
  27. package/locales/nl.json +1 -1
  28. package/locales/pt/LC_MESSAGES/volto.po +187 -6
  29. package/locales/pt.json +1 -1
  30. package/locales/pt_BR/LC_MESSAGES/volto.po +195 -14
  31. package/locales/pt_BR.json +1 -1
  32. package/locales/ro/LC_MESSAGES/volto.po +187 -6
  33. package/locales/ro.json +1 -1
  34. package/locales/volto.pot +187 -6
  35. package/locales/zh_CN/LC_MESSAGES/volto.po +187 -6
  36. package/locales/zh_CN.json +1 -1
  37. package/package-why.json +0 -1
  38. package/package.json +9 -8
  39. package/packages/volto-slate/build/messages/src/blocks/Table/TableBlockEdit.json +1 -1
  40. package/packages/volto-slate/build/messages/src/blocks/Text/DefaultTextBlockEditor.json +1 -1
  41. package/packages/volto-slate/build/messages/src/blocks/Text/DetachedTextBlockEditor.json +1 -1
  42. package/packages/volto-slate/build/messages/src/blocks/Text/SlashMenu.json +1 -1
  43. package/packages/volto-slate/build/messages/src/editor/plugins/AdvancedLink/index.json +1 -1
  44. package/packages/volto-slate/build/messages/src/editor/plugins/Link/index.json +1 -1
  45. package/packages/volto-slate/build/messages/src/editor/plugins/Table/index.json +1 -1
  46. package/packages/volto-slate/build/messages/src/elementEditor/messages.json +1 -1
  47. package/packages/volto-slate/build/messages/src/widgets/HtmlSlateWidget.json +1 -1
  48. package/packages/volto-slate/build/messages/src/widgets/RichTextWidgetView.json +1 -1
  49. package/packages/volto-slate/package.json +1 -1
  50. package/packages/volto-slate/src/blocks/Table/index.js +2 -0
  51. package/packages/volto-slate/src/blocks/Text/SlashMenu.jsx +4 -3
  52. package/packages/volto-slate/src/editor/deserialize.js +0 -1
  53. package/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx +14 -4
  54. package/razzle.config.js +28 -0
  55. package/src/actions/index.js +6 -0
  56. package/src/actions/language/language.js +9 -8
  57. package/src/actions/querystringsearch/querystringsearch.js +20 -14
  58. package/src/actions/relations/rebuild.js +25 -0
  59. package/src/actions/relations/relations.js +86 -0
  60. package/src/actions/relations/relations.test.js +15 -0
  61. package/src/components/index.js +1 -0
  62. package/src/components/manage/Add/Add.jsx +2 -2
  63. package/src/components/manage/BlockChooser/BlockChooser.jsx +14 -5
  64. package/src/components/manage/BlockChooser/BlockChooser.test.jsx +5 -0
  65. package/src/components/manage/Blocks/Listing/Edit.jsx +0 -19
  66. package/src/components/manage/Blocks/Listing/ListingBody.jsx +77 -61
  67. package/src/components/manage/Blocks/Listing/View.jsx +0 -4
  68. package/src/components/manage/Blocks/Listing/getAsyncData.js +10 -2
  69. package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +18 -13
  70. package/src/components/manage/Blocks/Search/SearchBlockEdit.jsx +5 -4
  71. package/src/components/manage/Blocks/Search/SearchBlockView.jsx +2 -1
  72. package/src/components/manage/Blocks/Search/components/DateRangeFacet.jsx +4 -1
  73. package/src/components/manage/Blocks/Search/components/Facets.jsx +58 -2
  74. package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +24 -11
  75. package/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx +17 -5
  76. package/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx +17 -5
  77. package/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx +21 -5
  78. package/src/components/manage/Blocks/Search/schema.js +16 -1
  79. package/src/components/manage/Blocks/ToC/Edit.jsx +1 -0
  80. package/src/components/manage/Contents/Contents.jsx +69 -33
  81. package/src/components/manage/Contents/ContentsItem.jsx +6 -0
  82. package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +3 -3
  83. package/src/components/manage/Controlpanels/Controlpanels.jsx +199 -224
  84. package/src/components/manage/Controlpanels/Controlpanels.test.jsx +46 -7
  85. package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +66 -0
  86. package/src/components/manage/Controlpanels/Relations/Relations.jsx +114 -0
  87. package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +479 -0
  88. package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +531 -0
  89. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.jsx +3 -3
  90. package/src/components/manage/Controlpanels/Users/UserGroupMembershipListing.jsx +51 -82
  91. package/src/components/manage/Controlpanels/Users/UserGroupMembershipMatrix.jsx +79 -75
  92. package/src/components/manage/DragDropList/DragDropList.jsx +63 -42
  93. package/src/components/manage/Form/BlocksToolbar.jsx +5 -1
  94. package/src/components/manage/Form/Form.jsx +11 -5
  95. package/src/components/manage/Form/InlineForm.jsx +39 -9
  96. package/src/components/manage/Form/InlineFormState.js +8 -0
  97. package/src/components/manage/Multilingual/CreateTranslation.jsx +2 -2
  98. package/src/components/manage/Multilingual/TranslationObject.jsx +4 -3
  99. package/src/components/manage/Preferences/ChangePassword.jsx +2 -2
  100. package/src/components/manage/Preferences/PersonalPreferences.jsx +2 -2
  101. package/src/components/manage/Toast/Toast.jsx +1 -1
  102. package/src/components/manage/Toolbar/Types.jsx +2 -2
  103. package/src/components/manage/Widgets/DatetimeWidget.jsx +9 -5
  104. package/src/components/manage/Widgets/ObjectListWidget.jsx +3 -8
  105. package/src/components/manage/Widgets/RecurrenceWidget/ByDayField.jsx +2 -1
  106. package/src/components/manage/Widgets/RecurrenceWidget/MonthOfTheYearField.jsx +2 -1
  107. package/src/components/manage/Widgets/RecurrenceWidget/Occurences.jsx +2 -1
  108. package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +7 -2
  109. package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthField.jsx +2 -1
  110. package/src/components/manage/Widgets/SelectUtils.js +1 -1
  111. package/src/components/manage/Widgets/SelectWidget.jsx +1 -1
  112. package/src/components/theme/Footer/Footer.jsx +2 -13
  113. package/src/components/theme/Header/Header.jsx +37 -63
  114. package/src/components/theme/Header/Header.test.jsx +18 -0
  115. package/src/components/theme/Icon/Icon.jsx +2 -2
  116. package/src/components/theme/LanguageSelector/LanguageSelector.js +8 -3
  117. package/src/components/theme/Login/Login.jsx +1 -0
  118. package/src/components/theme/Logo/Logo.jsx +2 -1
  119. package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +2 -2
  120. package/src/components/theme/Navigation/NavItem.jsx +4 -2
  121. package/src/components/theme/NotFound/NotFound.jsx +55 -41
  122. package/src/components/theme/PasswordReset/PasswordReset.jsx +7 -4
  123. package/src/components/theme/PasswordReset/RequestPasswordReset.jsx +1 -1
  124. package/src/components/theme/Sitemap/Sitemap.jsx +5 -3
  125. package/src/components/theme/View/DefaultView.jsx +1 -1
  126. package/src/components/theme/View/EventDatesInfo.jsx +2 -1
  127. package/src/components/theme/View/RenderBlocks.jsx +7 -1
  128. package/src/components/theme/Widgets/DateWidget.jsx +2 -1
  129. package/src/components/theme/Widgets/DatetimeWidget.jsx +2 -1
  130. package/src/components/theme/Widgets/RelationsWidget.jsx +13 -11
  131. package/src/config/ControlPanels.js +2 -0
  132. package/src/config/Widgets.jsx +1 -0
  133. package/src/config/index.js +2 -0
  134. package/src/constants/ActionTypes.js +4 -0
  135. package/src/constants/Languages.js +8 -4
  136. package/src/express-middleware/sitemap.js +36 -4
  137. package/src/helpers/Api/Api.js +1 -1
  138. package/src/helpers/FormValidation/FormValidation.js +11 -2
  139. package/src/helpers/FormValidation/FormValidation.test.js +73 -0
  140. package/src/helpers/Html/Html.jsx +3 -1
  141. package/src/helpers/Html/Html.test.jsx +5 -0
  142. package/src/helpers/MessageLabels/MessageLabels.js +72 -0
  143. package/src/helpers/Robots/Robots.js +24 -6
  144. package/src/helpers/Sitemap/Sitemap.js +44 -2
  145. package/src/helpers/Url/Url.js +27 -6
  146. package/src/helpers/Url/Url.test.js +26 -0
  147. package/src/helpers/Utils/Utils.js +38 -13
  148. package/src/helpers/Utils/Utils.test.js +4 -4
  149. package/src/helpers/index.js +7 -2
  150. package/src/hooks/userSession/useToken.js +5 -0
  151. package/src/middleware/Api.test.js +54 -0
  152. package/src/middleware/api.js +8 -4
  153. package/src/reducers/actions/actions.js +1 -1
  154. package/src/reducers/breadcrumbs/breadcrumbs.js +1 -1
  155. package/src/reducers/index.js +2 -0
  156. package/src/reducers/navigation/navigation.js +1 -1
  157. package/src/reducers/relations/relations.js +173 -0
  158. package/src/reducers/types/types.js +1 -1
  159. package/src/routes.js +5 -0
  160. package/src/server.jsx +28 -23
  161. package/test-setup-config.js +1 -0
  162. package/theme/themes/pastanaga/extras/contents.less +1 -0
  163. package/theme/themes/pastanaga/extras/main.less +80 -1
  164. package/theme/themes/pastanaga/extras/search.less +6 -0
  165. package/theme/themes/pastanaga/extras/sidebar.less +4 -0
  166. package/theme/themes/pastanaga/extras/userscontrolpanel.less +99 -76
  167. package/.changelog.draft +0 -28
  168. package/.editorconfig +0 -36
  169. package/.storybook/main.js +0 -127
  170. package/.storybook/manager.js +0 -15
  171. package/.storybook/preview.js +0 -21
  172. package/.storybook/static/previewImage.svg +0 -48
  173. package/.yarnrc.yml +0 -5
  174. package/jsdoc.json +0 -16
  175. package/netlify.toml +0 -5
  176. package/pyvenv.cfg +0 -3
  177. package/share/man/man1/ttx.1 +0 -225
  178. package/src/components/theme/Header/Header.md +0 -27
  179. package/towncrier.toml +0 -33
@@ -4,6 +4,7 @@ import { defineMessages, injectIntl } from 'react-intl';
4
4
  import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
5
5
  import { compose } from 'redux';
6
6
  import { Icon } from '@plone/volto/components';
7
+ import { toBackendLang } from '@plone/volto/helpers/Utils/Utils';
7
8
  import { connect } from 'react-redux';
8
9
 
9
10
  import leftKey from '@plone/volto/icons/left-key.svg';
@@ -82,7 +83,9 @@ const DateRangeFacet = (props) => {
82
83
  noBorder
83
84
  showClearDates
84
85
  customCloseIcon={<CloseIcon />}
85
- displayFormat={moment.localeData(lang).longDateFormat('L')}
86
+ displayFormat={moment
87
+ .localeData(toBackendLang(lang))
88
+ .longDateFormat('L')}
86
89
  focusedInput={focused}
87
90
  onFocusChange={(focusedInput) => setFocused(focusedInput)}
88
91
  onDatesChange={({ startDate, endDate }) => {
@@ -1,7 +1,16 @@
1
- import React from 'react';
1
+ import React, { useState, useMemo } from 'react';
2
+ import { Button, Grid } from 'semantic-ui-react';
2
3
  import { resolveExtension } from '@plone/volto/helpers/Extensions/withBlockExtensions';
3
4
  import config from '@plone/volto/registry';
4
5
  import { hasNonValueOperation, hasDateOperation } from '../utils';
6
+ import { defineMessages, useIntl } from 'react-intl';
7
+
8
+ const messages = defineMessages({
9
+ moreFilters: { id: 'More filters', defaultMessage: 'More filters' },
10
+ lessFilters: { id: 'Less filters', defaultMessage: 'Less filters' },
11
+ showFilters: { id: 'Show filters', defaultMessage: 'Show filters' },
12
+ hideFilters: { id: 'Hide filters', defaultMessage: 'Hide filters' },
13
+ });
5
14
 
6
15
  const showFacet = (index) => {
7
16
  const { values } = index;
@@ -14,6 +23,7 @@ const showFacet = (index) => {
14
23
  };
15
24
 
16
25
  const Facets = (props) => {
26
+ const [hidden, setHidden] = useState(true);
17
27
  const {
18
28
  querystring,
19
29
  data = {},
@@ -24,11 +34,29 @@ const Facets = (props) => {
24
34
  } = props;
25
35
  const { search } = config.blocks.blocksConfig;
26
36
 
37
+ const advancedFilters = useMemo(() => {
38
+ let count = 0;
39
+ for (let facetSettings of data.facets || []) {
40
+ if (facetSettings.advanced) {
41
+ count++;
42
+ }
43
+ }
44
+
45
+ if (count === data.facets?.length) {
46
+ return 2;
47
+ }
48
+ if (count) {
49
+ return 1;
50
+ }
51
+ return 0;
52
+ }, [data.facets]);
53
+
27
54
  const FacetWrapper = facetWrapper;
28
55
  const query_to_values = Object.assign(
29
56
  {},
30
57
  ...(data?.query?.query?.map(({ i, v }) => ({ [i]: v })) || []),
31
58
  );
59
+ const intl = useIntl();
32
60
 
33
61
  return (
34
62
  <>
@@ -36,6 +64,7 @@ const Facets = (props) => {
36
64
  ?.filter((facetSettings) => !facetSettings.hidden)
37
65
  .map((facetSettings) => {
38
66
  const field = facetSettings?.field?.value;
67
+ const isAdvanced = facetSettings?.advanced;
39
68
  const index = querystring.indexes[field] || {};
40
69
  const { values = {} } = index;
41
70
 
@@ -58,6 +87,7 @@ const Facets = (props) => {
58
87
 
59
88
  const isMulti = facetSettings.multiple;
60
89
  const selectedValue = facets[facetSettings?.field?.value];
90
+ const visible = (isAdvanced && !hidden) || !isAdvanced;
61
91
 
62
92
  // TODO :handle changing the type of facet (multi/nonmulti)
63
93
 
@@ -74,7 +104,11 @@ const Facets = (props) => {
74
104
  } = search.extensions.facetWidgets;
75
105
 
76
106
  return FacetWrapper && (isEditMode || showFacet(index)) ? (
77
- <FacetWrapper key={facetSettings['@id']}>
107
+ <FacetWrapper
108
+ key={facetSettings['@id']}
109
+ facetSettings={facetSettings}
110
+ visible={visible}
111
+ >
78
112
  <FacetWidget
79
113
  facet={facetSettings}
80
114
  choices={rewriteOptions(facetSettings?.field?.value, choices)}
@@ -90,6 +124,28 @@ const Facets = (props) => {
90
124
  ''
91
125
  );
92
126
  })}
127
+ {advancedFilters > 0 && (
128
+ <Grid.Column
129
+ mobile={12}
130
+ tablet={12}
131
+ computer={12}
132
+ className="toggle-advanced-facets"
133
+ >
134
+ <Button
135
+ onClick={() => {
136
+ setHidden((prevHidden) => !prevHidden);
137
+ }}
138
+ >
139
+ {hidden
140
+ ? advancedFilters === 2
141
+ ? intl.formatMessage(messages.showFilters)
142
+ : intl.formatMessage(messages.moreFilters)
143
+ : advancedFilters === 2
144
+ ? intl.formatMessage(messages.hideFilters)
145
+ : intl.formatMessage(messages.lessFilters)}
146
+ </Button>
147
+ </Grid.Column>
148
+ )}
93
149
  </>
94
150
  );
95
151
  };
@@ -114,15 +114,19 @@ function normalizeState({
114
114
  block: id,
115
115
  };
116
116
 
117
- // TODO: need to check if SearchableText facet is not already in the query
118
- // Ideally the searchtext functionality should be restructured as being just
119
- // another facet
120
- params.query = params.query.reduce(
121
- // Remove SearchableText from query
122
- (acc, kvp) => (kvp.i === 'SearchableText' ? acc : [...acc, kvp]),
123
- [],
124
- );
117
+ // Note Ideally the searchtext functionality should be restructured as being just
118
+ // another facet. But right now it's the same. This means that if a searchText
119
+ // is provided, it will override the SearchableText facet.
120
+ // If there is no searchText, the SearchableText in the query remains in effect.
121
+ // TODO eventually the searchText should be a distinct facet from SearchableText, and
122
+ // the two conditions could be combined, in comparison to the current state, when
123
+ // one overrides the other.
125
124
  if (searchText) {
125
+ params.query = params.query.reduce(
126
+ // Remove SearchableText from query
127
+ (acc, kvp) => (kvp.i === 'SearchableText' ? acc : [...acc, kvp]),
128
+ [],
129
+ );
126
130
  params.query.push({
127
131
  i: 'SearchableText',
128
132
  o: 'plone.app.querystring.operation.string.contains',
@@ -278,8 +282,14 @@ const withSearch = (options) => (WrappedComponent) => {
278
282
  const timeoutRef = React.useRef();
279
283
  const facetSettings = data?.facets;
280
284
 
285
+ const deepQuery = JSON.stringify(data.query);
281
286
  const onTriggerSearch = React.useCallback(
282
- (toSearchText, toSearchFacets, toSortOn, toSortOrder) => {
287
+ (
288
+ toSearchText = undefined,
289
+ toSearchFacets = undefined,
290
+ toSortOn = undefined,
291
+ toSortOrder = undefined,
292
+ ) => {
283
293
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
284
294
  timeoutRef.current = setTimeout(
285
295
  () => {
@@ -287,7 +297,7 @@ const withSearch = (options) => (WrappedComponent) => {
287
297
  id,
288
298
  query: data.query || {},
289
299
  facets: toSearchFacets || facets,
290
- searchText: toSearchText,
300
+ searchText: toSearchText || searchText,
291
301
  sortOn: toSortOn || sortOn,
292
302
  sortOrder: toSortOrder || sortOrder,
293
303
  facetSettings,
@@ -301,11 +311,14 @@ const withSearch = (options) => (WrappedComponent) => {
301
311
  toSearchFacets ? inputDelay / 3 : inputDelay,
302
312
  );
303
313
  },
314
+ // eslint-disable-next-line react-hooks/exhaustive-deps
304
315
  [
305
- data.query,
316
+ // Use deep comparison of data.query
317
+ deepQuery,
306
318
  facets,
307
319
  id,
308
320
  setLocationSearchData,
321
+ searchText,
309
322
  sortOn,
310
323
  sortOrder,
311
324
  facetSettings,
@@ -11,6 +11,7 @@ import { Grid, Segment } from 'semantic-ui-react';
11
11
  import { Button } from 'semantic-ui-react';
12
12
  import { flushSync } from 'react-dom';
13
13
  import { defineMessages, useIntl } from 'react-intl';
14
+ import cx from 'classnames';
14
15
 
15
16
  const messages = defineMessages({
16
17
  searchButtonText: {
@@ -19,11 +20,22 @@ const messages = defineMessages({
19
20
  },
20
21
  });
21
22
 
22
- const FacetWrapper = ({ children }) => (
23
- <Segment basic className="facet">
24
- {children}
25
- </Segment>
26
- );
23
+ const FacetWrapper = ({ children, facetSettings = {}, visible }) => {
24
+ const { advanced, field = {} } = facetSettings;
25
+
26
+ return (
27
+ <Segment
28
+ basic
29
+ className={cx('facet', {
30
+ [`facet-index-${field.value}`]: !!field.value,
31
+ 'advanced-facet': advanced,
32
+ 'advanced-facet-hidden': !visible,
33
+ })}
34
+ >
35
+ {children}
36
+ </Segment>
37
+ );
38
+ };
27
39
 
28
40
  const LeftColumnFacets = (props) => {
29
41
  const {
@@ -11,6 +11,7 @@ import { Grid, Segment } from 'semantic-ui-react';
11
11
  import { Button } from 'semantic-ui-react';
12
12
  import { flushSync } from 'react-dom';
13
13
  import { defineMessages, useIntl } from 'react-intl';
14
+ import cx from 'classnames';
14
15
 
15
16
  const messages = defineMessages({
16
17
  searchButtonText: {
@@ -19,11 +20,22 @@ const messages = defineMessages({
19
20
  },
20
21
  });
21
22
 
22
- const FacetWrapper = ({ children }) => (
23
- <Segment basic className="facet">
24
- {children}
25
- </Segment>
26
- );
23
+ const FacetWrapper = ({ children, facetSettings = {}, visible }) => {
24
+ const { advanced, field = {} } = facetSettings;
25
+
26
+ return (
27
+ <Segment
28
+ basic
29
+ className={cx('facet', {
30
+ [`facet-index-${field.value}`]: !!field.value,
31
+ 'advanced-facet': advanced,
32
+ 'advanced-facet-hidden': !visible,
33
+ })}
34
+ >
35
+ {children}
36
+ </Segment>
37
+ );
38
+ };
27
39
 
28
40
  const RightColumnFacets = (props) => {
29
41
  const {
@@ -11,6 +11,7 @@ import {
11
11
  SortOn,
12
12
  ViewSwitcher,
13
13
  } from '../components';
14
+ import cx from 'classnames';
14
15
 
15
16
  const messages = defineMessages({
16
17
  searchButtonText: {
@@ -19,11 +20,24 @@ const messages = defineMessages({
19
20
  },
20
21
  });
21
22
 
22
- const FacetWrapper = ({ children }) => (
23
- <Grid.Column mobile={12} tablet={4} computer={3}>
24
- {children}
25
- </Grid.Column>
26
- );
23
+ const FacetWrapper = ({ children, facetSettings = {}, visible }) => {
24
+ const { advanced, field = {} } = facetSettings;
25
+
26
+ return (
27
+ <Grid.Column
28
+ mobile={12}
29
+ tablet={4}
30
+ computer={3}
31
+ className={cx('facet', {
32
+ [`facet-index-${field.value}`]: !!field.value,
33
+ 'advanced-facet': advanced,
34
+ 'advanced-facet-hidden': !visible,
35
+ })}
36
+ >
37
+ {children}
38
+ </Grid.Column>
39
+ );
40
+ };
27
41
 
28
42
  const TopSideFacets = (props) => {
29
43
  const {
@@ -117,6 +131,7 @@ const TopSideFacets = (props) => {
117
131
  <ViewSwitcher {...props} />
118
132
  )}
119
133
  </div>
134
+
120
135
  {data.facets?.length > 0 && (
121
136
  <div className="facets">
122
137
  {data.facetsTitle && <h3>{data.facetsTitle}</h3>}
@@ -136,6 +151,7 @@ const TopSideFacets = (props) => {
136
151
  </Grid>
137
152
  </div>
138
153
  )}
154
+
139
155
  <SearchDetails
140
156
  text={searchedText}
141
157
  total={totalItems}
@@ -88,6 +88,15 @@ const messages = defineMessages({
88
88
  defaultMessage:
89
89
  'Hidden facets will still filter the results if proper parameters are passed in URLs',
90
90
  },
91
+ advancedFacetTitle: {
92
+ id: 'Advanced facet?',
93
+ defaultMessage: 'Advanced facet?',
94
+ },
95
+ advancedFacetDescription: {
96
+ id: 'Advanced facets are initially hidden and displayed on demand',
97
+ defaultMessage:
98
+ 'Advanced facets are initially hidden and displayed on demand',
99
+ },
91
100
  facetWidget: {
92
101
  id: 'Facet widget',
93
102
  defaultMessage: 'Facet widget',
@@ -131,7 +140,7 @@ const FacetSchema = ({ intl }) => ({
131
140
  {
132
141
  id: 'default',
133
142
  title: 'Default',
134
- fields: ['title', 'field', 'type', 'hidden'],
143
+ fields: ['title', 'field', 'type', 'hidden', 'advanced'],
135
144
  },
136
145
  ],
137
146
  properties: {
@@ -170,6 +179,12 @@ const FacetSchema = ({ intl }) => ({
170
179
  default: false,
171
180
  description: intl.formatMessage(messages.hideFacetDescription),
172
181
  },
182
+ advanced: {
183
+ type: 'boolean',
184
+ title: intl.formatMessage(messages.advancedFacetTitle),
185
+ default: false,
186
+ description: intl.formatMessage(messages.advancedFacetDescription),
187
+ },
173
188
  type: {
174
189
  title: intl.formatMessage(messages.facetWidget),
175
190
  choices: config.blocks.blocksConfig.search.extensions.facetWidgets.types.map(
@@ -26,6 +26,7 @@ class Edit extends Component {
26
26
  }}
27
27
  onChangeBlock={this.props.onChangeBlock}
28
28
  formData={this.props.data}
29
+ block={this.props.block}
29
30
  />
30
31
  </SidebarPortal>
31
32
  </>
@@ -290,6 +290,10 @@ const messages = defineMessages({
290
290
  id: 'This Page is referenced by the following items:',
291
291
  defaultMessage: 'This Page is referenced by the following items:',
292
292
  },
293
+ deleteItemCountMessage: {
294
+ id: 'Total items to be deleted:',
295
+ defaultMessage: 'Total items to be deleted:',
296
+ },
293
297
  deleteItemMessage: {
294
298
  id: 'Items to be deleted:',
295
299
  defaultMessage: 'Items to be deleted:',
@@ -418,6 +422,8 @@ class Contents extends Component {
418
422
  this.paste = this.paste.bind(this);
419
423
  this.fetchContents = this.fetchContents.bind(this);
420
424
  this.orderTimeout = null;
425
+ this.deleteItemsToShowThreshold = 10;
426
+
421
427
  this.state = {
422
428
  selected: [],
423
429
  showDelete: false,
@@ -427,6 +433,7 @@ class Contents extends Component {
427
433
  showProperties: false,
428
434
  showWorkflow: false,
429
435
  itemsToDelete: [],
436
+ showAllItemsToDelete: true,
430
437
  items: this.props.items,
431
438
  filter: '',
432
439
  currentPage: 0,
@@ -456,7 +463,6 @@ class Contents extends Component {
456
463
  this.fetchContents();
457
464
  this.setState({ isClient: true });
458
465
  }
459
-
460
466
  async componentDidUpdate(_, prevState) {
461
467
  if (
462
468
  this.state.itemsToDelete !== prevState.itemsToDelete &&
@@ -468,6 +474,8 @@ class Contents extends Component {
468
474
  this.getFieldById(item, 'UID'),
469
475
  ),
470
476
  ),
477
+ showAllItemsToDelete:
478
+ this.state.itemsToDelete.length < this.deleteItemsToShowThreshold,
471
479
  });
472
480
  }
473
481
  }
@@ -788,18 +796,20 @@ class Contents extends Component {
788
796
  */
789
797
  onMoveToTop(event, { value }) {
790
798
  const id = this.state.items[value]['@id'];
791
- value = this.state.currentPage * this.state.pageSize + value;
792
- this.props.orderContent(
793
- getBaseUrl(this.props.pathname),
794
- id.replace(/^.*\//, ''),
795
- -value,
796
- );
797
- this.setState(
798
- {
799
- currentPage: 0,
800
- },
801
- () => this.fetchContents(),
802
- );
799
+ this.props
800
+ .orderContent(
801
+ getBaseUrl(this.props.pathname),
802
+ id.replace(/^.*\//, ''),
803
+ 'top',
804
+ )
805
+ .then(() => {
806
+ this.setState(
807
+ {
808
+ currentPage: 0,
809
+ },
810
+ () => this.fetchContents(),
811
+ );
812
+ });
803
813
  }
804
814
 
805
815
  /**
@@ -810,18 +820,21 @@ class Contents extends Component {
810
820
  * @returns {undefined}
811
821
  */
812
822
  onMoveToBottom(event, { value }) {
813
- this.onOrderItem(
814
- this.state.items[value]['@id'],
815
- value,
816
- this.state.items.length - 1 - value,
817
- false,
818
- );
819
- this.onOrderItem(
820
- this.state.items[value]['@id'],
821
- value,
822
- this.state.items.length - 1 - value,
823
- true,
824
- );
823
+ const id = this.state.items[value]['@id'];
824
+ this.props
825
+ .orderContent(
826
+ getBaseUrl(this.props.pathname),
827
+ id.replace(/^.*\//, ''),
828
+ 'bottom',
829
+ )
830
+ .then(() => {
831
+ this.setState(
832
+ {
833
+ currentPage: 0,
834
+ },
835
+ () => this.fetchContents(),
836
+ );
837
+ });
825
838
  }
826
839
 
827
840
  /**
@@ -1000,6 +1013,7 @@ class Contents extends Component {
1000
1013
  sort_order: this.state.sort_order,
1001
1014
  metadata_fields: '_all',
1002
1015
  b_size: 100000000,
1016
+ show_inactive: true,
1003
1017
  ...(this.state.filter && { SearchableText: `${this.state.filter}*` }),
1004
1018
  });
1005
1019
  } else {
@@ -1011,6 +1025,7 @@ class Contents extends Component {
1011
1025
  ...(this.state.filter && { SearchableText: `${this.state.filter}*` }),
1012
1026
  b_size: this.state.pageSize,
1013
1027
  b_start: this.state.currentPage * this.state.pageSize,
1028
+ show_inactive: true,
1014
1029
  });
1015
1030
  }
1016
1031
  }
@@ -1188,16 +1203,35 @@ class Contents extends Component {
1188
1203
  <div className="content">
1189
1204
  <h3>
1190
1205
  {this.props.intl.formatMessage(
1191
- messages.deleteItemMessage,
1192
- )}
1206
+ messages.deleteItemCountMessage,
1207
+ ) + ` ${this.state.itemsToDelete.length}`}
1193
1208
  </h3>
1194
1209
  <ul className="content">
1195
- {map(this.state.itemsToDelete, (item) => (
1196
- <li key={item}>
1197
- {this.getFieldById(item, 'title')}
1198
- </li>
1199
- ))}
1210
+ {map(
1211
+ this.state.showAllItemsToDelete
1212
+ ? this.state.itemsToDelete
1213
+ : this.state.itemsToDelete.slice(
1214
+ 0,
1215
+ this.deleteItemsToShowThreshold,
1216
+ ),
1217
+ (item) => (
1218
+ <li key={item}>
1219
+ {this.getFieldById(item, 'title')}
1220
+ </li>
1221
+ ),
1222
+ )}
1200
1223
  </ul>
1224
+ {!this.state.showAllItemsToDelete && (
1225
+ <Button
1226
+ onClick={() =>
1227
+ this.setState({
1228
+ showAllItemsToDelete: true,
1229
+ })
1230
+ }
1231
+ >
1232
+ Show all items
1233
+ </Button>
1234
+ )}
1201
1235
  {this.state.linkIntegrityBreakages.length > 0 ? (
1202
1236
  <div>
1203
1237
  <h3>
@@ -1753,7 +1787,9 @@ class Contents extends Component {
1753
1787
  <Menu.Header
1754
1788
  content={this.props.intl.formatMessage(
1755
1789
  messages.selected,
1756
- { count: this.state.selected.length },
1790
+ {
1791
+ count: this.state.selected.length,
1792
+ },
1757
1793
  )}
1758
1794
  />
1759
1795
  <Input
@@ -169,6 +169,12 @@ export const ContentsItemComponent = ({
169
169
  <FormattedMessage id="Expired" defaultMessage="Expired" />
170
170
  </Button>
171
171
  )}
172
+ {item.EffectiveDate !== 'None' &&
173
+ new Date(item.EffectiveDate).getTime() > new Date().getTime() && (
174
+ <Button className="button-margin effective-future" size="mini">
175
+ <FormattedMessage id="Scheduled" defaultMessage="Scheduled" />
176
+ </Button>
177
+ )}
172
178
  </Link>
173
179
  </Table.Cell>
174
180
  {map(indexes, (index) => (
@@ -43,7 +43,7 @@ const messages = defineMessages({
43
43
  addAddons: {
44
44
  id: 'Add Addons',
45
45
  defaultMessage:
46
- 'To make new add-ons show up here, add them to your buildout configuration, run buildout, and restart the server process. For detailed instructions see',
46
+ 'To make new add-ons show up here, add them to your configuration, build, and restart the server process. For detailed instructions see',
47
47
  },
48
48
  addonsSettings: {
49
49
  id: 'Add-ons Settings',
@@ -380,11 +380,11 @@ class AddonsControlpanel extends Component {
380
380
  </Header>
381
381
  <FormattedMessage
382
382
  id="Add Addons"
383
- defaultMessage="To make new add-ons show up here, add them to your buildout configuration, run buildout, and restart the server process. For detailed instructions see"
383
+ defaultMessage="To make new add-ons show up here, add them to your configuration, build, and restart the server process. For detailed instructions see"
384
384
  />
385
385
  &nbsp;
386
386
  <a
387
- href="http://docs.plone.org/manage/installing/installing_addons.html"
387
+ href="https://6.docs.plone.org/install/"
388
388
  target="_blank"
389
389
  rel="noopener noreferrer"
390
390
  >