mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-31 17:38:48 +00:00
[ADF-4083] search facetFields - empty spaced labels support (#4322)
* [ADF-4083] ignore wrapping quotes for facet labels - bucket selection needs fixing * [ADF-4083] fix bucket selection - generate missing filterQuery values * [ADF-4083] fix label display * [ADF-4083] renaming * [ADF-4083] support also single quotes label wrappings - update documentation - tests * [ADF-4083] automatically escape facet field labels having spaces - better fix * [ADF-4083] remove unneeded mentions from documentation * [ADF-4083] clean-up code * [ADF-4083] better naming param * [ADF-4083] small refactoring
This commit is contained in:
committed by
Eugenio Romano
parent
877c57b356
commit
bfec78aec9
@@ -66,7 +66,7 @@ A typical configuration is shown below:
|
|||||||
"expanded": true,
|
"expanded": true,
|
||||||
"fields": [
|
"fields": [
|
||||||
{ "field": "content.mimetype", "mincount": 1, "label": "Type" },
|
{ "field": "content.mimetype", "mincount": 1, "label": "Type" },
|
||||||
{ "field": "content.size", "mincount": 1, "label": "Size" },
|
{ "field": "content.size", "mincount": 1, "label": "File Size" },
|
||||||
{ "field": "creator", "mincount": 1, "label": "Creator" },
|
{ "field": "creator", "mincount": 1, "label": "Creator" },
|
||||||
{ "field": "modifier", "mincount": 1, "label": "Modifier" }
|
{ "field": "modifier", "mincount": 1, "label": "Modifier" }
|
||||||
]
|
]
|
||||||
@@ -254,13 +254,16 @@ export interface SearchWidgetSettings {
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"search": {
|
"search": {
|
||||||
"facetFields": [
|
"facetFields": {
|
||||||
{ "field": "content.mimetype", "mincount": 1, "label": "Type" },
|
"expanded": true,
|
||||||
{ "field": "content.size", "mincount": 1, "label": "Size" },
|
"fields": [
|
||||||
{ "field": "creator", "mincount": 1, "label": "Creator" },
|
{ "field": "content.mimetype", "mincount": 1, "label": "Type" },
|
||||||
{ "field": "modifier", "mincount": 1, "label": "Modifier" },
|
{ "field": "content.size", "mincount": 1, "label": "File Size" },
|
||||||
{ "field": "created", "mincount": 1, "label": "Created" }
|
{ "field": "creator", "mincount": 1, "label": "Creator" },
|
||||||
]
|
{ "field": "modifier", "mincount": 1, "label": "Modifier" },
|
||||||
|
{ "field": "created", "mincount": 1, "label": "Created" }
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -268,7 +271,7 @@ export interface SearchWidgetSettings {
|
|||||||
Every field declared within the `facetFields` group is presented by a separate collapsible category at runtime.
|
Every field declared within the `facetFields` group is presented by a separate collapsible category at runtime.
|
||||||
|
|
||||||
By default, users see only the top 5 entries.
|
By default, users see only the top 5 entries.
|
||||||
If there are more than 5 entries, the "Show more" button is displayed to let the user move to
|
If there are more than 5 entries, a button to show more items is displayed to let the user move to
|
||||||
the next block of results.
|
the next block of results.
|
||||||
|
|
||||||

|

|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 38 KiB |
@@ -192,7 +192,7 @@ export class SearchFilterComponent implements OnInit, OnDestroy {
|
|||||||
private parseFacetItems(context: ResultSetContext, configFacetFields, itemType): FacetField[] {
|
private parseFacetItems(context: ResultSetContext, configFacetFields, itemType): FacetField[] {
|
||||||
return configFacetFields.map((field) => {
|
return configFacetFields.map((field) => {
|
||||||
const responseField = (context.facets || []).find((response) => response.type === itemType && response.label === field.label) || {};
|
const responseField = (context.facets || []).find((response) => response.type === itemType && response.label === field.label) || {};
|
||||||
const responseBuckets = this.getResponseBuckets(responseField)
|
const responseBuckets = this.getResponseBuckets(responseField, field)
|
||||||
.filter(this.getFilterByMinCount(field.mincount));
|
.filter(this.getFilterByMinCount(field.mincount));
|
||||||
|
|
||||||
const bucketList = new SearchFilterList<FacetFieldBucket>(responseBuckets, field.pageSize);
|
const bucketList = new SearchFilterList<FacetFieldBucket>(responseBuckets, field.pageSize);
|
||||||
@@ -270,10 +270,11 @@ export class SearchFilterComponent implements OnInit, OnDestroy {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getResponseBuckets(responseField: GenericFacetResponse): FacetFieldBucket[] {
|
private getResponseBuckets(responseField: GenericFacetResponse, configField: FacetField): FacetFieldBucket[] {
|
||||||
return ((responseField && responseField.buckets) || []).map((respBucket) => {
|
return ((responseField && responseField.buckets) || []).map((respBucket) => {
|
||||||
|
|
||||||
respBucket['count'] = this.getCountValue(respBucket);
|
respBucket['count'] = this.getCountValue(respBucket);
|
||||||
|
respBucket.filterQuery = respBucket.filterQuery || this.getCorrespondingFilterQuery(configField, respBucket.label);
|
||||||
return <FacetFieldBucket> {
|
return <FacetFieldBucket> {
|
||||||
...respBucket,
|
...respBucket,
|
||||||
checked: false,
|
checked: false,
|
||||||
@@ -312,4 +313,11 @@ export class SearchFilterComponent implements OnInit, OnDestroy {
|
|||||||
return bucket.count >= mincount;
|
return bucket.count >= mincount;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getCorrespondingFilterQuery (configFacetItem: FacetField, bucketLabel: string): string {
|
||||||
|
if (!configFacetItem.field || !bucketLabel) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return `${configFacetItem.field}:"${bucketLabel}"`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -216,6 +216,20 @@ describe('SearchQueryBuilder', () => {
|
|||||||
expect(field).toBeFalsy();
|
expect(field).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should fetch facets from the config by label with spaces and return field with request compatible label (escaped)', () => {
|
||||||
|
const config: SearchConfiguration = {
|
||||||
|
categories: [],
|
||||||
|
facetFields: { 'fields': [
|
||||||
|
{ 'field': 'content.size', 'mincount': 1, 'label': 'Label with spaces' }
|
||||||
|
]}
|
||||||
|
};
|
||||||
|
const builder = new SearchQueryBuilderService(buildConfig(config), null);
|
||||||
|
const field = builder.getFacetField('Label with spaces');
|
||||||
|
|
||||||
|
expect(field.label).toBe('"Label with spaces"');
|
||||||
|
expect(field.field).toBe('content.size');
|
||||||
|
});
|
||||||
|
|
||||||
xit('should build query and raise an event on update', async () => {
|
xit('should build query and raise an event on update', async () => {
|
||||||
const builder = new SearchQueryBuilderService(buildConfig({}), null);
|
const builder = new SearchQueryBuilderService(buildConfig({}), null);
|
||||||
const query = {};
|
const query = {};
|
||||||
@@ -371,6 +385,35 @@ describe('SearchQueryBuilder', () => {
|
|||||||
expect(compiled.facetFields.facets).toEqual(jasmine.objectContaining(config.facetFields.fields));
|
expect(compiled.facetFields.facets).toEqual(jasmine.objectContaining(config.facetFields.fields));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should build query with custom facet fields automatically getting their request compatible labels', () => {
|
||||||
|
const spacesLabel = {
|
||||||
|
configValue: 'label with spaces',
|
||||||
|
requestCompatibleValue: '"label with spaces"'
|
||||||
|
};
|
||||||
|
const noSpacesLabel = {
|
||||||
|
configValue: 'label',
|
||||||
|
requestCompatibleValue: 'label'
|
||||||
|
};
|
||||||
|
|
||||||
|
const config: SearchConfiguration = {
|
||||||
|
categories: [
|
||||||
|
<any> { id: 'cat1', enabled: true }
|
||||||
|
],
|
||||||
|
facetFields: { fields: [
|
||||||
|
{ field: 'field1', label: spacesLabel.configValue, mincount: 1, limit: null, offset: 0, prefix: null },
|
||||||
|
{ field: 'field2', label: noSpacesLabel.configValue, mincount: 1, limit: null, offset: 0, prefix: null }
|
||||||
|
]}
|
||||||
|
};
|
||||||
|
const builder = new SearchQueryBuilderService(buildConfig(config), null);
|
||||||
|
builder.queryFragments['cat1'] = 'cm:name:test';
|
||||||
|
|
||||||
|
const compiled = builder.buildQuery();
|
||||||
|
expect(compiled.facetFields.facets[0].label).toEqual(spacesLabel.requestCompatibleValue);
|
||||||
|
expect(compiled.facetFields.facets[0].label).not.toEqual(spacesLabel.configValue);
|
||||||
|
expect(compiled.facetFields.facets[1].label).toEqual(noSpacesLabel.requestCompatibleValue);
|
||||||
|
expect(compiled.facetFields.facets[1].label).toEqual(noSpacesLabel.configValue);
|
||||||
|
});
|
||||||
|
|
||||||
it('should build query with custom facet intervals', () => {
|
it('should build query with custom facet intervals', () => {
|
||||||
const config: SearchConfiguration = {
|
const config: SearchConfiguration = {
|
||||||
categories: [
|
categories: [
|
||||||
|
@@ -175,6 +175,7 @@ export class SearchQueryBuilderService {
|
|||||||
const fields = this.config.facetFields.fields || [];
|
const fields = this.config.facetFields.fields || [];
|
||||||
const result = fields.find((field) => field.label === label);
|
const result = fields.find((field) => field.label === label);
|
||||||
if (result) {
|
if (result) {
|
||||||
|
result.label = this.getSupportedLabel(result.label);
|
||||||
return { ...result };
|
return { ...result };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,6 +353,7 @@ export class SearchQueryBuilderService {
|
|||||||
if (this.userFacetBuckets) {
|
if (this.userFacetBuckets) {
|
||||||
Object.keys(this.userFacetBuckets).forEach((key) => {
|
Object.keys(this.userFacetBuckets).forEach((key) => {
|
||||||
const subQuery = (this.userFacetBuckets[key] || [])
|
const subQuery = (this.userFacetBuckets[key] || [])
|
||||||
|
.filter((bucket) => bucket.filterQuery)
|
||||||
.map((bucket) => bucket.filterQuery)
|
.map((bucket) => bucket.filterQuery)
|
||||||
.join(' OR ');
|
.join(' OR ');
|
||||||
if (subQuery) {
|
if (subQuery) {
|
||||||
@@ -374,7 +376,7 @@ export class SearchQueryBuilderService {
|
|||||||
facets: facetFields.map((facet) => <RequestFacetField> {
|
facets: facetFields.map((facet) => <RequestFacetField> {
|
||||||
field: facet.field,
|
field: facet.field,
|
||||||
mincount: facet.mincount,
|
mincount: facet.mincount,
|
||||||
label: facet.label,
|
label: this.getSupportedLabel(facet.label),
|
||||||
limit: facet.limit,
|
limit: facet.limit,
|
||||||
offset: facet.offset,
|
offset: facet.offset,
|
||||||
prefix: facet.prefix
|
prefix: facet.prefix
|
||||||
@@ -384,4 +386,12 @@ export class SearchQueryBuilderService {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSupportedLabel(configLabel: string): string {
|
||||||
|
const spaceInsideLabelIndex = configLabel.search(/\s/g);
|
||||||
|
if (spaceInsideLabelIndex > -1) {
|
||||||
|
return `"${configLabel}"`;
|
||||||
|
}
|
||||||
|
return configLabel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user