@plone/volto 15.0.0-alpha.4 → 15.0.0-alpha.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/ISSUE_TEMPLATE/bug_report.md +7 -6
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -1
- package/.github/workflows/docs.yml +15 -55
- package/CHANGELOG.md +57 -2
- package/CODE_OF_CONDUCT.md +0 -1
- package/COMMITLINT.md +19 -21
- package/README.md +1 -1
- package/SECURITY.md +0 -1
- package/addon-registry.js +6 -3
- package/dist/assets.json +1 -0
- package/dist/chunks.json +572 -0
- package/dist/loadable-stats.json +2099 -0
- package/dist/public/android-chrome-192x192.png +0 -0
- package/dist/public/android-chrome-512x512.png +0 -0
- package/dist/public/apple-touch-icon.png +0 -0
- package/dist/public/favicon-16x16.png +0 -0
- package/dist/public/favicon-32x32.png +0 -0
- package/dist/public/favicon.ico +0 -0
- package/dist/public/icon.svg +13 -0
- package/dist/public/index.html.spa +34 -0
- package/dist/public/robots.txt +2 -0
- package/dist/public/site.webmanifest +19 -0
- package/dist/public/static/css/15.2cdd5437.chunk.css +409 -0
- package/dist/public/static/css/15.2cdd5437.chunk.css.map +1 -0
- package/dist/public/static/css/8.37cef611.chunk.css +2 -0
- package/dist/public/static/css/8.37cef611.chunk.css.map +1 -0
- package/dist/public/static/css/client.4cb92c57.chunk.css +8 -0
- package/dist/public/static/css/client.4cb92c57.chunk.css.map +1 -0
- package/dist/public/static/css/plone-volto-components-manage-Widgets-DatetimeWidget.c847a331.chunk.css +2 -0
- package/dist/public/static/css/plone-volto-components-manage-Widgets-DatetimeWidget.c847a331.chunk.css.map +1 -0
- package/dist/public/static/js/0.3e794c57.chunk.js +2 -0
- package/dist/public/static/js/0.3e794c57.chunk.js.map +1 -0
- package/dist/public/static/js/1.fece2b93.chunk.js +3 -0
- package/dist/public/static/js/1.fece2b93.chunk.js.LICENSE.txt +8 -0
- package/dist/public/static/js/1.fece2b93.chunk.js.map +1 -0
- package/dist/public/static/js/15.2cdd5437.chunk.js +3 -0
- package/dist/public/static/js/15.2cdd5437.chunk.js.LICENSE.txt +120 -0
- package/dist/public/static/js/15.2cdd5437.chunk.js.map +1 -0
- package/dist/public/static/js/16.a3a0662d.chunk.js +3 -0
- package/dist/public/static/js/16.a3a0662d.chunk.js.LICENSE.txt +8 -0
- package/dist/public/static/js/16.a3a0662d.chunk.js.map +1 -0
- package/dist/public/static/js/17.9478c50d.chunk.js +2 -0
- package/dist/public/static/js/17.9478c50d.chunk.js.map +1 -0
- package/dist/public/static/js/18.388e65d0.chunk.js +2 -0
- package/dist/public/static/js/18.388e65d0.chunk.js.map +1 -0
- package/dist/public/static/js/19.7c6b4a80.chunk.js +2 -0
- package/dist/public/static/js/19.7c6b4a80.chunk.js.map +1 -0
- package/dist/public/static/js/2.e6b0d690.chunk.js +2 -0
- package/dist/public/static/js/2.e6b0d690.chunk.js.map +1 -0
- package/dist/public/static/js/20.ada67f0e.chunk.js +3 -0
- package/dist/public/static/js/20.ada67f0e.chunk.js.LICENSE.txt +8 -0
- package/dist/public/static/js/20.ada67f0e.chunk.js.map +1 -0
- package/dist/public/static/js/21.3de49ac8.chunk.js +2 -0
- package/dist/public/static/js/21.3de49ac8.chunk.js.map +1 -0
- package/dist/public/static/js/22.ecefb8f2.chunk.js +2 -0
- package/dist/public/static/js/22.ecefb8f2.chunk.js.map +1 -0
- package/dist/public/static/js/23.3027bc00.chunk.js +2 -0
- package/dist/public/static/js/23.3027bc00.chunk.js.map +1 -0
- package/dist/public/static/js/24.aaaf4abf.chunk.js +2 -0
- package/dist/public/static/js/24.aaaf4abf.chunk.js.map +1 -0
- package/dist/public/static/js/25.c4d7d5e0.chunk.js +2 -0
- package/dist/public/static/js/25.c4d7d5e0.chunk.js.map +1 -0
- package/dist/public/static/js/26.d59ac3c1.chunk.js +2 -0
- package/dist/public/static/js/26.d59ac3c1.chunk.js.map +1 -0
- package/dist/public/static/js/27.266d95dd.chunk.js +2 -0
- package/dist/public/static/js/27.266d95dd.chunk.js.map +1 -0
- package/dist/public/static/js/28.d965d304.chunk.js +2 -0
- package/dist/public/static/js/28.d965d304.chunk.js.map +1 -0
- package/dist/public/static/js/29.7d8d1992.chunk.js +2 -0
- package/dist/public/static/js/29.7d8d1992.chunk.js.map +1 -0
- package/dist/public/static/js/3.025ba843.chunk.js +2 -0
- package/dist/public/static/js/3.025ba843.chunk.js.map +1 -0
- package/dist/public/static/js/30.a3d54e31.chunk.js +2 -0
- package/dist/public/static/js/30.a3d54e31.chunk.js.map +1 -0
- package/dist/public/static/js/31.9edf64ee.chunk.js +2 -0
- package/dist/public/static/js/31.9edf64ee.chunk.js.map +1 -0
- package/dist/public/static/js/32.649dbfc2.chunk.js +2 -0
- package/dist/public/static/js/32.649dbfc2.chunk.js.map +1 -0
- package/dist/public/static/js/33.45949ca4.chunk.js +2 -0
- package/dist/public/static/js/33.45949ca4.chunk.js.map +1 -0
- package/dist/public/static/js/34.084257cf.chunk.js +2 -0
- package/dist/public/static/js/34.084257cf.chunk.js.map +1 -0
- package/dist/public/static/js/35.00679602.chunk.js +3 -0
- package/dist/public/static/js/35.00679602.chunk.js.LICENSE.txt +37 -0
- package/dist/public/static/js/35.00679602.chunk.js.map +1 -0
- package/dist/public/static/js/36.4a29fdbd.chunk.js +3 -0
- package/dist/public/static/js/36.4a29fdbd.chunk.js.LICENSE.txt +7 -0
- package/dist/public/static/js/36.4a29fdbd.chunk.js.map +1 -0
- package/dist/public/static/js/37.fbbe07b3.chunk.js +3 -0
- package/dist/public/static/js/37.fbbe07b3.chunk.js.LICENSE.txt +14 -0
- package/dist/public/static/js/37.fbbe07b3.chunk.js.map +1 -0
- package/dist/public/static/js/38.b31c59ad.chunk.js +3 -0
- package/dist/public/static/js/38.b31c59ad.chunk.js.LICENSE.txt +8 -0
- package/dist/public/static/js/38.b31c59ad.chunk.js.map +1 -0
- package/dist/public/static/js/39.69d6a789.chunk.js +2 -0
- package/dist/public/static/js/39.69d6a789.chunk.js.map +1 -0
- package/dist/public/static/js/4.bdc4a5c5.chunk.js +2 -0
- package/dist/public/static/js/4.bdc4a5c5.chunk.js.map +1 -0
- package/dist/public/static/js/40.90de6e4a.chunk.js +2 -0
- package/dist/public/static/js/40.90de6e4a.chunk.js.map +1 -0
- package/dist/public/static/js/7.7acc66bc.chunk.js +2 -0
- package/dist/public/static/js/7.7acc66bc.chunk.js.map +1 -0
- package/dist/public/static/js/8.37cef611.chunk.js +3 -0
- package/dist/public/static/js/8.37cef611.chunk.js.LICENSE.txt +25 -0
- package/dist/public/static/js/8.37cef611.chunk.js.map +1 -0
- package/dist/public/static/js/client.4cb92c57.chunk.js +2 -0
- package/dist/public/static/js/client.4cb92c57.chunk.js.map +1 -0
- package/dist/public/static/js/draft-js-lib-isSoftNewlineEvent.6cd05e34.chunk.js +2 -0
- package/dist/public/static/js/draft-js-lib-isSoftNewlineEvent.6cd05e34.chunk.js.map +1 -0
- package/dist/public/static/js/moment.2caa76d1.chunk.js +2 -0
- package/dist/public/static/js/moment.2caa76d1.chunk.js.map +1 -0
- package/dist/public/static/js/plone-volto-components-manage-Widgets-DatetimeWidget.c847a331.chunk.js +2 -0
- package/dist/public/static/js/plone-volto-components-manage-Widgets-DatetimeWidget.c847a331.chunk.js.map +1 -0
- package/dist/public/static/js/plone-volto-components-theme-View-EventView.433dd14b.chunk.js +2 -0
- package/dist/public/static/js/plone-volto-components-theme-View-EventView.433dd14b.chunk.js.map +1 -0
- package/dist/public/static/js/react-dates.f71abb7c.chunk.js +2 -0
- package/dist/public/static/js/react-dates.f71abb7c.chunk.js.map +1 -0
- package/dist/public/static/js/react-simple-code-editor.33478dc3.chunk.js +2 -0
- package/dist/public/static/js/react-simple-code-editor.33478dc3.chunk.js.map +1 -0
- package/dist/public/static/js/runtime~client.d372df0e.js +2 -0
- package/dist/public/static/js/runtime~client.d372df0e.js.map +1 -0
- package/dist/public/static/media/Logo.16e25cdf.svg +21 -0
- package/dist/public/static/media/block-image.8a4a14d5.svg +8 -0
- package/dist/public/static/media/block-maps.731e84f6.svg +7 -0
- package/dist/public/static/media/block-video.832fa3ff.svg +7 -0
- package/dist/public/static/media/default-image.9451b251.svg +13 -0
- package/dist/public/static/media/flags.9c74e172.png +0 -0
- package/dist/public/static/media/icons.022583c4.svg +320 -0
- package/dist/public/static/media/icons.06400145.ttf +0 -0
- package/dist/public/static/media/icons.dbc1ef8b.eot +0 -0
- package/dist/public/static/media/icons.df45b7de.woff +0 -0
- package/dist/server.js +2 -0
- package/locales/ca/LC_MESSAGES/volto.po +14 -0
- package/locales/ca.json +1 -1
- package/locales/de/LC_MESSAGES/volto.po +14 -0
- package/locales/de.json +1 -1
- package/locales/en/LC_MESSAGES/volto.po +14 -0
- package/locales/en.json +1 -1
- package/locales/es/LC_MESSAGES/volto.po +14 -0
- package/locales/es.json +1 -1
- package/locales/eu/LC_MESSAGES/volto.po +14 -0
- package/locales/eu.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +14 -0
- package/locales/fr.json +1 -1
- package/locales/it/LC_MESSAGES/volto.po +14 -0
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +14 -0
- package/locales/ja.json +1 -1
- package/locales/nl/LC_MESSAGES/volto.po +14 -0
- package/locales/nl.json +1 -1
- package/locales/pt/LC_MESSAGES/volto.po +14 -0
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +14 -0
- package/locales/pt_BR.json +1 -1
- package/locales/ro/LC_MESSAGES/volto.po +14 -0
- package/locales/ro.json +1 -1
- package/locales/volto.pot +15 -1
- package/logos/Logo.png +0 -0
- package/logos/volto-colorful.png +0 -0
- package/logos/volto-colorful.svg +35 -0
- package/logos/volto-guide.png +0 -0
- package/logos/volto-h-transparent.svg +6 -0
- package/logos/volto-transparent.png +0 -0
- package/logos/volto-transparent.svg +19 -0
- package/logos/volto-transparent2.svg +5 -0
- package/logos/volto-yellow.svg +29 -0
- package/logos/volto.sketch +0 -0
- package/netlify.toml +2 -0
- package/package.json +6 -2
- package/razzle.config.js +2 -2
- package/src/actions/language/language.js +7 -2
- package/src/components/manage/AnchorPlugin/components/LinkButton/AddLinkForm.jsx +1 -2
- package/src/components/manage/AnchorPlugin/components/LinkButton/index.jsx +15 -6
- package/src/components/manage/AnchorPlugin/index.jsx +12 -5
- package/src/components/manage/AnchorPlugin/utils/EditorUtils.js +8 -7
- package/src/components/manage/Blocks/Description/Edit.jsx +33 -19
- package/src/components/manage/Blocks/Description/Edit.test.jsx +6 -0
- package/src/components/manage/Blocks/HeroImageLeft/Edit.jsx +37 -26
- package/src/components/manage/Blocks/HeroImageLeft/Edit.test.jsx +6 -0
- package/src/components/manage/Blocks/Search/README.md +20 -0
- package/src/components/manage/Blocks/Search/components/CheckboxFacet.jsx +16 -3
- package/src/components/manage/Blocks/Search/components/DateRangeFacet.jsx +120 -0
- package/src/components/manage/Blocks/Search/components/DateRangeFacet.test.jsx +34 -0
- package/src/components/manage/Blocks/Search/components/DateRangeFacetFilterListEntry.jsx +39 -0
- package/src/components/manage/Blocks/Search/components/Facets.jsx +24 -25
- package/src/components/manage/Blocks/Search/components/FilterList.jsx +37 -67
- package/src/components/manage/Blocks/Search/components/FilterList.test.jsx +49 -1
- package/src/components/manage/Blocks/Search/components/SelectFacet.jsx +9 -0
- package/src/components/manage/Blocks/Search/components/SelectFacetFilterListEntry.jsx +42 -0
- package/src/components/manage/Blocks/Search/components/SelectStyling.jsx +1 -1
- package/src/components/manage/Blocks/Search/components/ToggleFacet.jsx +38 -0
- package/src/components/manage/Blocks/Search/components/ToggleFacetFilterListEntry.jsx +39 -0
- package/src/components/manage/Blocks/Search/components/base.js +52 -0
- package/src/components/manage/Blocks/Search/components/index.js +5 -0
- package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +68 -27
- package/src/components/manage/Blocks/Search/schema.js +7 -4
- package/src/components/manage/Blocks/Search/utils.js +16 -0
- package/src/components/manage/Blocks/Table/Cell.jsx +40 -14
- package/src/components/manage/Blocks/Table/Cell.test.jsx +7 -1
- package/src/components/manage/Blocks/Table/Edit.jsx +7 -3
- package/src/components/manage/Blocks/Table/Edit.test.jsx +6 -0
- package/src/components/manage/Blocks/Table/View.jsx +2 -2
- package/src/components/manage/Blocks/Text/Edit.jsx +56 -14
- package/src/components/manage/Blocks/Text/Edit.test.jsx +7 -1
- package/src/components/manage/Blocks/Text/View.jsx +2 -2
- package/src/components/manage/Blocks/Title/Edit.jsx +25 -13
- package/src/components/manage/Blocks/Title/Edit.test.jsx +6 -0
- package/src/components/manage/Sidebar/Sidebar.jsx +5 -1
- package/src/components/manage/Toolbar/Toolbar.jsx +3 -1
- package/src/components/manage/UniversalLink/UniversalLink.jsx +5 -2
- package/src/components/manage/Widgets/DatetimeWidget.jsx +3 -1
- package/src/components/manage/Widgets/UrlWidget.jsx +1 -1
- package/src/components/manage/Widgets/WysiwygWidget.jsx +45 -19
- package/src/components/manage/Widgets/WysiwygWidget.test.jsx +7 -1
- package/src/components/theme/View/LinkView.jsx +1 -1
- package/src/components/theme/View/View.jsx +5 -1
- package/src/config/Blocks.jsx +31 -0
- package/src/config/Loadables.jsx +22 -0
- package/src/config/RichTextEditor/Blocks.jsx +25 -20
- package/src/config/RichTextEditor/Plugins.jsx +38 -31
- package/src/config/RichTextEditor/Styles.jsx +48 -44
- package/src/config/RichTextEditor/index.js +25 -0
- package/src/config/index.js +14 -18
- package/src/helpers/Api/Api.js +18 -4
- package/src/helpers/Extensions/index.js +1 -1
- package/src/helpers/Extensions/withBlockExtensions.js +4 -0
- package/src/helpers/Extensions/withBlockExtensions.test.js +26 -1
- package/src/helpers/Url/Url.js +32 -1
- package/src/helpers/Url/urlRegex.js +7 -1
- package/src/helpers/index.js +2 -0
- package/src/middleware/api.js +21 -2
- package/src/server.jsx +9 -2
- package/test-setup-config.js +22 -7
- package/theme/themes/pastanaga/extras/blocks.less +29 -0
- package/src/components/manage/AnchorPlugin/utils/URLUtils.js +0 -36
- package/src/components/manage/AnchorPlugin/utils/mailRegex.js +0 -2
- package/src/components/manage/AnchorPlugin/utils/telRegex.js +0 -1
- package/src/components/manage/AnchorPlugin/utils/urlRegex.js +0 -54
|
@@ -7,15 +7,13 @@ import React, { Component } from 'react';
|
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import { connect } from 'react-redux';
|
|
9
9
|
import { compose } from 'redux';
|
|
10
|
-
import { Map } from 'immutable';
|
|
11
10
|
import { readAsDataURL } from 'promise-file-reader';
|
|
12
11
|
import { Button, Dimmer, Loader, Message } from 'semantic-ui-react';
|
|
13
|
-
import { stateFromHTML } from 'draft-js-import-html';
|
|
14
|
-
import { Editor, DefaultDraftBlockRenderMap, EditorState } from 'draft-js';
|
|
15
12
|
import { isEqual } from 'lodash';
|
|
16
13
|
import { defineMessages, injectIntl } from 'react-intl';
|
|
17
14
|
import cx from 'classnames';
|
|
18
15
|
|
|
16
|
+
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
19
17
|
import { flattenToAppURL, getBaseUrl } from '@plone/volto/helpers';
|
|
20
18
|
import { createContent } from '@plone/volto/actions';
|
|
21
19
|
import { Icon, SidebarPortal, LinkMore } from '@plone/volto/components';
|
|
@@ -51,32 +49,12 @@ const messages = defineMessages({
|
|
|
51
49
|
},
|
|
52
50
|
});
|
|
53
51
|
|
|
54
|
-
const blockTitleRenderMap = Map({
|
|
55
|
-
unstyled: {
|
|
56
|
-
element: 'h1',
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
const blockDescriptionRenderMap = Map({
|
|
61
|
-
unstyled: {
|
|
62
|
-
element: 'div',
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const extendedBlockRenderMap = DefaultDraftBlockRenderMap.merge(
|
|
67
|
-
blockTitleRenderMap,
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
const extendedDescripBlockRenderMap = DefaultDraftBlockRenderMap.merge(
|
|
71
|
-
blockDescriptionRenderMap,
|
|
72
|
-
);
|
|
73
|
-
|
|
74
52
|
/**
|
|
75
53
|
* Edit image block class.
|
|
76
54
|
* @class Edit
|
|
77
55
|
* @extends Component
|
|
78
56
|
*/
|
|
79
|
-
class
|
|
57
|
+
class EditComponent extends Component {
|
|
80
58
|
/**
|
|
81
59
|
* Property types.
|
|
82
60
|
* @property {Object} propTypes Property types.
|
|
@@ -126,7 +104,32 @@ class Edit extends Component {
|
|
|
126
104
|
uploading: false,
|
|
127
105
|
};
|
|
128
106
|
|
|
107
|
+
const { Map } = this.props.immutableLib;
|
|
108
|
+
|
|
129
109
|
if (!__SERVER__) {
|
|
110
|
+
const { DefaultDraftBlockRenderMap, EditorState } = props.draftJs;
|
|
111
|
+
const { stateFromHTML } = props.draftJsImportHtml;
|
|
112
|
+
|
|
113
|
+
const blockTitleRenderMap = Map({
|
|
114
|
+
unstyled: {
|
|
115
|
+
element: 'h1',
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const blockDescriptionRenderMap = Map({
|
|
120
|
+
unstyled: {
|
|
121
|
+
element: 'div',
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
this.extendedBlockRenderMap = DefaultDraftBlockRenderMap.merge(
|
|
126
|
+
blockTitleRenderMap,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
this.extendedDescripBlockRenderMap = DefaultDraftBlockRenderMap.merge(
|
|
130
|
+
blockDescriptionRenderMap,
|
|
131
|
+
);
|
|
132
|
+
|
|
130
133
|
let titleEditorState;
|
|
131
134
|
let descriptionEditorState;
|
|
132
135
|
if (props.data && props.data.title) {
|
|
@@ -187,6 +190,9 @@ class Edit extends Component {
|
|
|
187
190
|
});
|
|
188
191
|
}
|
|
189
192
|
|
|
193
|
+
const { EditorState } = this.props.draftJs;
|
|
194
|
+
const { stateFromHTML } = this.props.draftJsImportHtml;
|
|
195
|
+
|
|
190
196
|
if (
|
|
191
197
|
nextProps.data.title &&
|
|
192
198
|
this.props.data.title !== nextProps.data.title &&
|
|
@@ -299,6 +305,7 @@ class Edit extends Component {
|
|
|
299
305
|
if (__SERVER__) {
|
|
300
306
|
return <div />;
|
|
301
307
|
}
|
|
308
|
+
const { Editor } = this.props.draftJs;
|
|
302
309
|
const placeholder =
|
|
303
310
|
this.props.data.placeholder ||
|
|
304
311
|
this.props.intl.formatMessage(messages.placeholder);
|
|
@@ -374,7 +381,7 @@ class Edit extends Component {
|
|
|
374
381
|
readOnly={!this.props.editable}
|
|
375
382
|
onChange={this.onChangeTitle}
|
|
376
383
|
editorState={this.state.titleEditorState}
|
|
377
|
-
blockRenderMap={extendedBlockRenderMap}
|
|
384
|
+
blockRenderMap={this.extendedBlockRenderMap}
|
|
378
385
|
handleReturn={() => true}
|
|
379
386
|
placeholder={this.props.intl.formatMessage(messages.title)}
|
|
380
387
|
blockStyleFn={() => 'title-editor'}
|
|
@@ -416,7 +423,7 @@ class Edit extends Component {
|
|
|
416
423
|
readOnly={!this.props.editable}
|
|
417
424
|
onChange={this.onChangeDescription}
|
|
418
425
|
editorState={this.state.descriptionEditorState}
|
|
419
|
-
blockRenderMap={extendedDescripBlockRenderMap}
|
|
426
|
+
blockRenderMap={this.extendedDescripBlockRenderMap}
|
|
420
427
|
handleReturn={() => true}
|
|
421
428
|
placeholder={this.props.intl.formatMessage(
|
|
422
429
|
messages.description,
|
|
@@ -460,6 +467,10 @@ class Edit extends Component {
|
|
|
460
467
|
}
|
|
461
468
|
}
|
|
462
469
|
|
|
470
|
+
const Edit = injectLazyLibs(['draftJs', 'immutableLib', 'draftJsImportHtml'])(
|
|
471
|
+
EditComponent,
|
|
472
|
+
);
|
|
473
|
+
|
|
463
474
|
export default compose(
|
|
464
475
|
injectIntl,
|
|
465
476
|
connect(
|
|
@@ -5,6 +5,12 @@ import { Provider } from 'react-intl-redux';
|
|
|
5
5
|
|
|
6
6
|
import Edit from './Edit';
|
|
7
7
|
|
|
8
|
+
jest.mock('@plone/volto/helpers/Loadable/Loadable');
|
|
9
|
+
beforeAll(
|
|
10
|
+
async () =>
|
|
11
|
+
await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
|
|
12
|
+
);
|
|
13
|
+
|
|
8
14
|
global.__SERVER__ = true; // eslint-disable-line no-underscore-dangle
|
|
9
15
|
|
|
10
16
|
const mockStore = configureStore();
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## Terminology
|
|
2
|
+
|
|
3
|
+
Facet: a filter control that allows the final users of search block to tweak
|
|
4
|
+
the query that's sent to the `@querystringsearch` endpoint. Usually, a facet is
|
|
5
|
+
a list of all possible values for a field, so that it can be set to either
|
|
6
|
+
a single value or a list of those selected values.
|
|
7
|
+
|
|
8
|
+
Facets: a control that renders the list of facet filters.
|
|
9
|
+
|
|
10
|
+
FilterList: a control rendered at the top of the block, it shows a list of all
|
|
11
|
+
applied facet values, with quick access to the users to clear either the facet
|
|
12
|
+
or the entire searchblock state.
|
|
13
|
+
|
|
14
|
+
`<FacetType>FilterListEntry`: components used to render the selected value for
|
|
15
|
+
a particular facet, in the FilterList component. They can be registered per
|
|
16
|
+
facet type.
|
|
17
|
+
|
|
18
|
+
Layout: a high-level component that controls the way the results are layed out
|
|
19
|
+
in relation to the facet list (facets can be displayed at top, left or right of
|
|
20
|
+
results).
|
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Checkbox, Header } from 'semantic-ui-react';
|
|
3
|
+
import {
|
|
4
|
+
selectFacetSchemaEnhancer,
|
|
5
|
+
selectFacetStateToValue,
|
|
6
|
+
selectFacetValueToQuery,
|
|
7
|
+
} from './base';
|
|
3
8
|
|
|
4
|
-
|
|
9
|
+
/**
|
|
10
|
+
* A facet that uses radio/checkboxes to provide an explicit list of values for
|
|
11
|
+
* filtering
|
|
12
|
+
*/
|
|
13
|
+
const CheckboxFacet = (props) => {
|
|
5
14
|
const { facet, choices, isMulti, onChange, value, isEditMode } = props;
|
|
6
15
|
const facetValue = value;
|
|
7
16
|
|
|
8
17
|
return (
|
|
9
18
|
<div className="checkbox-facet">
|
|
10
|
-
<Header as="h4">{facet.title}</Header>
|
|
19
|
+
<Header as="h4">{facet.title ?? facet?.field?.label}</Header>
|
|
11
20
|
<div className="entries">
|
|
12
21
|
{choices.map(({ label, value }, i) => (
|
|
13
22
|
<div className="entry" key={value}>
|
|
@@ -43,4 +52,8 @@ const SelectFacet = (props) => {
|
|
|
43
52
|
);
|
|
44
53
|
};
|
|
45
54
|
|
|
46
|
-
|
|
55
|
+
CheckboxFacet.schemaEnhancer = selectFacetSchemaEnhancer;
|
|
56
|
+
CheckboxFacet.stateToValue = selectFacetStateToValue;
|
|
57
|
+
CheckboxFacet.valueToQuery = selectFacetValueToQuery;
|
|
58
|
+
|
|
59
|
+
export default CheckboxFacet;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Header } from 'semantic-ui-react';
|
|
3
|
+
import { defineMessages, injectIntl } from 'react-intl';
|
|
4
|
+
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
5
|
+
import { compose } from 'redux';
|
|
6
|
+
import { Icon } from '@plone/volto/components';
|
|
7
|
+
|
|
8
|
+
import leftKey from '@plone/volto/icons/left-key.svg';
|
|
9
|
+
import rightKey from '@plone/volto/icons/right-key.svg';
|
|
10
|
+
import clearSVG from '@plone/volto/icons/clear.svg';
|
|
11
|
+
|
|
12
|
+
import 'react-dates/initialize';
|
|
13
|
+
import 'react-dates/lib/css/_datepicker.css';
|
|
14
|
+
|
|
15
|
+
const messages = defineMessages({
|
|
16
|
+
startDate: {
|
|
17
|
+
id: 'Start Date',
|
|
18
|
+
defaultMessage: 'Start Date',
|
|
19
|
+
},
|
|
20
|
+
endDate: {
|
|
21
|
+
id: 'End Date',
|
|
22
|
+
defaultMessage: 'End Date',
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const PrevIcon = () => (
|
|
27
|
+
<div
|
|
28
|
+
className="prev-icon"
|
|
29
|
+
style={{
|
|
30
|
+
color: '#000',
|
|
31
|
+
left: '22px',
|
|
32
|
+
padding: '5px',
|
|
33
|
+
position: 'absolute',
|
|
34
|
+
top: '15px',
|
|
35
|
+
}}
|
|
36
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
37
|
+
tabIndex="0"
|
|
38
|
+
>
|
|
39
|
+
<Icon name={leftKey} size="30px" />
|
|
40
|
+
</div>
|
|
41
|
+
);
|
|
42
|
+
const NextIcon = () => (
|
|
43
|
+
<div
|
|
44
|
+
className="next-icon"
|
|
45
|
+
style={{
|
|
46
|
+
color: '#000',
|
|
47
|
+
right: '22px',
|
|
48
|
+
padding: '5px',
|
|
49
|
+
position: 'absolute',
|
|
50
|
+
top: '15px',
|
|
51
|
+
}}
|
|
52
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
53
|
+
tabIndex="0"
|
|
54
|
+
>
|
|
55
|
+
<Icon name={rightKey} size="30px" />
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const CloseIcon = () => <Icon name={clearSVG} size="24px" className="close" />;
|
|
60
|
+
|
|
61
|
+
const DateRangeFacet = (props) => {
|
|
62
|
+
const { facet, isEditMode, onChange, value, reactDates, intl } = props;
|
|
63
|
+
const moment = props.moment.default;
|
|
64
|
+
const { DateRangePicker } = reactDates;
|
|
65
|
+
const [focused, setFocused] = useState(null);
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<div className="daterange-facet">
|
|
69
|
+
<Header as="h4">{facet?.title ?? facet?.field?.label}</Header>
|
|
70
|
+
<div className="ui form date-time-widget-wrapper">
|
|
71
|
+
<div className="ui input date-input">
|
|
72
|
+
<DateRangePicker
|
|
73
|
+
startDate={value && value[0] ? moment(value[0]) : null}
|
|
74
|
+
startDateId={`${facet['@id']}-start-date`}
|
|
75
|
+
startDatePlaceholderText={intl.formatMessage(messages.startDate)}
|
|
76
|
+
endDate={value && value[1] ? moment(value[1]) : null}
|
|
77
|
+
endDateId={`${facet['@id']}-end-date`}
|
|
78
|
+
endDatePlaceholderText={intl.formatMessage(messages.endDate)}
|
|
79
|
+
numberOfMonths={1}
|
|
80
|
+
disabled={isEditMode}
|
|
81
|
+
noBorder
|
|
82
|
+
showClearDates
|
|
83
|
+
customCloseIcon={<CloseIcon />}
|
|
84
|
+
displayFormat={moment.localeData(intl.locale).longDateFormat('L')}
|
|
85
|
+
focusedInput={focused}
|
|
86
|
+
onFocusChange={(focusedInput) => setFocused(focusedInput)}
|
|
87
|
+
onDatesChange={({ startDate, endDate }) => {
|
|
88
|
+
onChange(facet.field.value, [
|
|
89
|
+
startDate ? startDate.format('YYYY-MM-DD') : null,
|
|
90
|
+
endDate ? endDate.format('YYYY-MM-DD') : null,
|
|
91
|
+
]);
|
|
92
|
+
}}
|
|
93
|
+
isOutsideRange={() => false}
|
|
94
|
+
navPrev={<PrevIcon />}
|
|
95
|
+
navNext={<NextIcon />}
|
|
96
|
+
/>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
DateRangeFacet.stateToValue = ({ facetSettings, index, selectedValue }) => {
|
|
104
|
+
return selectedValue || [null, null];
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
DateRangeFacet.valueToQuery = ({ value, facet }) => {
|
|
108
|
+
return value && typeof value[0] === 'string' && typeof value[1] === 'string'
|
|
109
|
+
? {
|
|
110
|
+
i: facet.field.value,
|
|
111
|
+
o: 'plone.app.querystring.operation.date.between',
|
|
112
|
+
v: value,
|
|
113
|
+
}
|
|
114
|
+
: null;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export default compose(
|
|
118
|
+
injectLazyLibs(['reactDates', 'moment']),
|
|
119
|
+
injectIntl,
|
|
120
|
+
)(DateRangeFacet);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import configureStore from 'redux-mock-store';
|
|
3
|
+
import { Provider } from 'react-intl-redux';
|
|
4
|
+
import { waitFor, render, screen } from '@testing-library/react';
|
|
5
|
+
|
|
6
|
+
import DateRangeFacet from './DateRangeFacet';
|
|
7
|
+
|
|
8
|
+
const mockStore = configureStore();
|
|
9
|
+
|
|
10
|
+
jest.mock('@plone/volto/helpers/Loadable/Loadable');
|
|
11
|
+
beforeAll(
|
|
12
|
+
async () =>
|
|
13
|
+
await require('@plone/volto/helpers/Loadable/Loadable').__setLoadables(),
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
describe('DateRangeFaceg', () => {
|
|
17
|
+
it('renders a facet component with a date range widget', async () => {
|
|
18
|
+
const store = mockStore({
|
|
19
|
+
userSession: { token: null },
|
|
20
|
+
content: { data: { '@id': 'myid' } },
|
|
21
|
+
intl: {
|
|
22
|
+
locale: 'en',
|
|
23
|
+
messages: {},
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
const { container } = render(
|
|
27
|
+
<Provider store={store}>
|
|
28
|
+
<DateRangeFacet facet={{ title: 'Test Facet', field: {} }} />
|
|
29
|
+
</Provider>,
|
|
30
|
+
);
|
|
31
|
+
await waitFor(() => screen.getByText('Test Facet'));
|
|
32
|
+
expect(container).toMatchSnapshot();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Label, Icon } from 'semantic-ui-react';
|
|
3
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
4
|
+
|
|
5
|
+
const messages = defineMessages({
|
|
6
|
+
yes: {
|
|
7
|
+
id: 'yes',
|
|
8
|
+
defaultMessage: 'Yes',
|
|
9
|
+
},
|
|
10
|
+
no: {
|
|
11
|
+
id: 'no',
|
|
12
|
+
defaultMessage: 'No',
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
function DateRangeFacetFilterListEntry(props) {
|
|
17
|
+
const { facet, isEditMode, setFacets, facets } = props;
|
|
18
|
+
const intl = useIntl();
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Label size="small">
|
|
22
|
+
{intl.formatMessage(facets[facet] ? messages.yes : messages.no)}
|
|
23
|
+
<Icon
|
|
24
|
+
name="delete"
|
|
25
|
+
onClick={() => {
|
|
26
|
+
const filteredFacets = Object.assign(
|
|
27
|
+
{},
|
|
28
|
+
...Object.keys(facets)
|
|
29
|
+
.filter((f) => f !== facet)
|
|
30
|
+
.map((f) => ({ [f]: facets[f] })),
|
|
31
|
+
);
|
|
32
|
+
!isEditMode && setFacets(filteredFacets);
|
|
33
|
+
}}
|
|
34
|
+
/>
|
|
35
|
+
</Label>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default DateRangeFacetFilterListEntry;
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { resolveExtension } from '@plone/volto/helpers/Extensions/withBlockExtensions';
|
|
3
3
|
import config from '@plone/volto/registry';
|
|
4
|
+
import { hasNonValueOperation, hasDateOperation } from '../utils';
|
|
5
|
+
|
|
6
|
+
const showFacet = (index) => {
|
|
7
|
+
const { values } = index;
|
|
8
|
+
return index
|
|
9
|
+
? hasNonValueOperation(index.operations || []) ||
|
|
10
|
+
hasDateOperation(index.operations || [])
|
|
11
|
+
? true
|
|
12
|
+
: values && Object.keys(values).length > 0
|
|
13
|
+
: values && Object.keys(values).length > 0;
|
|
14
|
+
};
|
|
4
15
|
|
|
5
16
|
const Facets = (props) => {
|
|
6
17
|
const {
|
|
@@ -22,9 +33,9 @@ const Facets = (props) => {
|
|
|
22
33
|
return (
|
|
23
34
|
<>
|
|
24
35
|
{data?.facets
|
|
25
|
-
?.filter((
|
|
26
|
-
.map((
|
|
27
|
-
const field =
|
|
36
|
+
?.filter((facetSettings) => !facetSettings.hidden)
|
|
37
|
+
.map((facetSettings) => {
|
|
38
|
+
const field = facetSettings?.field?.value;
|
|
28
39
|
const index = querystring.indexes[field] || {};
|
|
29
40
|
const { values = {} } = index;
|
|
30
41
|
|
|
@@ -41,40 +52,28 @@ const Facets = (props) => {
|
|
|
41
52
|
: true,
|
|
42
53
|
);
|
|
43
54
|
|
|
44
|
-
const isMulti =
|
|
45
|
-
const selectedValue = facets[
|
|
55
|
+
const isMulti = facetSettings.multiple;
|
|
56
|
+
const selectedValue = facets[facetSettings?.field?.value];
|
|
46
57
|
|
|
47
58
|
// TODO :handle changing the type of facet (multi/nonmulti)
|
|
48
59
|
|
|
49
|
-
|
|
50
|
-
? isMulti
|
|
51
|
-
? Array.isArray(selectedValue)
|
|
52
|
-
? selectedValue.map((v) => ({
|
|
53
|
-
value: v,
|
|
54
|
-
label: index.values?.[v]?.title,
|
|
55
|
-
}))
|
|
56
|
-
: []
|
|
57
|
-
: {
|
|
58
|
-
value: selectedValue,
|
|
59
|
-
label: index.values?.[selectedValue]?.title,
|
|
60
|
-
}
|
|
61
|
-
: [];
|
|
62
|
-
|
|
63
|
-
const { view: FacetWidget } = resolveExtension(
|
|
60
|
+
const { view: FacetWidget, stateToValue } = resolveExtension(
|
|
64
61
|
'type',
|
|
65
62
|
search.extensions.facetWidgets.types,
|
|
66
|
-
|
|
63
|
+
facetSettings,
|
|
67
64
|
);
|
|
68
65
|
|
|
66
|
+
let value = stateToValue({ facetSettings, index, selectedValue });
|
|
67
|
+
|
|
69
68
|
const {
|
|
70
69
|
rewriteOptions = (name, options) => options,
|
|
71
70
|
} = search.extensions.facetWidgets;
|
|
72
71
|
|
|
73
|
-
return FacetWrapper &&
|
|
74
|
-
<FacetWrapper key={
|
|
72
|
+
return FacetWrapper && (isEditMode || showFacet(index)) ? (
|
|
73
|
+
<FacetWrapper key={facetSettings['@id']}>
|
|
75
74
|
<FacetWidget
|
|
76
|
-
facet={
|
|
77
|
-
choices={rewriteOptions(
|
|
75
|
+
facet={facetSettings}
|
|
76
|
+
choices={rewriteOptions(facetSettings?.field?.value, choices)}
|
|
78
77
|
isMulti={isMulti}
|
|
79
78
|
value={value}
|
|
80
79
|
isEditMode={isEditMode}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Accordion, Button,
|
|
2
|
+
import { Accordion, Button, Icon } from 'semantic-ui-react';
|
|
3
3
|
import { Icon as VoltoIcon } from '@plone/volto/components';
|
|
4
4
|
import downSVG from '@plone/volto/icons/down-key.svg';
|
|
5
5
|
import { defineMessages, useIntl } from 'react-intl';
|
|
6
|
+
import { resolveExtension } from '@plone/volto/helpers/Extensions/withBlockExtensions';
|
|
7
|
+
import config from '@plone/volto/registry';
|
|
6
8
|
|
|
7
9
|
const messages = defineMessages({
|
|
8
10
|
currentFilters: {
|
|
@@ -15,26 +17,27 @@ const messages = defineMessages({
|
|
|
15
17
|
},
|
|
16
18
|
});
|
|
17
19
|
|
|
20
|
+
/**
|
|
21
|
+
* A list of active filtered values and controls to clear those filters.
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
18
24
|
const FilterList = (props) => {
|
|
19
|
-
const { data, facets, setFacets, isEditMode } = props;
|
|
25
|
+
const { data = {}, facets = {}, setFacets, isEditMode } = props;
|
|
26
|
+
const definedFacets = data.facets || [];
|
|
20
27
|
const [isOpened, setIsOpened] = React.useState(false);
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
const totalFilters = definedFacets.filter(
|
|
30
|
+
({ field }) =>
|
|
31
|
+
field && Object.keys(facets).includes(field.value) && facets[field.value],
|
|
32
|
+
).length;
|
|
25
33
|
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const totalFilters = [].concat.apply([], Object.values(currentFilters))
|
|
31
|
-
.length;
|
|
32
|
-
|
|
33
|
-
// console.log({ data, facets, showFilterList, currentFilters, totalFilters });
|
|
34
|
+
const {
|
|
35
|
+
types: facetWidgetTypes,
|
|
36
|
+
} = config.blocks.blocksConfig.search.extensions.facetWidgets;
|
|
34
37
|
|
|
35
38
|
const intl = useIntl();
|
|
36
39
|
|
|
37
|
-
return
|
|
40
|
+
return totalFilters ? (
|
|
38
41
|
<Accordion className="filter-listing">
|
|
39
42
|
<Accordion.Title
|
|
40
43
|
className="filter-list-header"
|
|
@@ -61,59 +64,26 @@ const FilterList = (props) => {
|
|
|
61
64
|
</Accordion.Title>
|
|
62
65
|
<Accordion.Content className="filter-list-content" active={isOpened}>
|
|
63
66
|
<div className="filter-list">
|
|
64
|
-
{
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
setFacets({
|
|
85
|
-
...facets,
|
|
86
|
-
[facet]: '',
|
|
87
|
-
});
|
|
88
|
-
}}
|
|
89
|
-
/>
|
|
90
|
-
</Label>
|
|
91
|
-
) : (
|
|
92
|
-
<>
|
|
93
|
-
{facets[facet].map((entry, i) => (
|
|
94
|
-
<Label size="small" key={i}>
|
|
95
|
-
{entry}
|
|
96
|
-
<Icon
|
|
97
|
-
name="delete"
|
|
98
|
-
onClick={() => {
|
|
99
|
-
const entries = facets[facet].filter(
|
|
100
|
-
(item) => item !== entry,
|
|
101
|
-
);
|
|
102
|
-
!isEditMode &&
|
|
103
|
-
setFacets({
|
|
104
|
-
...facets,
|
|
105
|
-
[facet]: entries,
|
|
106
|
-
});
|
|
107
|
-
}}
|
|
108
|
-
/>
|
|
109
|
-
</Label>
|
|
110
|
-
))}
|
|
111
|
-
</>
|
|
112
|
-
)}
|
|
113
|
-
</div>
|
|
114
|
-
)}
|
|
115
|
-
</div>
|
|
116
|
-
))}
|
|
67
|
+
{data.facets?.map((facetSettings, i) => {
|
|
68
|
+
const {
|
|
69
|
+
filterListComponent: FilterListComponent,
|
|
70
|
+
} = resolveExtension('type', facetWidgetTypes, facetSettings);
|
|
71
|
+
const facet = facetSettings?.field?.value;
|
|
72
|
+
if (!facet) return null;
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<div key={i}>
|
|
76
|
+
{Object.keys(facets).includes(facet) && !!facets[facet] && (
|
|
77
|
+
<div className="filter-list-group" key={i}>
|
|
78
|
+
<span className="label-title">
|
|
79
|
+
{facetSettings.title ?? facetSettings?.field?.label}
|
|
80
|
+
</span>
|
|
81
|
+
<FilterListComponent {...props} facet={facet} />
|
|
82
|
+
</div>
|
|
83
|
+
)}
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
})}
|
|
117
87
|
</div>
|
|
118
88
|
</Accordion.Content>
|
|
119
89
|
</Accordion>
|
|
@@ -2,11 +2,45 @@ import React from 'react';
|
|
|
2
2
|
import renderer from 'react-test-renderer';
|
|
3
3
|
import configureStore from 'redux-mock-store';
|
|
4
4
|
import { Provider } from 'react-intl-redux';
|
|
5
|
+
import config from '@plone/volto/registry';
|
|
5
6
|
|
|
6
7
|
import FilterList from './FilterList';
|
|
8
|
+
import SelectFacet from './SelectFacet';
|
|
9
|
+
import SelectFacetFilterListEntry from './SelectFacetFilterListEntry';
|
|
7
10
|
|
|
8
11
|
const mockStore = configureStore();
|
|
9
12
|
|
|
13
|
+
config.blocks.blocksConfig = {
|
|
14
|
+
search: {
|
|
15
|
+
id: 'search',
|
|
16
|
+
title: 'Search',
|
|
17
|
+
restricted: false,
|
|
18
|
+
mostUsed: false,
|
|
19
|
+
sidebarTab: 1,
|
|
20
|
+
security: {
|
|
21
|
+
addPermission: [],
|
|
22
|
+
view: [],
|
|
23
|
+
},
|
|
24
|
+
variations: [],
|
|
25
|
+
extensions: {
|
|
26
|
+
facetWidgets: {
|
|
27
|
+
types: [
|
|
28
|
+
{
|
|
29
|
+
id: 'selectFacet',
|
|
30
|
+
title: 'Select',
|
|
31
|
+
view: SelectFacet,
|
|
32
|
+
isDefault: true,
|
|
33
|
+
schemaEnhancer: SelectFacet.schemaEnhancer,
|
|
34
|
+
stateToValue: SelectFacet.stateToValue,
|
|
35
|
+
valueToQuery: SelectFacet.valueToQuery,
|
|
36
|
+
filterListComponent: SelectFacetFilterListEntry,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
10
44
|
describe('FilterList', () => {
|
|
11
45
|
it('renders filters listing component for search block', () => {
|
|
12
46
|
const store = mockStore({
|
|
@@ -17,9 +51,23 @@ describe('FilterList', () => {
|
|
|
17
51
|
messages: {},
|
|
18
52
|
},
|
|
19
53
|
});
|
|
54
|
+
const data = {
|
|
55
|
+
facets: [
|
|
56
|
+
{
|
|
57
|
+
'@id': 'a',
|
|
58
|
+
field: {
|
|
59
|
+
value: 'portal_type',
|
|
60
|
+
label: 'Portal type',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
};
|
|
20
65
|
const component = renderer.create(
|
|
21
66
|
<Provider store={store}>
|
|
22
|
-
<FilterList
|
|
67
|
+
<FilterList
|
|
68
|
+
data={data}
|
|
69
|
+
facets={{ portal_type: ['Document', 'Folder'] }}
|
|
70
|
+
/>
|
|
23
71
|
</Provider>,
|
|
24
72
|
);
|
|
25
73
|
const json = component.toJSON();
|