Skip to content

Commit

Permalink
Add support for sidebar facet conditions (#18)
Browse files Browse the repository at this point in the history
* Add support for sidebar facet conditions

- add person result type
  - display phone, email
  - add missing icons
  - thumbnail image
  - fallback avatar
- layout selector and grid layout
- ResultItemPreviewImage helper
- query parameters improvements
  - refactor conversion between state and query parameters
  - support search conditions as a query parameter
- facet fields UI
  - optimized rendering
  - field results
    - cached selection
    - sorted values by count, alphabetic
    - show remaining, already selected values at the end of the list
  - prefix filter for each field
  - support Show more for each field
- fix semantic-ui dimmer to cover the entire viewport

* Add required news doodah

* fix linting

* fix linting

* fix linting

* fix linting

* fix linting

* fix linting

* - pass layout to result type templates as a prop

* - enable translations on facet search condition labels

* - implement base64 conversion of utf, needed for accented characters

* rename prefix - contains

* fix tests

* - fix css for image result type, tile footer

* fix linting

* Use the branched version of kitconcept.solr for acceptance

* - fix margins of preview image in result types

* fix counter layout, casued problem with missing (0) counters

* Fix dimmer to not block the entire page, center instead

* - hide page selector if there is only one page

* Show more indicator displayed only if there are more elements

* - fix - never provide a * as a fallback for empty SearchableText

* - add doEmptySearch option that causes to allow search with empty term

This is useful to start search with the facet conditions.

* improve scrollbar placement on more list of values

* Fix linting

Fix linting

Fix linting

* Update acceptance to use kitconcept.solr==1.0.0a5

* Update solr configuration for acceptance tests

* Fix local acceptance testing, HOST env var is needed for Volto 17 setup

* Fix results to be shown

* Fix updating search on paging or sort order change

* Fix sort order

* Fix unit tests

---------

Co-authored-by: Balázs Reé <ree@greenfinity.hu>
  • Loading branch information
reekitconcept and reebalazs authored Mar 4, 2024
1 parent 361e6ac commit 4603af9
Show file tree
Hide file tree
Showing 35 changed files with 1,738 additions and 216 deletions.
6 changes: 6 additions & 0 deletions acceptance/cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ Cypress.Commands.add(
contentContactName,
contentWebsite,
contentContactMail,
contentEffective,
reviewState = 'published',
withImage,
path = '',
Expand Down Expand Up @@ -189,6 +190,7 @@ Cypress.Commands.add(
description: contentDescription,
subjects: contentSubjects,
topic: contentTopics,
effective: contentEffective,
file: {
data: 'dGVzdGZpbGUK',
encoding: 'base64',
Expand All @@ -215,6 +217,7 @@ Cypress.Commands.add(
title: contentTitle,
description: contentDescription,
subjects: contentSubjects,
effective: contentEffective,
image: {
data:
'iVBORw0KGgoAAAANSUhEUgAAANcAAAA4CAMAAABZsZ3QAAAAM1BMVEX29fK42OU+oMvn7u9drtIPisHI4OhstdWZyt4fkcXX5+sAg74umMhNp86p0eJ7vNiKw9v/UV4wAAAAAXRSTlMAQObYZgAABBxJREFUeF7tmuty4yAMhZG4X2zn/Z92J5tsBJwWXG/i3XR6frW2Y/SBLIRAfaQUDNt8E5tLUt9BycfcKfq3R6Mlfyimtx4rzp+K3dtibXkor99zsEqLYZltblTecciogoh+TXfY1Ve4dn07rCDGG9dHSEEOg/GmXl0U1XDxTKxNK5De7BxsyyBr6gGm2/vPxKJ8F6f7BXKfRMp1xIWK9A+5ks25alSb353dWnDJN1k35EL5f8dVGifTf/4tjUuuFq7u4srmXC60yAmldLXIWbg65RKU87lcGxJCFqUPv0IacW0PmSivOZFLE908inPToMmii/roG+MRV/O8FU88i8tFsxV3a06MFUw0Qu7RmAtdV5/HVVaOVMTWNOWSwMljLhzhcB6XIS7OK5V6AvRDNN7t5VJWQs1J40UmalbK56usBG/CuCHSYuc+rkUGeMCViNRARPrzW52N3oQLe6WifNliSuuGaH3czbVNudI9s7ZLUCLHVwWlyES522o1t14uvmbblmVTKqFjaZYJFSTPP4dLL1kU1z7p0lzdbRulmEWLxoQX+z9ce7A8GqEEucllLxePuZwdJl1Lezu0hoswvTPt61DrFcRuujV/2cmlxaGBC7Aw6cpovGANwRiSdOAWJ5AGy4gLL64dl0QhUEAuEUNws+XxV+OKGPdw/hESGYF9XEGaFC7sNLMSXWJjHsnanYi87VK428N2uxpOjOFANcagLM5l+7mSycM8KknZpKLcGi6jmzWGr/vLurZ/0g4u9AZuAoeb5r1ceQhyiTPY1E4wUR6u/F3H2ojSpXMMriBPT9cezTto8Cx+MsglHL4fv1Rxrb1LVw9yvyQpJ3AhFnLZfuRLH2QsOG3FGGD20X/th/u5bFAt16Bt308KjF+MNOXgl/SquIEySX3GhaZvc67KZbDxcCDORz2N8yCWPaY5lyQZO7lQ29fnZbt3Xu6qoge4+DjXl/MocySPOp9rlvdyznahRyHEYd77v3LhugOXDv4J65QXfl803BDAdaWBEDhfVx7nKofjoVCgxnUAqw/UAUDPn788BDvQuG4TDtdtUPvzjSlXAB8DvaDOhhrmhwbywylXAm8CvaouikJTL93gs3y7Yy4VYbIxOHrcMizPqWOjqO9l3Uz52kibQy4xxOgqhJvD+w5rvokOcAlGvNCfeqCv1ste1stzLm0f71Iq3ZfTrPfuE5nhPtF+LvQE2lffQC7pYtQy3tdzdrKvd5TLVVzDetScS3nEKmmwDyt1Cev1kX3YfbvzNK4fzrlw+cB6vm+uiUgf2zdXI62241LawCb7Pi5FXFPF8KpzDoF/Sw2lg+GrHNbno1mhPu+VCF/vfMnw06PnUl6j48dVHD3jHNHPua+fc3o/5yp/zsGi0vYtzi3Pz5mHd4T6BWMIlewacd63AAAAAElFTkSuQmCC',
Expand Down Expand Up @@ -243,6 +246,7 @@ Cypress.Commands.add(
title: contentTitle,
description: contentDescription,
subjects: contentSubjects,
effective: contentEffective,
target_url: target_url,
shows_people: false,
language,
Expand Down Expand Up @@ -277,6 +281,7 @@ Cypress.Commands.add(
description: contentDescription,
head_title: contentHeadTitle,
subjects: contentSubjects,
effective: contentEffective,
blocks: blocks,
blocks_layout: blocksLayout,
allow_discussion: allow_discussion,
Expand All @@ -302,6 +307,7 @@ Cypress.Commands.add(
description: contentDescription,
head_title: contentHeadTitle,
subjects: contentSubjects,
effective: contentEffective,
allow_discussion: allow_discussion,
review_state: reviewState,
contact_name: contentContactName,
Expand Down
3 changes: 3 additions & 0 deletions acceptance/cypress/tests/search-ui.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ context('Search Acceptance Tests (UI)', () => {
contentId: 'alpha',
contentTitle: 'Alpha Beta Gaga Colorful',
path: '/',
contentEffective: '2018-01-21T08:00:00',
});
cy.request({
method: 'POST',
Expand All @@ -28,6 +29,7 @@ context('Search Acceptance Tests (UI)', () => {
contentId: 'beta',
contentTitle: 'Beta Colorful',
path: '',
contentEffective: '2018-02-21T08:00:00',
});
cy.request({
method: 'POST',
Expand All @@ -45,6 +47,7 @@ context('Search Acceptance Tests (UI)', () => {
contentId: 'gamma',
contentTitle: 'Gamma Colorful',
path: '',
contentEffective: '2018-03-21T08:00:00',
});
cy.request({
method: 'POST',
Expand Down
3 changes: 2 additions & 1 deletion acceptance/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ services:
environment:
RAZZLE_INTERNAL_API_PATH: http://backend-acceptance:55001/plone
RAZZLE_API_PATH: http://localhost:55001/plone
HOST: 0.0.0.0
ports:
- 3000:3000
- 3001:3001
Expand Down Expand Up @@ -51,7 +52,7 @@ services:
# Use plone.volto rather than kitconcept.volto for the acceptance
# testing, which makes login in tests "more conventional". - otherwise
# it's no difference, both could make sense.
ADDONS: 'plone.app.robotframework==2.0.0 plone.app.contenttypes plone.restapi plone.volto kitconcept.solr==1.0.0a1'
ADDONS: 'plone.app.robotframework==2.0.0 plone.app.contenttypes plone.restapi plone.volto kitconcept.solr==1.0.0a5'
APPLY_PROFILES: plone.app.contenttypes:plone-content,plone.restapi:default,plone.volto:default-homepage,kitconcept.solr:default,collective.solr:default
CONFIGURE_PACKAGES: plone.app.contenttypes,plone.restapi,plone.volto,plone.volto.cors,kitconcept.solr,collective.solr
SOLR_HOST: solr-acceptance
Expand Down
2 changes: 1 addition & 1 deletion acceptance/solr/etc/conf/schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@

<!-- custom content type: Event -->
<field
name="contact_email" type="text" indexed="true" stored="false" />
name="contact_email" type="string" indexed="true" stored="false" />
<field name="contact_name"
type="text" indexed="true" stored="false" />
<field name="event_url" type="text" indexed="true"
Expand Down
73 changes: 53 additions & 20 deletions acceptance/solr/etc/conf/solrconfig.xml
Original file line number Diff line number Diff line change
@@ -1,26 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<config>
<luceneMatchVersion>4.5</luceneMatchVersion>

<dataDir>${solr.data.dir:}</dataDir>

<directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}" />
<directoryFactory class="${solr.directoryFactory:solr.NRTCachingDirectoryFactory}"
name="DirectoryFactory"
/>

<codecFactory class="solr.SchemaCodecFactory" />
<schemaFactory class="ClassicIndexSchemaFactory" />

<!-- TIKA START -->
<!-- Load Data Import Handler and Apache Tika (extraction) libraries -->
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-dataimporthandler-.*\.jar" />

<lib dir="${solr.install.dir:../../../..}/contrib/extraction/lib" regex=".*\.jar" />
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-cell-\d.*\.jar" />

<lib dir="${solr.install.dir:../../../..}/contrib/langid/lib/" regex=".*\.jar" />
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-langid-\d.*\.jar" />

<lib dir="${solr.install.dir:../../../..}/contrib/velocity/lib" regex=".*\.jar" />
<lib dir="${solr.install.dir:../../../..}/dist/" regex="solr-velocity-\d.*\.jar" />
<lib dir="${solr.install.dir:../../../..}/dist/"
regex="solr-dataimporthandler-.*\.jar"
/>

<lib dir="${solr.install.dir:../../../..}/contrib/extraction/lib"
regex=".*\.jar"
/>
<lib dir="${solr.install.dir:../../../..}/dist/"
regex="solr-cell-\d.*\.jar"
/>

<lib dir="${solr.install.dir:../../../..}/contrib/langid/lib/"
regex=".*\.jar"
/>
<lib dir="${solr.install.dir:../../../..}/dist/"
regex="solr-langid-\d.*\.jar"
/>

<lib dir="${solr.install.dir:../../../..}/contrib/velocity/lib"
regex=".*\.jar"
/>
<lib dir="${solr.install.dir:../../../..}/dist/"
regex="solr-velocity-\d.*\.jar"
/>

<!-- Request Dispatcher
This section contains instructions for how the SolrDispatchFilter
Expand Down Expand Up @@ -51,7 +67,11 @@
<requestParsers enableRemoteStreaming="false" multipartUploadLimitInKB="-1" formdataUploadLimitInKB="-1" addHttpRequestToContext="false"/>
-->

<requestParsers enableRemoteStreaming="true" multipartUploadLimitInKB="-1" formdataUploadLimitInKB="-1" addHttpRequestToContext="false" />
<requestParsers addHttpRequestToContext="false"
enableRemoteStreaming="true"
formdataUploadLimitInKB="-1"
multipartUploadLimitInKB="-1"
/>

<!-- HTTP Caching
Set HTTP caching related parameters (for proxy caches and clients).
Expand Down Expand Up @@ -99,7 +119,10 @@
<!-- Solr Cell Update Request Handler
http://wiki.apache.org/solr/ExtractingRequestHandler
-->
<requestHandler name="/update/extract" startup="lazy" class="solr.extraction.ExtractingRequestHandler">
<requestHandler class="solr.extraction.ExtractingRequestHandler"
name="/update/extract"
startup="lazy"
>
<lst name="defaults">
<str name="lowernames">true</str>
<str name="uprefix">ignored_</str>
Expand Down Expand Up @@ -180,7 +203,9 @@

</updateHandler>

<requestHandler name="/select" class="solr.SearchHandler">
<requestHandler class="solr.SearchHandler"
name="/select"
>
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int>
Expand All @@ -189,9 +214,13 @@
</lst>
</requestHandler>

<requestHandler name="/update" class="solr.UpdateRequestHandler" />
<requestHandler class="solr.UpdateRequestHandler"
name="/update"
/>

<requestHandler name="/admin/ping" class="solr.PingRequestHandler">
<requestHandler class="solr.PingRequestHandler"
name="/admin/ping"
>
<lst name="invariants">
<str name="q">solrpingquery</str>
</lst>
Expand All @@ -202,7 +231,9 @@

<!-- Autocomplete/suggest -->

<requestHandler class="org.apache.solr.handler.component.SearchHandler" name="/suggest">
<requestHandler class="org.apache.solr.handler.component.SearchHandler"
name="/suggest"
>
<lst name="defaults">
<str name="echoParams">none</str>
<str name="wt">json</str>
Expand All @@ -218,7 +249,9 @@
</lst>
</requestHandler>

<searchComponent class="solr.SpellCheckComponent" name="suggest">
<searchComponent class="solr.SpellCheckComponent"
name="suggest"
>
<lst name="spellchecker">
<str name="name">suggestDictionary</str>
<str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
Expand All @@ -229,4 +262,4 @@
</lst>
</searchComponent>

</config>
</config>
1 change: 1 addition & 0 deletions news/15.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for sidebar facet conditions @reebalazs
6 changes: 3 additions & 3 deletions src/actions/solrsearch/solrsearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ export function solrSearchContent(url, options, subrequest = null) {
!options['portal_type'] &&
!options['review_state'];

if (emptySearchCondition) {
if (!options.doEmptySearch && emptySearchCondition) {
// If none of the conditions are specified, we don't do a server
// search but return an empty result set in a shortcut.
// Note that an empty `q` parameter would fail anyway.
// This behavior is configurable by the `doEmptySearch` option.
return resetSolrSearchContent(subrequest);
}

Expand Down Expand Up @@ -92,8 +93,7 @@ export function solrSearchContent(url, options, subrequest = null) {
'&',
)
: '',
// SearchableText is inserted in all cases, if missing * will be applied
`q=${options.SearchableText !== undefined ? options.SearchableText : '*'}`,
`q=${options.SearchableText ?? ''}`,
// Default batch size is injected here
`rows=${
options.b_size !== undefined ? options.b_size : settings.defaultPageSize
Expand Down
20 changes: 14 additions & 6 deletions src/actions/solrsearch/solrsearch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ describe('SOLR search action', () => {
expect(action.subrequest).toBe(null);
});

it('doEmptySearch option', () => {
const url = '/blog';
const action = solrSearchContent(url, { doEmptySearch: true });

expect(action.type).toEqual(SOLR_SEARCH_CONTENT);
expect(action.subrequest).toBe(null);
});

it('if SearchableText, portal_type, review_state are all missing, no request is made and results are cleared, with subrequest', () => {
const url = '/blog';
const action = solrSearchContent(url, {}, 'my-subrequest');
Expand All @@ -36,27 +44,27 @@ describe('SOLR search action', () => {
expect(action.subrequest).toEqual('my-subrequest');
});

it('if SearchableText is missing but portal_type is specified, q=* will be provided', () => {
it('if SearchableText is missing but portal_type is specified, q= will be provided', () => {
const url = '/blog';
const portalType = 'Document';
const action = solrSearchContent(url, { portal_type: portalType });

expect(action.type).toEqual(SOLR_SEARCH_CONTENT);
expect(action.request.op).toEqual('get');
expect(action.request.path).toEqual(
`${url}/@solr?portal_type=${portalType}&q=*&rows=25`,
`${url}/@solr?portal_type=${portalType}&q=&rows=25`,
);
});

it('if SearchableText is missing but review_state is specified, q=* will be provided', () => {
it('if SearchableText is missing but review_state is specified, q= will be provided', () => {
const url = '/blog';
const reviewState = 'published';
const action = solrSearchContent(url, { review_state: reviewState });

expect(action.type).toEqual(SOLR_SEARCH_CONTENT);
expect(action.request.op).toEqual('get');
expect(action.request.path).toEqual(
`${url}/@solr?review_state=${reviewState}&q=*&rows=25`,
`${url}/@solr?review_state=${reviewState}&q=&rows=25`,
);
});
});
Expand Down Expand Up @@ -107,7 +115,7 @@ describe('SOLR search action', () => {
expect(action.type).toEqual(SOLR_SEARCH_CONTENT);
expect(action.request.op).toEqual('get');
expect(action.request.path).toEqual(
`${url}/@solr?portal_type:list=Document&portal_type:list=Image&review_state:list=published&review_state:list=private&q=*&rows=25`,
`${url}/@solr?portal_type:list=Document&portal_type:list=Image&review_state:list=published&review_state:list=private&q=&rows=25`,
);
});

Expand All @@ -131,7 +139,7 @@ describe('SOLR search action', () => {
expect(action.subrequest).toEqual('my-subrequest');
expect(action.request.op).toEqual('get');
expect(action.request.path).toEqual(
`${url}/@solr?portal_type=${portalType}&q=*&rows=25`,
`${url}/@solr?portal_type=${portalType}&q=&rows=25`,
);
});

Expand Down
Loading

0 comments on commit 4603af9

Please sign in to comment.