diff --git a/src/components/Blocks/FacetedSearchBlockEdit.jsx b/src/components/Blocks/FacetedSearchBlockEdit.jsx
index e9238263..cb2b8b33 100644
--- a/src/components/Blocks/FacetedSearchBlockEdit.jsx
+++ b/src/components/Blocks/FacetedSearchBlockEdit.jsx
@@ -18,7 +18,7 @@ const Edit = ({ data, onChangeBlock, block, selected }) => {
-
+
);
};
diff --git a/src/components/Blocks/FacetedSearchBlockView.jsx b/src/components/Blocks/FacetedSearchBlockView.jsx
index 14b27a2e..6cc0e92d 100644
--- a/src/components/Blocks/FacetedSearchBlockView.jsx
+++ b/src/components/Blocks/FacetedSearchBlockView.jsx
@@ -1,5 +1,3 @@
-import React from 'react';
-
import FacetedSearch from '../Views/FacetedSearch';
const View = ({ data }) => {
diff --git a/src/components/Blocks/schema.js b/src/components/Blocks/schema.js
index 19a18112..2f90f0b8 100644
--- a/src/components/Blocks/schema.js
+++ b/src/components/Blocks/schema.js
@@ -69,12 +69,18 @@ export const SearchBlockSchema = ({ data = {}, intl }) => {
'allowed_content_types',
'allowed_review_states',
'searchedFields',
+ 'batchSize',
],
},
{
id: 'results',
title: 'Results',
- fields: ['extrainfo_fields', 'subjectsFieldname'],
+ fields: [
+ 'extrainfo_fields',
+ 'subjectsFieldname',
+ 'showNewsItemPublishedDate',
+ 'showEventStartDate',
+ ],
},
{
id: 'divers',
@@ -143,6 +149,11 @@ export const SearchBlockSchema = ({ data = {}, intl }) => {
creatable: true,
default: ['title^1.4', 'description^1.2', 'blocks_plaintext'],
},
+ batchSize: {
+ title: 'Batch size',
+ type: 'number',
+ default: 10,
+ },
facet_fields: {
title: 'Facets',
description: 'Fields to filter on.',
@@ -167,7 +178,23 @@ export const SearchBlockSchema = ({ data = {}, intl }) => {
title: 'Field name of tags field',
description:
'Show tags to search for. Let the field empty to not show tags.',
- default: '',
+ default: 'subjects',
+ },
+ showNewsItemPublishedDate: {
+ title: 'Show published date of news items',
+ type: 'array',
+ widget: 'array',
+ items: {
+ vocabulary: { '@id': 'plone.app.vocabularies.UserFriendlyTypes' },
+ },
+ },
+ showEventStartDate: {
+ title: 'Show start date of events',
+ type: 'array',
+ widget: 'array',
+ items: {
+ vocabulary: { '@id': 'plone.app.vocabularies.UserFriendlyTypes' },
+ },
},
relocation: {
title: 'Relocation',
diff --git a/src/components/Searchkit/CustomESRequestSerializer.jsx b/src/components/Searchkit/CustomESRequestSerializer.jsx
index 761245c8..4fe7e7f9 100644
--- a/src/components/Searchkit/CustomESRequestSerializer.jsx
+++ b/src/components/Searchkit/CustomESRequestSerializer.jsx
@@ -155,7 +155,7 @@ export class CustomESRequestSerializer {
// fields with boosting
let searchedFields = [...this.searchedFields];
-
+
let searchedFields_simple = searchedFields.map((fld) => {
const fieldname = fld.split('^')[0];
return fld.replace(fieldname, `${fieldname}.${this.language}`);
@@ -223,14 +223,19 @@ export class CustomESRequestSerializer {
bodyParams['highlight'] = {
number_of_fragments: 20,
- fields: ['title', 'description', 'blocks_plaintext'].map(fieldname => {
- return {
- [fieldname]: {
- matched_fields: [`${fieldname}.${this.language}`, `${fieldname}.${this.language}_exact`],
- type: 'fvh',
- },
- }
- })
+ fields: ['title', 'description', 'blocks_plaintext'].map(
+ (fieldname) => {
+ return {
+ [fieldname]: {
+ matched_fields: [
+ `${fieldname}.${this.language}`,
+ `${fieldname}.${this.language}_exact`,
+ ],
+ type: 'fvh',
+ },
+ };
+ },
+ ),
};
}
@@ -258,12 +263,14 @@ export class CustomESRequestSerializer {
// Generate terms of global filters
let terms = [];
// If isMultilingual, search only in language
-
- this.language && volto_config.settings.isMultilingual && terms.push({
- terms: {
- language: [this.language],
- },
- });
+
+ this.language &&
+ volto_config.settings.isMultilingual &&
+ terms.push({
+ terms: {
+ language: [this.language],
+ },
+ });
this.allowed_content_types?.length > 0 &&
terms.push({
terms: {
diff --git a/src/components/Searchkit/CustomESResponseSerializer.jsx b/src/components/Searchkit/CustomESResponseSerializer.jsx
index 07cdfbee..8327a86d 100644
--- a/src/components/Searchkit/CustomESResponseSerializer.jsx
+++ b/src/components/Searchkit/CustomESResponseSerializer.jsx
@@ -41,7 +41,7 @@ export class CustomESResponseSerializer {
hit._source['highlight'] = hit.highlight;
return hit._source;
}) || [],
- total: hits?.total.value < 11 ? hits.hits.length : hits?.total.value || 0,
+ total: hits?.total.value || 0,
};
return foo;
}
diff --git a/src/components/Searchkit/ElasticSearchHighlights.jsx b/src/components/Searchkit/ElasticSearchHighlights.jsx
index c948b2c0..739fb2ab 100644
--- a/src/components/Searchkit/ElasticSearchHighlights.jsx
+++ b/src/components/Searchkit/ElasticSearchHighlights.jsx
@@ -6,7 +6,7 @@ import React from 'react';
import { useIntl } from 'react-intl';
import messages from '../../messages';
-export const ElasticSearchHighlights = ({ highlight, indexResult }) => {
+export const ElasticSearchHighlights = ({ highlight }) => {
const [toggleDetails, setToggleDetails] = React.useState(false);
const intl = useIntl();
@@ -32,7 +32,6 @@ export const ElasticSearchHighlights = ({ highlight, indexResult }) => {
onClick={showDetails}
role="button"
onKeyPress={showDetails}
- tabIndex={indexResult}
>
{fragments.slice(0, 3).map((el, index) => {
return
;
@@ -44,7 +43,6 @@ export const ElasticSearchHighlights = ({ highlight, indexResult }) => {
onClick={showDetails}
role="button"
onKeyPress={showDetails}
- tabIndex={indexResult}
>
{Object.keys(highlight)
.reverse()
diff --git a/src/components/Searchkit/SearchBarSection.jsx b/src/components/Searchkit/SearchBarSection.jsx
index 81939111..7c4917d4 100644
--- a/src/components/Searchkit/SearchBarSection.jsx
+++ b/src/components/Searchkit/SearchBarSection.jsx
@@ -13,7 +13,7 @@ const _SearchBarSection = (props) => {
sortOrder: 'asc',
layout: 'list',
page: 1,
- size: 10,
+ size: props.currentQueryState.data.batchSize,
queryString: '',
},
};
diff --git a/src/components/Searchkit/SectionsSearch.jsx b/src/components/Searchkit/SectionsSearch.jsx
index 133ad80c..70b7b65d 100644
--- a/src/components/Searchkit/SectionsSearch.jsx
+++ b/src/components/Searchkit/SectionsSearch.jsx
@@ -67,7 +67,7 @@ const _SectionsSearch = (props) => {
sortOrder: 'desc',
layout: 'list',
page: 1,
- size: 10,
+ size: props.currentQueryState.data.batchSize,
filters: currentQueryState.filters,
};
if (currentQueryState.queryString) {
diff --git a/src/components/Views/FacetedSearch.jsx b/src/components/Views/FacetedSearch.jsx
index e5ebb623..7a157a9b 100644
--- a/src/components/Views/FacetedSearch.jsx
+++ b/src/components/Views/FacetedSearch.jsx
@@ -32,7 +32,7 @@ import {
} from 'react-searchkit';
import { expandToBackendURL } from '@plone/volto/helpers';
-import { Icon } from '@plone/volto/components';
+import { FormattedDate, Icon } from '@plone/volto/components';
import leftAngle from '@plone/volto/icons/left-key.svg';
import rightAngle from '@plone/volto/icons/right-key.svg';
import firstAngle from '@plone/volto/icons/first.svg';
@@ -104,7 +104,7 @@ const _ExtraInfo = (props) => {
const translate = (key, fieldname) => {
let label = key;
- if (querystringindexes || querystringindexes[fieldname]) {
+ if (querystringindexes && fieldname in querystringindexes) {
label = querystringindexes[fieldname]?.values[key]?.title || key;
}
return label;
@@ -131,7 +131,7 @@ const _ExtraInfo = (props) => {
sortOrder: 'asc',
layout: 'list',
page: 1,
- size: 10,
+ size: props.currentQueryState.data.batchSize,
filters: [[`${extrainfo_key}_agg`, item]],
},
};
@@ -182,7 +182,7 @@ const _ExtraInfo = (props) => {
sortOrder: 'asc',
layout: 'list',
page: 1,
- size: 10,
+ size: props.currentQueryState.data.batchSize,
queryString: tito,
},
};
@@ -206,15 +206,22 @@ const _ExtraInfo = (props) => {
const ExtraInfo = withState(_ExtraInfo);
const _CustomResultsListItem = (props) => {
- const { result, index } = props;
+ const { result } = props;
const backend_url = props.currentQueryState.data?.backend_url;
const is_external_content = !result['@id'].includes(backend_url);
const item_url = result['@id'].includes(backend_url)
? flattenESUrlToPath(result['@id'])
: result['@id'];
+ const locale = useSelector((state) => state.query?.locale);
const querystringindexes = useSelector(
(state) => state.query?.data?.querystringindexes,
);
+ const showNewsItemPublishedDate = useSelector(
+ (state) => state.query?.data.showNewsItemPublishedDate,
+ );
+ const showEventStartDate = useSelector(
+ (state) => state.query?.data.showEventStartDate,
+ );
const translate = (key) => {
let label = key;
@@ -226,7 +233,7 @@ const _CustomResultsListItem = (props) => {
return (
-
@@ -241,7 +248,7 @@ const _CustomResultsListItem = (props) => {
sortOrder: 'asc',
layout: 'list',
page: 1,
- size: 10,
+ size: props.currentQueryState.data.batchSize,
filters: [['informationtype_agg', item]],
},
};
@@ -264,6 +271,17 @@ const _CustomResultsListItem = (props) => {
>
{result.title}
+ {showNewsItemPublishedDate.includes(result.portal_type) &&
+ result.effective ? (
+
+
+
+ ) : null}
+ {showEventStartDate.includes(result.portal_type) && result.start ? (
+
+
+
+ ) : null}
{truncate(result.description, { length: 200 })}
@@ -275,6 +293,17 @@ const _CustomResultsListItem = (props) => {
{result.title}
+ {showNewsItemPublishedDate.includes(result.portal_type) &&
+ result.effective ? (
+
+
+
+ ) : null}
+ {showEventStartDate.includes(result.portal_type) && result.start ? (
+
+
+
+ ) : null}
{truncate(result.description, { length: 200 })}
@@ -283,10 +312,7 @@ const _CustomResultsListItem = (props) => {
)}
-
+
);
@@ -345,7 +371,7 @@ const CustomBucketAggregationElement = (props) => {
* @returns
*/
const translate = (bucks) => {
- if (querystringindexes[fieldname]) {
+ if (querystringindexes && fieldname in querystringindexes) {
bucks.forEach((element) => {
element.label =
querystringindexes[fieldname].values[element.key]?.title ||
@@ -651,35 +677,6 @@ const sortValues = [
// },
];
-const initialState = {
- sortBy: 'bestmatch',
- sortOrder: 'asc',
- // sortBy: 'modified',
- // sortOrder: 'desc',
- queryString: '',
- layout: 'list',
- page: 1,
- size: 10,
-};
-
-const defaultOverriddenComponents = {
- 'ResultsList.item.elasticsearch': CustomResultsListItem,
- 'Count.element': MyCountElement,
- 'ActiveFilters.element': myActiveFiltersElement,
- 'EmptyResults.element': customEmpytResultsElement,
- 'Sort.element.volto': customSort,
- 'Pagination.element': customPaginationElement,
- 'Error.element': ErrorComponent,
-};
-
-const dropdownOverriddenComponents = {
- 'BucketAggregation.element': CustomBucketAggregationElement,
- 'BucketAggregationContainer.element': CustomBucketAggregationContainerElement,
- 'BucketAggregationValues.element': withState(
- CustomBucketAggregationValuesElement,
- ),
-};
-
/**
* FacetedSearch
* @param {string} filterLayout default 'dropdown'
@@ -704,6 +701,35 @@ const FacetedSearch = ({ data, overriddenComponents }) => {
delete facet_fields_object.Subject;
}
+ // TODO Get config from data
+ const initialState = {
+ page: 1,
+ queryString: '',
+ sortBy: 'modified',
+ sortOrder: 'desc',
+ size: data.batchSize,
+ layout: 'list',
+ };
+
+ const defaultOverriddenComponents = {
+ 'ResultsList.item.elasticsearch': CustomResultsListItem,
+ 'Count.element': MyCountElement,
+ 'ActiveFilters.element': myActiveFiltersElement,
+ 'EmptyResults.element': customEmpytResultsElement,
+ 'Sort.element.volto': customSort,
+ 'Pagination.element': customPaginationElement,
+ 'Error.element': ErrorComponent,
+ };
+
+ const dropdownOverriddenComponents = {
+ 'BucketAggregation.element': CustomBucketAggregationElement,
+ 'BucketAggregationContainer.element':
+ CustomBucketAggregationContainerElement,
+ 'BucketAggregationValues.element': withState(
+ CustomBucketAggregationValuesElement,
+ ),
+ };
+
overriddenComponents = {
...defaultOverriddenComponents,
...(filterLayout === 'dropdown' && dropdownOverriddenComponents),
@@ -712,8 +738,7 @@ const FacetedSearch = ({ data, overriddenComponents }) => {
};
// TODO Check if check on client could be made simpler
- const language = useSelector((state) => state.intl.locale);
- console.debug('language', language);
+ const locale = useSelector((state) => state.intl.locale);
const [isClient, setIsClient] = React.useState(null);
React.useEffect(() => setIsClient(true), []);
@@ -722,11 +747,13 @@ const FacetedSearch = ({ data, overriddenComponents }) => {
{isClient && (
diff --git a/src/components/Views/TestSearchkitQuerystrings.jsx b/src/components/Views/TestSearchkitQuerystrings.jsx
index 0d5e3148..5f456102 100644
--- a/src/components/Views/TestSearchkitQuerystrings.jsx
+++ b/src/components/Views/TestSearchkitQuerystrings.jsx
@@ -1,11 +1,13 @@
import React from 'react';
import { useIntl } from 'react-intl';
+import { createPortal } from 'react-dom';
import { Container, Header, Segment } from 'semantic-ui-react';
+import { useHistory } from 'react-router';
import { Link, useLocation } from 'react-router-dom';
-import { useDispatch, useSelector } from 'react-redux';
+import { useSelector } from 'react-redux';
import { OverridableContext } from 'react-overridable';
-import { getControlpanel } from '@plone/volto/actions';
-import { Icon as IconNext } from '@plone/volto/components';
+import { Icon, Toolbar } from '@plone/volto/components';
+import { getParentUrl } from '@plone/volto/helpers';
import backSVG from '@plone/volto/icons/back.svg';
import {
@@ -21,6 +23,8 @@ import { ploneSearchApi } from './FacetedSearch';
import { ElasticSearchMatches } from '../Searchkit/ElasticSearchHighlights';
import messages from '../../messages';
+import config from '@plone/volto/registry';
+
const sort_caseinsensitive = (a, b) => {
var nameA = a.toUpperCase(); // Groß-/Kleinschreibung ignorieren
var nameB = b.toUpperCase(); // Groß-/Kleinschreibung ignorieren
@@ -103,27 +107,8 @@ const overriddenComponents = {
const TestSearchkitQuerystrings = (props) => {
const intl = useIntl();
- const dispatch = useDispatch();
- const searchkitblock_controlpanel = useSelector(
- (state) => state.controlpanels.controlpanel?.data,
- );
- const searchconfig = searchkitblock_controlpanel
- ? {
- elastic_search_api_url:
- searchkitblock_controlpanel?.testsearch_elasticsearch_url,
- elastic_search_api_index:
- searchkitblock_controlpanel?.testsearch_elasticsearch_index,
-
- searchedFields: [],
- facet_fields: [],
- allowed_content_types:
- searchkitblock_controlpanel?.allowed_content_types,
- allowed_review_states:
- searchkitblock_controlpanel?.allowed_review_states,
- backend_url: searchkitblock_controlpanel?.testsearch_backend,
- frontend_url: searchkitblock_controlpanel?.testsearch_frontend,
- }
- : {};
+ const history = useHistory();
+ const searchconfig = config.blocks.blocksConfig.searchkitblock.searchconfig;
const initialState = {
sortBy: 'bestmatch',
@@ -145,69 +130,88 @@ const TestSearchkitQuerystrings = (props) => {
return;
};
+ const locale = useSelector((state) => state.intl.locale);
const [isClient, setIsClient] = React.useState(null);
React.useEffect(() => setIsClient(true), []);
- React.useEffect(() => {
- dispatch(getControlpanel('volto_searchkit_block_control_panel'));
- }, [dispatch]);
-
return (
-
-
-
-
- {isClient && searchkitblock_controlpanel && (
-
-
- <>
-
- {/* {
- onchangehandler(event, data);
- }}
- /> */}
- {
- onchangehandler(event, data);
- }}
+
+
+
+
+
+ {isClient && (
+
+
+ <>
+
+ {/* {
+ onchangehandler(event, data);
+ }}
+ /> */}
+ {
+ onchangehandler(event, data);
+ }}
+ />
+
+
+
+
+ Documents with title and matches
+
+
+ >
+
+
+ )}
+
+
+ {isClient &&
+ createPortal(
+ {
+ history.push(getParentUrl(location.pathname));
+ }}
+ >
+
-
-
-
-
- Documents with title and matches
-
-
- >
-
-
- )}
-
-
-
-
+
+ }
+ />,
+ document.getElementById('toolbar'),
+ )}
+
);
};
diff --git a/src/components/helpers.jsx b/src/components/helpers.jsx
index 919dffa5..71814bde 100644
--- a/src/components/helpers.jsx
+++ b/src/components/helpers.jsx
@@ -1,4 +1,5 @@
import React from 'react';
+import { useSelector } from 'react-redux';
class NoSSR extends React.Component {
state = {
diff --git a/src/index.js b/src/index.js
index 058e3fca..c6334a56 100644
--- a/src/index.js
+++ b/src/index.js
@@ -65,7 +65,6 @@ const applyConfig = (config) => {
title: 'Test searchkit querystrings',
},
];
-
config.addonRoutes = [
...config.addonRoutes,
{
@@ -73,6 +72,20 @@ const applyConfig = (config) => {
component: TestSearchkitQuerystrings,
},
];
+ // Configure 'Test searchkit querystrings' controlpanel
+ config.blocks.blocksConfig.searchkitblock.searchconfig = {
+ searchedFields: [
+ 'title^1.4',
+ 'description^1.2',
+ 'blocks_plaintext',
+ 'subjects^1.2',
+ ],
+ facet_fields: [],
+ allowed_content_types: ['Document', 'News Item', 'Event'],
+ allowed_review_states: [],
+ backend_url: 'http://host.docker.internal:8080/Plone',
+ frontend_url: 'http://localhost:3000',
+ };
// Fetch querystring indexes.
// See /effective-volto/addons/asyncconnect
diff --git a/src/messages.js b/src/messages.js
index d733e786..ca12b01e 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -71,6 +71,10 @@ const messages = defineMessages({
id: 'Content',
defaultMessage: 'Content',
},
+ cancel: {
+ id: 'Cancel',
+ defaultMessage: 'Cancel',
+ },
});
export default messages;