Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(search): show facets count and hide facets values that are not meeting the mandatory criterias in search block #5812

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b279c93
feat(search): show facets count in search block
razvanMiu Feb 29, 2024
f1592e5
Hide facets values that does not belong to the results that come from…
dobri1408 Mar 6, 2024
df1f120
remove count.count and count_criteria
dobri1408 Mar 6, 2024
4e207c7
show facet that have info from querystring-search
dobri1408 Mar 6, 2024
30b6d6c
Update pnpm-lock.yaml
dobri1408 Mar 7, 2024
06b1607
change criteria to mandatory
dobri1408 Mar 7, 2024
d693c9d
change criteria to mandatory
dobri1408 Mar 7, 2024
d349581
change criteria to mandatory
dobri1408 Mar 7, 2024
1e09f3b
make yaml lock to be as main
dobri1408 Mar 8, 2024
81d39ee
Update pnpm-lock.yaml
dobri1408 Mar 8, 2024
e53782d
changelog
dobri1408 Mar 8, 2024
f0638b6
Merge branch 'facets_count' of https://github.com/plone/volto into fa…
dobri1408 Mar 8, 2024
37fb8ee
merge main
dobri1408 Mar 8, 2024
fb78dea
update snapshot
dobri1408 Mar 8, 2024
c1f7920
fix checkbox
dobri1408 Mar 8, 2024
8e30c49
update snapshot
dobri1408 Mar 8, 2024
3a42cb8
Update pnpm-lock.yaml to match main
dobri1408 Mar 8, 2024
1d6b11d
Update querystringsearch.test.js
dobri1408 Mar 8, 2024
53ed562
fix tests
dobri1408 Mar 8, 2024
f394ebc
fix tets
dobri1408 Mar 8, 2024
a2ad654
fix tets
dobri1408 Mar 8, 2024
8c32a5b
fix tets
dobri1408 Mar 8, 2024
d095140
fix lint
dobri1408 Mar 8, 2024
4197c18
ensure that is backwords compatibile
dobri1408 Mar 8, 2024
d7cbaca
Update CheckboxFacet.test.jsx.snap
dobri1408 Mar 8, 2024
ba58583
ensure that is backward compatibile
dobri1408 Mar 8, 2024
cf2baa9
ensure that is backward compatibile
dobri1408 Mar 8, 2024
9ae97ad
Update pnpm-lock.yaml
dobri1408 Mar 8, 2024
b6cab39
Merge branch 'main' into facets_count
dobri1408 Mar 13, 2024
f0c4930
Merge branch 'main' into facets_count
razvanMiu Mar 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/volto/news/5812.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
feat(search): show facets count and hide facets that are not meeting the mandatory criterias in search block @razvanMiu @dobri1408
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ export default function getListingBlockAsyncData(props) {

const subrequestID = content?.UID ? `${content?.UID}-${id}` : id;
const currentPage = getCurrentPage(location, id);

return [
dispatch(
getQueryStringResults(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,14 @@ export default function withQuerystringResults(WrappedComponent) {
// save the path so it won't trigger dispatch on eager router location change
const [initialPath] = React.useState(getBaseUrl(path));

const copyFields = ['limit', 'query', 'sort_on', 'sort_order', 'depth'];
const copyFields = [
'limit',
'query',
'sort_on',
'sort_order',
'depth',
'facets',
];
const { currentPage, setCurrentPage } = usePagination(id, 1);
const adaptedQuery = Object.assign(
variation?.fullobjects ? { fullobjects: 1 } : { metadata_fields: '_all' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import config from '@plone/volto/registry';

import { SearchBlockViewComponent } from './SearchBlockView';
import Schema from './schema';
import { withSearch, withQueryString } from './hocs';
import { withSearch, withQueryString, withFacetsCount } from './hocs';
import { cloneDeep } from 'lodash';

const messages = defineMessages({
Expand Down Expand Up @@ -99,4 +99,8 @@ const SearchBlockEdit = (props) => {
);
};

export default compose(withQueryString, withSearch())(SearchBlockEdit);
export default compose(
withQueryString,
withFacetsCount,
withSearch(),
)(SearchBlockEdit);
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { withBlockExtensions } from '@plone/volto/helpers';

import config from '@plone/volto/registry';

import { withSearch, withQueryString } from './hocs';
import { withSearch, withQueryString, withFacetsCount } from './hocs';
import { compose } from 'redux';
import { useSelector } from 'react-redux';
import { isEqual, isFunction } from 'lodash';
Expand Down Expand Up @@ -106,4 +106,6 @@ export const SearchBlockViewComponent = compose(
(Component) => React.memo(Component, blockPropsAreChanged),
)(SearchBlockView);

export default withSearch()(withQueryString(SearchBlockViewComponent));
export default withSearch()(
withQueryString(withFacetsCount(SearchBlockViewComponent)),
);
Original file line number Diff line number Diff line change
Expand Up @@ -11,42 +11,83 @@ import {
* filtering
*/
const CheckboxFacet = (props) => {
const { facet, choices, isMulti, onChange, value, isEditMode } = props;
const {
facet,
facetCount,
choices,
isMulti,
onChange,
value,
isEditMode,
isFacetCountEnabled,
} = props;
const facetValue = value;

return (
<div className="checkbox-facet">
<Header as="h4">{facet.title ?? facet?.field?.label}</Header>
<div className="entries">
{choices.map(({ label, value }, i) => (
<div className="entry" key={value}>
<Checkbox
disabled={isEditMode}
label={label}
radio={!isMulti}
checked={
isMulti
? !!facetValue?.find((f) => f.value === value)
: facetValue && facetValue.value === value
}
onChange={(e, { checked }) =>
onChange(
facet.field.value,
isMulti
? [
...facetValue
.filter((f) => f.value !== value)
.map((f) => f.value),
...(checked ? [value] : []),
]
: checked
? value
: null,
)
}
/>
</div>
))}
{choices.map(({ label, value }, i) => {
const count = facetCount?.data?.[value] || 0;

return (
<div className="entry" key={value}>
{isFacetCountEnabled === true ? (
<Checkbox
disabled={isEditMode}
label={`${label} (${count})`}
radio={!isMulti}
checked={
isMulti
? !!facetValue?.find((f) => f.value === value)
: facetValue && facetValue.value === value
}
onChange={(e, { checked }) =>
onChange(
facet.field.value,
isMulti
? [
...facetValue
.filter((f) => f.value !== value)
.map((f) => f.value),
...(checked ? [value] : []),
]
: checked
? value
: null,
)
}
/>
) : (
<Checkbox
disabled={isEditMode}
label={label}
radio={!isMulti}
checked={
isMulti
? !!facetValue?.find((f) => f.value === value)
: facetValue && facetValue.value === value
}
onChange={(e, { checked }) =>
onChange(
facet.field.value,
isMulti
? [
...facetValue
.filter((f) => f.value !== value)
.map((f) => f.value),
...(checked ? [value] : []),
]
: checked
? value
: null,
)
}
/>
)}
</div>
);
})}
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ const Facets = (props) => {
const isAdvanced = facetSettings?.advanced;
const index = querystring.indexes[field] || {};
const { values = {} } = index;
const isFacetCountEnabled = props.facetsCount ? true : false;
const facetCount =
props.facetsCount?.[facetSettings?.field?.value] || 0;

let choices = Object.keys(values)
.map((name) => ({
Expand Down Expand Up @@ -124,7 +127,17 @@ const Facets = (props) => {
>
<FacetWidget
facet={facetSettings}
choices={rewriteOptions(facetSettings?.field?.value, choices)}
facetCount={facetCount}
isFacetCountEnabled={isFacetCountEnabled}
choices={rewriteOptions(
facetSettings?.field?.value,
choices,
).filter(({ _, value }) => {
if (isFacetCountEnabled === false) return true;
return Object.keys(facetCount?.data || {}).find(
(key) => key === value,
);
})}
isMulti={isMulti}
value={value}
isEditMode={isEditMode}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,76 @@ import {
} from './base';

const SelectFacet = (props) => {
const { facet, choices, reactSelect, isMulti, onChange, value, isEditMode } =
props;
const {
facet,
facetCount,
choices,
reactSelect,
isMulti,
onChange,
value,
isEditMode,
isFacetCountEnabled,
} = props;
const Select = reactSelect.default;
const v = Array.isArray(value) && value.length === 0 ? null : value;

return (
<Select
placeholder={facet?.title ?? (facet?.field?.label || 'select...')}
className="react-select-container"
classNamePrefix="react-select"
options={choices}
styles={customSelectStyles}
theme={selectTheme}
components={{ DropdownIndicator, Option, MultiValueContainer }}
isDisabled={isEditMode}
onChange={(data) => {
if (data) {
onChange(
facet.field.value,
isMulti ? data.map(({ value }) => value) : data.value,
);
} else {
// data has been removed
onChange(facet.field.value, isMulti ? [] : '');
}
}}
isMulti={facet.multiple}
isClearable
value={v}
/>
);
if (isFacetCountEnabled)
return (
<Select
placeholder={facet?.title ?? (facet?.field?.label || 'select...')}
className="react-select-container"
classNamePrefix="react-select"
options={choices}
styles={customSelectStyles}
theme={selectTheme}
components={{ DropdownIndicator, Option, MultiValueContainer }}
isDisabled={isEditMode}
onChange={(data) => {
if (data) {
onChange(
facet.field.value,
isMulti ? data.map(({ value }) => value) : data.value,
);
} else {
// data has been removed
onChange(facet.field.value, isMulti ? [] : '');
}
}}
isMulti={facet.multiple}
isClearable
value={v}
getOptionLabel={({ label, value }) => {
return `${label} (${facetCount?.data?.[value] || 0})`;
}}
/>
);
else
return (
<Select
placeholder={facet?.title ?? (facet?.field?.label || 'select...')}
className="react-select-container"
classNamePrefix="react-select"
options={choices}
styles={customSelectStyles}
theme={selectTheme}
components={{ DropdownIndicator, Option, MultiValueContainer }}
isDisabled={isEditMode}
onChange={(data) => {
if (data) {
onChange(
facet.field.value,
isMulti ? data.map(({ value }) => value) : data.value,
);
} else {
// data has been removed
onChange(facet.field.value, isMulti ? [] : '');
}
}}
isMulti={facet.multiple}
isClearable
value={v}
/>
);
};

SelectFacet.schemaEnhancer = selectFacetSchemaEnhancer;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as withFacetsCount } from './withFacetsCount';
export { default as withQueryString } from './withQueryString';
export { default as withSearch } from './withSearch';
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { useSelector } from 'react-redux';

function getDisplayName(WrappedComponent) {
return WrappedComponent.displayName || WrappedComponent.name || 'Component';
}

/**
* A HOC that injects querystring metadata information from the backend.
*
*/
export default function withFacetsCount(WrappedComponent) {
function WithFacetsCount(props) {
const { id } = props;

const facetsCount = useSelector((state) => {
return state.querystringsearch.subrequests[id]?.facets_count;
});

return <WrappedComponent {...props} facetsCount={facetsCount} />;
}
WithFacetsCount.displayName = `WithFacetsCount(${getDisplayName(
WrappedComponent,
)})`;
return WithFacetsCount;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const SEARCH_ENDPOINT_FIELDS = [
'limit',
'sort_on',
'sort_order',
'facets',
];

const PAQO = 'plone.app.querystring.operation';
Expand All @@ -42,7 +43,12 @@ function getInitialState(

return {
query: [
...(data.query?.query || []),
...(data.query?.query.map((q) => {
return {
...q,
mandatory: true,
};
}) || []),
...(facetSettings || [])
.map((facet) => {
if (!facet?.field) return null;
Expand Down Expand Up @@ -73,6 +79,7 @@ function getInitialState(
sort_order: sortOrderParam || data.query?.sort_order,
b_size: data.query?.b_size,
limit: data.query?.limit,
facets: (data?.facets || []).map((facet) => facet?.field?.value),
block: id,
};
}
Expand Down Expand Up @@ -126,6 +133,7 @@ function normalizeState({
return valueToQuery({ value, facet });
}),
].filter((o) => !!o),
facets: configuredFacets,
sort_on: sortOn || query.sort_on,
sort_order: sortOrder || query.sort_order,
b_size: query.b_size,
Expand Down Expand Up @@ -447,7 +455,6 @@ const withSearch = (options) => (WrappedComponent) => {
);
const totalItems =
querystringResults[id]?.total || querystringResults[id]?.items?.length;

return (
<WrappedComponent
{...props}
Expand Down