mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[ADF-5417] Support multiple search configuration in app config json (#7096)
* [ACS-1642] Support multiple search configuration in app config json * [ci:force] unit test added * adf component added * [ci:force] check compatibility * [ci:force] * run all e2e * * revert initvalue * [ci:force] revert app config * [ci:force] docs update
This commit is contained in:
@@ -349,5 +349,8 @@
|
||||
"PROCESS_ID": "Process Instance ID",
|
||||
"ACTION_TYPE": "Action Type"
|
||||
}
|
||||
},
|
||||
"SEARCH_FORMS": {
|
||||
"ALL": "All"
|
||||
}
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@
|
||||
"copyright": "© 2016 - 2021 Alfresco Software, Inc. All Rights Reserved."
|
||||
},
|
||||
"notifications": true,
|
||||
"search": {
|
||||
"search": [{
|
||||
"filterWithContains": true,
|
||||
"app:fields": [
|
||||
"cm:name",
|
||||
@@ -365,8 +365,10 @@
|
||||
"postfix": ")"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
},
|
||||
"name": "SEARCH_FORMS.ALL",
|
||||
"default": true
|
||||
}],
|
||||
"search-headers": {
|
||||
"filterWithContains": true,
|
||||
"app:fields": [
|
||||
|
@@ -9,6 +9,8 @@
|
||||
<mat-progress-bar *ngIf="isLoading" color="primary" mode="indeterminate"></mat-progress-bar>
|
||||
<div class="app-search-results__sorting">
|
||||
<adf-search-sorting-picker></adf-search-sorting-picker>
|
||||
|
||||
<adf-search-form (formChange)="onFormChange($event)"></adf-search-form>
|
||||
</div>
|
||||
<app-files-component
|
||||
[showHeader]="false"
|
||||
|
@@ -16,7 +16,9 @@
|
||||
}
|
||||
|
||||
&__sorting {
|
||||
text-align: right;
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -15,12 +15,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, OnInit, Optional, OnDestroy } from '@angular/core';
|
||||
import { Router, ActivatedRoute, Params } from '@angular/router';
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||
import { Pagination, ResultSetPaging } from '@alfresco/js-api';
|
||||
import { SearchQueryBuilderService } from '@alfresco/adf-content-services';
|
||||
import { UserPreferencesService, SearchService, AppConfigService } from '@alfresco/adf-core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { SearchForm, SearchQueryBuilderService } from '@alfresco/adf-content-services';
|
||||
import { SearchService, UserPreferencesService } from '@alfresco/adf-core';
|
||||
import { combineLatest, Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
@@ -38,14 +38,24 @@ export class SearchResultComponent implements OnInit, OnDestroy {
|
||||
isLoading = true;
|
||||
|
||||
sorting = ['name', 'asc'];
|
||||
searchForms: SearchForm[];
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(public router: Router,
|
||||
private config: AppConfigService,
|
||||
private preferences: UserPreferencesService,
|
||||
private queryBuilder: SearchQueryBuilderService,
|
||||
@Optional() private route: ActivatedRoute) {
|
||||
private route: ActivatedRoute) {
|
||||
combineLatest([this.route.params, this.queryBuilder.configUpdated])
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(([params, searchConfig]) => {
|
||||
this.searchedWord = params.hasOwnProperty(this.queryParamName) ? params[this.queryParamName] : null;
|
||||
const query = this.formatSearchQuery(this.searchedWord, searchConfig['app:fields']);
|
||||
if (query) {
|
||||
this.queryBuilder.userQuery = query;
|
||||
}
|
||||
});
|
||||
|
||||
queryBuilder.paging = {
|
||||
maxItems: this.preferences.paginationSize,
|
||||
skipCount: 0
|
||||
@@ -76,10 +86,7 @@ export class SearchResultComponent implements OnInit, OnDestroy {
|
||||
if (this.route) {
|
||||
this.route.params.forEach((params: Params) => {
|
||||
this.searchedWord = params.hasOwnProperty(this.queryParamName) ? params[this.queryParamName] : null;
|
||||
const query = this.formatSearchQuery(this.searchedWord);
|
||||
|
||||
if (query) {
|
||||
this.queryBuilder.userQuery = query;
|
||||
if (this.searchedWord) {
|
||||
this.queryBuilder.update();
|
||||
} else {
|
||||
this.queryBuilder.userQuery = null;
|
||||
@@ -94,15 +101,11 @@ export class SearchResultComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
private formatSearchQuery(userInput: string) {
|
||||
private formatSearchQuery(userInput: string, fields = ['cm:name']) {
|
||||
if (!userInput) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const fields = this.config.get<string[]>('search.app:fields', ['cm:name']);
|
||||
const query = fields.map((field) => `${field}:"${userInput}*"`).join(' OR ');
|
||||
|
||||
return query;
|
||||
return fields.map((field) => `${field}:"${userInput}*"`).join(' OR ');
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@@ -136,4 +139,8 @@ export class SearchResultComponent implements OnInit, OnDestroy {
|
||||
|
||||
return ['name', 'asc'];
|
||||
}
|
||||
|
||||
onFormChange(form: SearchForm) {
|
||||
this.queryBuilder.updateSelectedConfiguration(form.index);
|
||||
}
|
||||
}
|
||||
|
75
docs/content-services/components/search-form.component.md
Normal file
75
docs/content-services/components/search-form.component.md
Normal file
@@ -0,0 +1,75 @@
|
||||
---
|
||||
Title: Search Form component
|
||||
Added: v4.5.0
|
||||
Status: Active
|
||||
Last reviewed: 2021-06-11
|
||||
---
|
||||
|
||||
# [Search Form component](../../../lib/content-services/src/lib/search/components/search-form/search-form.component.ts "Defined in search-form.component.ts")
|
||||
|
||||
Selecting a configuration from a set of configured options.
|
||||
|
||||

|
||||
|
||||
## Basic usage
|
||||
|
||||
```json
|
||||
{
|
||||
"search": [
|
||||
{
|
||||
"categories": [
|
||||
{
|
||||
"id": "queryName",
|
||||
"name": "Name",
|
||||
"enabled": true,
|
||||
"expanded": true,
|
||||
"component": {
|
||||
"selector": "text",
|
||||
"settings": {
|
||||
"searchPrefix": "",
|
||||
"searchSuffix": "",
|
||||
"pattern": "cm:name:'(.*?)'",
|
||||
"field": "cm:name",
|
||||
"placeholder": "Enter the name",
|
||||
"allowUpdateOnChange": true
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "ALL",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"categories": [
|
||||
{
|
||||
"id": "queryName",
|
||||
"name": "Name",
|
||||
"enabled": true,
|
||||
"expanded": true,
|
||||
"component": {
|
||||
"selector": "text",
|
||||
"settings": {
|
||||
"searchPrefix": "",
|
||||
"searchSuffix": "",
|
||||
"pattern": "cm:name:'(.*?)'",
|
||||
"field": "cm:name",
|
||||
"placeholder": "Enter the name",
|
||||
"allowUpdateOnChange": true
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"name": "Other"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Details
|
||||
|
||||
This component lets the user pick a configuration for a search.
|
||||
|
||||
## See also
|
||||
|
||||
- [Search Query Builder](../services/search-query-builder.service.md)
|
BIN
docs/docassets/images/search-form-component.png
Normal file
BIN
docs/docassets/images/search-form-component.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { SearchCategory } from '../search/search-category.interface';
|
||||
import { SearchCategory } from '../search/models/search-category.interface';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
@@ -57,7 +57,7 @@ import { ContentActionModel } from './../models/content-action.model';
|
||||
import { PermissionStyleModel } from './../models/permissions-style.model';
|
||||
import { NodeEntityEvent, NodeEntryEvent } from './node.event';
|
||||
import { NavigableComponentInterface } from '../../breadcrumb/navigable-component.interface';
|
||||
import { FilterSearch } from './../../search/filter-search.interface';
|
||||
import { FilterSearch } from './../../search/models/filter-search.interface';
|
||||
import { RowFilter } from '../data/row-filter.model';
|
||||
import { DocumentListService } from '../services/document-list.service';
|
||||
import { DocumentLoaderNode } from '../models/document-folder.model';
|
||||
|
@@ -20,7 +20,7 @@ import { PaginationModel, DataSorting } from '@alfresco/adf-core';
|
||||
import { DocumentListComponent } from '../document-list.component';
|
||||
import { SEARCH_QUERY_SERVICE_TOKEN } from '../../../search/search-query-service.token';
|
||||
import { SearchHeaderQueryBuilderService } from '../../../search/search-header-query-builder.service';
|
||||
import { FilterSearch } from './../../../search/filter-search.interface';
|
||||
import { FilterSearch } from './../../../search/models/filter-search.interface';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { NodePaging, MinimalNode } from '@alfresco/js-api';
|
||||
|
@@ -290,6 +290,8 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"FORMS": "Search Forms",
|
||||
"UNKNOWN_FORM": "Unknown Configuration",
|
||||
"SEARCH_HEADER" : {
|
||||
"TITLE":"Filter",
|
||||
"TYPE": "Type",
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SearchCategory } from '../search/search-category.interface';
|
||||
import { SearchCategory } from '../search/models/search-category.interface';
|
||||
|
||||
export const mockContentModelTextProperty = {
|
||||
name: 'name',
|
||||
|
@@ -27,24 +27,31 @@ import {
|
||||
RequestHighlight,
|
||||
RequestScope
|
||||
} from '@alfresco/js-api';
|
||||
import { SearchCategory } from './search-category.interface';
|
||||
import { FilterQuery } from './filter-query.interface';
|
||||
import { SearchRange } from './search-range.interface';
|
||||
import { SearchConfiguration } from './search-configuration.interface';
|
||||
import { FacetQuery } from './facet-query.interface';
|
||||
import { SearchSortingDefinition } from './search-sorting-definition.interface';
|
||||
import { FacetField } from './facet-field.interface';
|
||||
import { FacetFieldBucket } from './facet-field-bucket.interface';
|
||||
import { SearchCategory } from './models/search-category.interface';
|
||||
import { FilterQuery } from './models/filter-query.interface';
|
||||
import { SearchRange } from './models/search-range.interface';
|
||||
import { SearchConfiguration } from './models/search-configuration.interface';
|
||||
import { FacetQuery } from './models/facet-query.interface';
|
||||
import { SearchSortingDefinition } from './models/search-sorting-definition.interface';
|
||||
import { FacetField } from './models/facet-field.interface';
|
||||
import { FacetFieldBucket } from './models/facet-field-bucket.interface';
|
||||
import { SearchForm } from './models/search-form.interface';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export abstract class BaseQueryBuilderService {
|
||||
|
||||
private _userQuery = '';
|
||||
/* Stream that emits the search configuration whenever the user change the search forms */
|
||||
configUpdated = new Subject<SearchConfiguration>();
|
||||
|
||||
/* Stream that emits the query before search whenever user search */
|
||||
updated = new Subject<QueryBody>();
|
||||
|
||||
/* Stream that emits the results whenever user search */
|
||||
executed = new Subject<ResultSetPaging>();
|
||||
|
||||
/* Stream that emits the error whenever user search */
|
||||
error = new Subject();
|
||||
|
||||
categories: SearchCategory[] = [];
|
||||
@@ -54,6 +61,8 @@ export abstract class BaseQueryBuilderService {
|
||||
sorting: SearchSortingDefinition[] = [];
|
||||
sortingOptions: SearchSortingDefinition[] = [];
|
||||
private scope: RequestScope;
|
||||
private selectedConfiguration: number;
|
||||
private _userQuery = '';
|
||||
|
||||
protected userFacetBuckets: { [key: string]: FacetFieldBucket[] } = {};
|
||||
|
||||
@@ -77,15 +86,62 @@ export abstract class BaseQueryBuilderService {
|
||||
this.resetToDefaults();
|
||||
}
|
||||
|
||||
public abstract loadConfiguration(): SearchConfiguration;
|
||||
public abstract loadConfiguration(): SearchConfiguration | SearchConfiguration[];
|
||||
|
||||
public abstract isFilterServiceActive(): boolean;
|
||||
|
||||
public resetToDefaults() {
|
||||
const currentConfig = this.loadConfiguration();
|
||||
const currentConfig = this.getDefaultConfiguration();
|
||||
this.configUpdated.next(currentConfig);
|
||||
this.setUpSearchConfiguration(currentConfig);
|
||||
}
|
||||
|
||||
public getDefaultConfiguration(): SearchConfiguration | undefined {
|
||||
const configurations = this.loadConfiguration();
|
||||
|
||||
if (this.selectedConfiguration >= 0) {
|
||||
return configurations[this.selectedConfiguration];
|
||||
}
|
||||
|
||||
if (Array.isArray(configurations)) {
|
||||
return configurations.find((configuration) => configuration.default);
|
||||
}
|
||||
return configurations;
|
||||
}
|
||||
|
||||
public updateSelectedConfiguration(index: number): void {
|
||||
const currentConfig = this.loadConfiguration();
|
||||
if (Array.isArray(currentConfig) && currentConfig[index] !== undefined) {
|
||||
this.configUpdated.next(currentConfig[index]);
|
||||
this.selectedConfiguration = index;
|
||||
this.resetSearchOptions();
|
||||
this.setUpSearchConfiguration(currentConfig[index]);
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
|
||||
private resetSearchOptions(): void {
|
||||
this.categories = [];
|
||||
this.queryFragments = {};
|
||||
this.filterQueries = [];
|
||||
this.sorting = [];
|
||||
this.sortingOptions = [];
|
||||
this.scope = null;
|
||||
}
|
||||
|
||||
public getSearchConfigurationDetails(): SearchForm[] {
|
||||
const configurations = this.loadConfiguration();
|
||||
if (Array.isArray(configurations)) {
|
||||
return configurations.map((configuration, index) => ({
|
||||
index,
|
||||
name: configuration.name || 'SEARCH.UNKNOWN_FORM',
|
||||
default: configuration.default || false,
|
||||
selected: this.selectedConfiguration !== undefined ? index === this.selectedConfiguration : configuration.default
|
||||
}));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
private setUpSearchConfiguration(currentConfiguration: SearchConfiguration) {
|
||||
if (currentConfiguration) {
|
||||
this.config = JSON.parse(JSON.stringify(currentConfiguration));
|
||||
|
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { SearchCheckListComponent, SearchListOption } from './search-check-list.component';
|
||||
import { SearchFilterList } from '../search-filter/models/search-filter-list.model';
|
||||
import { SearchFilterList } from '../../models/search-filter-list.model';
|
||||
import { setupTestBed } from '@alfresco/adf-core';
|
||||
import { ContentTestingModule } from '../../../testing/content.testing.module';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
@@ -17,10 +17,10 @@
|
||||
|
||||
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
|
||||
import { MatCheckboxChange } from '@angular/material/checkbox';
|
||||
import { SearchWidget } from '../../search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../search-widget-settings.interface';
|
||||
import { SearchWidget } from '../../models/search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
|
||||
import { SearchQueryBuilderService } from '../../search-query-builder.service';
|
||||
import { SearchFilterList } from '../search-filter/models/search-filter-list.model';
|
||||
import { SearchFilterList } from '../../models/search-filter-list.model';
|
||||
|
||||
export interface SearchListOption {
|
||||
name: string;
|
||||
|
@@ -20,8 +20,8 @@ import { FormControl, Validators, FormGroup } from '@angular/forms';
|
||||
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';
|
||||
import { MomentDateAdapter, MOMENT_DATE_FORMATS, UserPreferencesService, UserPreferenceValues } from '@alfresco/adf-core';
|
||||
|
||||
import { SearchWidget } from '../../search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../search-widget-settings.interface';
|
||||
import { SearchWidget } from '../../models/search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
|
||||
import { SearchQueryBuilderService } from '../../search-query-builder.service';
|
||||
import { LiveErrorStateMatcher } from '../../forms/live-error-state-matcher';
|
||||
import { Moment } from 'moment';
|
||||
|
@@ -19,8 +19,8 @@ import { OnInit, Component, ViewEncapsulation, OnDestroy } from '@angular/core';
|
||||
import { FormControl, Validators, FormGroup } from '@angular/forms';
|
||||
import { UserPreferencesService, UserPreferenceValues } from '@alfresco/adf-core';
|
||||
|
||||
import { SearchWidget } from '../../search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../search-widget-settings.interface';
|
||||
import { SearchWidget } from '../../models/search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
|
||||
import { SearchQueryBuilderService } from '../../search-query-builder.service';
|
||||
import { LiveErrorStateMatcher } from '../../forms/live-error-state-matcher';
|
||||
import { Moment } from 'moment';
|
||||
|
@@ -25,7 +25,7 @@ import { SEARCH_QUERY_SERVICE_TOKEN } from '../../search-query-service.token';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { SearchFilterContainerComponent } from './search-filter-container.component';
|
||||
import { MatMenuTrigger } from '@angular/material/menu';
|
||||
import { SearchCategory } from '../../search-category.interface';
|
||||
import { SearchCategory } from '../../models/search-category.interface';
|
||||
|
||||
const mockCategory: SearchCategory = {
|
||||
'id': 'queryName',
|
||||
|
@@ -31,7 +31,7 @@ import { ConfigurableFocusTrapFactory, ConfigurableFocusTrap } from '@angular/cd
|
||||
import { DataColumn, TranslationService } from '@alfresco/adf-core';
|
||||
import { SearchWidgetContainerComponent } from '../search-widget-container/search-widget-container.component';
|
||||
import { SearchHeaderQueryBuilderService } from '../../search-header-query-builder.service';
|
||||
import { SearchCategory } from '../../search-category.interface';
|
||||
import { SearchCategory } from '../../models/search-category.interface';
|
||||
import { SEARCH_QUERY_SERVICE_TOKEN } from '../../search-query-service.token';
|
||||
import { Subject } from 'rxjs';
|
||||
import { MatMenuTrigger } from '@angular/material/menu';
|
||||
|
@@ -19,9 +19,9 @@ import { SearchFilterComponent } from './search-filter.component';
|
||||
import { SearchQueryBuilderService } from '../../search-query-builder.service';
|
||||
import { AppConfigService, SearchService, setupTestBed, TranslationService } from '@alfresco/adf-core';
|
||||
import { Subject } from 'rxjs';
|
||||
import { FacetFieldBucket } from '../../facet-field-bucket.interface';
|
||||
import { FacetField } from '../../facet-field.interface';
|
||||
import { SearchFilterList } from './models/search-filter-list.model';
|
||||
import { FacetFieldBucket } from '../../models/facet-field-bucket.interface';
|
||||
import { FacetField } from '../../models/facet-field.interface';
|
||||
import { SearchFilterList } from '../../models/search-filter-list.model';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { ContentTestingModule } from '../../../testing/content.testing.module';
|
||||
|
@@ -19,9 +19,9 @@ import { Component, ViewEncapsulation, OnInit, OnDestroy, Inject, Input } from '
|
||||
import { MatCheckboxChange } from '@angular/material/checkbox';
|
||||
import { TranslationService, SearchService } from '@alfresco/adf-core';
|
||||
import { SearchQueryBuilderService } from '../../search-query-builder.service';
|
||||
import { FacetFieldBucket } from '../../facet-field-bucket.interface';
|
||||
import { FacetField } from '../../facet-field.interface';
|
||||
import { SearchFilterList } from './models/search-filter-list.model';
|
||||
import { FacetFieldBucket } from '../../models/facet-field-bucket.interface';
|
||||
import { FacetField } from '../../models/facet-field.interface';
|
||||
import { SearchFilterList } from '../../models/search-filter-list.model';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
import { GenericBucket, GenericFacetResponse, ResultSetContext, ResultSetPaging } from '@alfresco/js-api';
|
||||
import { Subject } from 'rxjs';
|
||||
|
@@ -0,0 +1,8 @@
|
||||
<mat-form-field floatLabel="always" *ngIf="searchForms.length">
|
||||
<mat-label>{{ 'SEARCH.FORMS' | translate }}</mat-label>
|
||||
<mat-select [(value)]="selected" (selectionChange)="onSelectionChange($event.value)">
|
||||
<mat-option *ngFor="let form of searchForms" [value]="form.index">
|
||||
{{form.name | translate}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
@@ -0,0 +1,91 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SearchFormComponent } from './search-form.component';
|
||||
import { setupTestBed } from '@alfresco/adf-core';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ContentTestingModule } from '../../../testing/content.testing.module';
|
||||
import { SEARCH_QUERY_SERVICE_TOKEN } from '../../search-query-service.token';
|
||||
import { SearchHeaderQueryBuilderService } from '../../search-header-query-builder.service';
|
||||
import { SearchForm } from '../../models/search-form.interface';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
describe('SearchFormComponent', () => {
|
||||
let fixture: ComponentFixture<SearchFormComponent>;
|
||||
let component: SearchFormComponent;
|
||||
let queryBuilder: SearchHeaderQueryBuilderService;
|
||||
const mockSearchForms: SearchForm[] = [
|
||||
{ default: false, index: 0, name: 'All', selected: false },
|
||||
{ default: true, index: 1, name: 'First', selected: true },
|
||||
{ default: false, index: 2, name: 'Second', selected: false }
|
||||
];
|
||||
|
||||
setupTestBed({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
],
|
||||
providers: [
|
||||
{ provide: SEARCH_QUERY_SERVICE_TOKEN, useClass: SearchHeaderQueryBuilderService }
|
||||
]
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SearchFormComponent);
|
||||
component = fixture.componentInstance;
|
||||
queryBuilder = TestBed.inject<SearchHeaderQueryBuilderService>(SEARCH_QUERY_SERVICE_TOKEN);
|
||||
spyOn(queryBuilder, 'getSearchConfigurationDetails').and.returnValue(mockSearchForms);
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should show search forms', async () => {
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
expect(component.selected).toBe(1);
|
||||
const label = fixture.debugElement.query(By.css('.mat-form-field mat-label'));
|
||||
expect(label.nativeElement.innerText).toContain('SEARCH.FORMS');
|
||||
const selectValue = fixture.debugElement.query(By.css('.mat-select-value'));
|
||||
expect(selectValue.nativeElement.innerText).toContain('First');
|
||||
});
|
||||
|
||||
it('should emit on form change', async (done) => {
|
||||
component.formChange.subscribe((form) => {
|
||||
expect(form).toEqual(mockSearchForms[2]);
|
||||
done();
|
||||
});
|
||||
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
|
||||
const matSelect = fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement;
|
||||
matSelect.click();
|
||||
fixture.detectChanges();
|
||||
|
||||
const matOption = fixture.debugElement.queryAll(By.css('.mat-option'))[2].nativeElement;
|
||||
matOption.click();
|
||||
});
|
||||
|
||||
it('should not display search form if no form configured', async () => {
|
||||
component.searchForms = [];
|
||||
await fixture.whenStable();
|
||||
fixture.detectChanges();
|
||||
const field = fixture.debugElement.query(By.css('.mat-form-field'));
|
||||
expect(field).toEqual(null, 'search form displayed for empty configuration');
|
||||
});
|
||||
});
|
@@ -0,0 +1,44 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, EventEmitter, Inject, OnInit, Output } from '@angular/core';
|
||||
import { SearchQueryBuilderService } from '../../search-query-builder.service';
|
||||
import { SearchForm } from '../../models/search-form.interface';
|
||||
import { SEARCH_QUERY_SERVICE_TOKEN } from '../../search-query-service.token';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-search-form',
|
||||
templateUrl: './search-form.component.html'
|
||||
})
|
||||
export class SearchFormComponent implements OnInit {
|
||||
@Output()
|
||||
formChange: EventEmitter<SearchForm> = new EventEmitter<SearchForm>();
|
||||
|
||||
selected: number;
|
||||
searchForms: SearchForm[] = [];
|
||||
|
||||
constructor(@Inject(SEARCH_QUERY_SERVICE_TOKEN) private queryBuilder: SearchQueryBuilderService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.searchForms = this.queryBuilder.getSearchConfigurationDetails();
|
||||
this.selected = this.searchForms.find(form => form.selected)?.index;
|
||||
}
|
||||
|
||||
onSelectionChange(index: number) {
|
||||
this.formChange.emit(this.searchForms[index]);
|
||||
}
|
||||
}
|
@@ -17,8 +17,8 @@
|
||||
|
||||
import { OnInit, Component, ViewEncapsulation } from '@angular/core';
|
||||
import { FormControl, Validators, FormGroup } from '@angular/forms';
|
||||
import { SearchWidget } from '../../search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../search-widget-settings.interface';
|
||||
import { SearchWidget } from '../../models/search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
|
||||
import { SearchQueryBuilderService } from '../../search-query-builder.service';
|
||||
import { LiveErrorStateMatcher } from '../../forms/live-error-state-matcher';
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { SearchCheckListComponent, SearchListOption } from '../search-check-list/search-check-list.component';
|
||||
import { SearchFilterList } from '../search-filter/models/search-filter-list.model';
|
||||
import { SearchFilterList } from '../../models/search-filter-list.model';
|
||||
import { setupTestBed } from '@alfresco/adf-core';
|
||||
import { ContentTestingModule } from '../../../testing/content.testing.module';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
@@ -91,8 +91,8 @@ describe('SearchRadioComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const optionElements = fixture.debugElement.query(By.css('mat-radio-button'));
|
||||
optionElements.triggerEventHandler('change', { checked: true });
|
||||
const optionElements = fixture.debugElement.query(By.css('mat-radio-group'));
|
||||
optionElements.triggerEventHandler('change', { value: sizeOptions[0].value });
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.context.update).toHaveBeenCalled();
|
||||
|
@@ -18,10 +18,10 @@
|
||||
import { Component, ViewEncapsulation, OnInit, Input } from '@angular/core';
|
||||
import { MatRadioChange } from '@angular/material/radio';
|
||||
|
||||
import { SearchWidget } from '../../search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../search-widget-settings.interface';
|
||||
import { SearchWidget } from '../../models/search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
|
||||
import { SearchQueryBuilderService } from '../../search-query-builder.service';
|
||||
import { SearchFilterList } from '../search-filter/models/search-filter-list.model';
|
||||
import { SearchFilterList } from '../../models/search-filter-list.model';
|
||||
|
||||
export interface SearchRadioOption {
|
||||
name: string;
|
||||
@@ -67,9 +67,11 @@ export class SearchRadioComponent implements SearchWidget, OnInit {
|
||||
const initialValue = this.getSelectedValue();
|
||||
|
||||
if (initialValue !== null) {
|
||||
this.setValue(initialValue);
|
||||
this.value = initialValue;
|
||||
this.context.queryFragments[this.id] = initialValue;
|
||||
} else if (this.startValue !== null) {
|
||||
this.setValue(initialValue);
|
||||
this.value = initialValue;
|
||||
this.context.queryFragments[this.id] = initialValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,8 +16,8 @@
|
||||
*/
|
||||
|
||||
import { Component, ViewEncapsulation, OnInit, Input } from '@angular/core';
|
||||
import { SearchWidget } from '../../search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../search-widget-settings.interface';
|
||||
import { SearchWidget } from '../../models/search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
|
||||
import { SearchQueryBuilderService } from '../../search-query-builder.service';
|
||||
import { MatSliderChange } from '@angular/material/slider';
|
||||
|
||||
|
@@ -18,7 +18,7 @@
|
||||
import { SearchSortingPickerComponent } from './search-sorting-picker.component';
|
||||
import { SearchQueryBuilderService } from '../../search-query-builder.service';
|
||||
import { AppConfigService } from '@alfresco/adf-core';
|
||||
import { SearchConfiguration } from '../../search-configuration.interface';
|
||||
import { SearchConfiguration } from '../../models/search-configuration.interface';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { ContentTestingModule } from '../../../testing/content.testing.module';
|
||||
|
||||
|
@@ -17,7 +17,7 @@
|
||||
|
||||
import { Component, OnInit, ViewEncapsulation, Inject } from '@angular/core';
|
||||
import { SearchQueryBuilderService } from '../../search-query-builder.service';
|
||||
import { SearchSortingDefinition } from '../../search-sorting-definition.interface';
|
||||
import { SearchSortingDefinition } from '../../models/search-sorting-definition.interface';
|
||||
import { SEARCH_QUERY_SERVICE_TOKEN } from '../../search-query-service.token';
|
||||
|
||||
@Component({
|
||||
|
@@ -16,8 +16,8 @@
|
||||
*/
|
||||
|
||||
import { Component, ViewEncapsulation, OnInit, Input } from '@angular/core';
|
||||
import { SearchWidget } from '../../search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../search-widget-settings.interface';
|
||||
import { SearchWidget } from '../../models/search-widget.interface';
|
||||
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
|
||||
import { SearchQueryBuilderService } from '../../search-query-builder.service';
|
||||
|
||||
@Component({
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SearchFilterList } from './components/search-filter/models/search-filter-list.model';
|
||||
import { SearchFilterList } from './search-filter-list.model';
|
||||
import { FacetFieldBucket } from './facet-field-bucket.interface';
|
||||
|
||||
export interface FacetField {
|
@@ -49,4 +49,6 @@ export interface SearchConfiguration {
|
||||
defaults: SearchSortingDefinition[];
|
||||
};
|
||||
highlight?: RequestHighlight;
|
||||
name?: string;
|
||||
default?: boolean;
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright 2019 Alfresco Software, Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export interface SearchForm {
|
||||
index: number;
|
||||
name: string;
|
||||
default: boolean;
|
||||
selected: boolean;
|
||||
}
|
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import { SearchWidgetSettings } from './search-widget-settings.interface';
|
||||
import { SearchQueryBuilderService } from './search-query-builder.service';
|
||||
import { SearchQueryBuilderService } from '../search-query-builder.service';
|
||||
|
||||
export interface SearchWidget {
|
||||
id: string;
|
@@ -15,17 +15,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './facet-field-bucket.interface';
|
||||
export * from './facet-field.interface';
|
||||
export * from './facet-query.interface';
|
||||
export * from './filter-query.interface';
|
||||
export * from './filter-search.interface';
|
||||
export * from './search-category.interface';
|
||||
export * from './search-widget-settings.interface';
|
||||
export * from './search-widget.interface';
|
||||
export * from './search-configuration.interface';
|
||||
export * from './models/facet-field-bucket.interface';
|
||||
export * from './models/facet-field.interface';
|
||||
export * from './models/facet-query.interface';
|
||||
export * from './models/filter-query.interface';
|
||||
export * from './models/filter-search.interface';
|
||||
export * from './models/search-category.interface';
|
||||
export * from './models/search-widget-settings.interface';
|
||||
export * from './models/search-widget.interface';
|
||||
export * from './models/search-configuration.interface';
|
||||
export * from './search-query-builder.service';
|
||||
export * from './search-range.interface';
|
||||
export * from './models/search-range.interface';
|
||||
export * from './models/search-form.interface';
|
||||
|
||||
export * from './search-query-service.token';
|
||||
export * from './search-header-query-builder.service';
|
||||
|
||||
@@ -49,5 +51,6 @@ export * from './components/search-sorting-picker/search-sorting-picker.componen
|
||||
export * from './components/search-text/search-text.component';
|
||||
export * from './components/search-widget-container/search-widget-container.component';
|
||||
export * from './components/search-datetime-range/search-datetime-range.component';
|
||||
export * from './components/search-form/search-form.component';
|
||||
|
||||
export * from './search.module';
|
||||
|
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { SearchConfiguration } from './search-configuration.interface';
|
||||
import { SearchConfiguration } from './models/search-configuration.interface';
|
||||
import { AppConfigService } from '@alfresco/adf-core';
|
||||
import { SearchHeaderQueryBuilderService } from './search-header-query-builder.service';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
@@ -17,14 +17,14 @@
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AlfrescoApiService, AppConfigService, NodesApiService, DataSorting } from '@alfresco/adf-core';
|
||||
import { SearchConfiguration } from './search-configuration.interface';
|
||||
import { SearchConfiguration } from './models/search-configuration.interface';
|
||||
import { BaseQueryBuilderService } from './base-query-builder.service';
|
||||
import { SearchCategory } from './search-category.interface';
|
||||
import { SearchCategory } from './models/search-category.interface';
|
||||
import { MinimalNode, QueryBody } from '@alfresco/js-api';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { Observable } from 'rxjs';
|
||||
import { SearchSortingDefinition } from './search-sorting-definition.interface';
|
||||
import { FilterSearch } from './filter-search.interface';
|
||||
import { SearchSortingDefinition } from './models/search-sorting-definition.interface';
|
||||
import { FilterSearch } from './models/filter-search.interface';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
@@ -16,9 +16,9 @@
|
||||
*/
|
||||
|
||||
import { SearchQueryBuilderService } from './search-query-builder.service';
|
||||
import { SearchConfiguration } from './search-configuration.interface';
|
||||
import { SearchConfiguration } from './models/search-configuration.interface';
|
||||
import { AppConfigService } from '@alfresco/adf-core';
|
||||
import { FacetField } from './facet-field.interface';
|
||||
import { FacetField } from './models/facet-field.interface';
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { ContentTestingModule } from '../testing/content.testing.module';
|
||||
|
||||
@@ -669,4 +669,91 @@ describe('SearchQueryBuilder', () => {
|
||||
|
||||
expect(queryBody.scope).toEqual(mockScope);
|
||||
});
|
||||
|
||||
it('should return empty if array of search config not found', () => {
|
||||
const builder = new SearchQueryBuilderService(buildConfig({}), null);
|
||||
const forms = builder.getSearchConfigurationDetails();
|
||||
expect(forms).toEqual([]);
|
||||
});
|
||||
|
||||
describe('Multiple search configuration', () => {
|
||||
let configs: SearchConfiguration[];
|
||||
let builder: SearchQueryBuilderService;
|
||||
beforeEach(() => {
|
||||
configs = [
|
||||
{
|
||||
categories: [
|
||||
<any> { id: 'cat1', enabled: true },
|
||||
<any> { id: 'cat2', enabled: true }
|
||||
],
|
||||
filterQueries: [
|
||||
{ query: 'query1' },
|
||||
{ query: 'query2' }
|
||||
],
|
||||
name: 'config1',
|
||||
default: true
|
||||
},
|
||||
{
|
||||
categories: [
|
||||
<any> { id: 'mouse', enabled: true }
|
||||
],
|
||||
filterQueries: [
|
||||
{ query: 'query1' },
|
||||
{ query: 'query2' }
|
||||
],
|
||||
name: 'config2',
|
||||
default: false
|
||||
},
|
||||
{
|
||||
categories: [
|
||||
<any> { id: 'cat_and_mouse', enabled: true }
|
||||
],
|
||||
default: false
|
||||
}
|
||||
];
|
||||
builder = new SearchQueryBuilderService(buildConfig(configs), null);
|
||||
});
|
||||
|
||||
it('should pick the default configuration from list', () => {
|
||||
builder.categories = [];
|
||||
builder.filterQueries = [];
|
||||
|
||||
expect(builder.categories.length).toBe(0);
|
||||
expect(builder.filterQueries.length).toBe(0);
|
||||
|
||||
builder.resetToDefaults();
|
||||
|
||||
expect(builder.categories.length).toBe(2);
|
||||
expect(builder.categories.length).toBe(2);
|
||||
expect(builder.filterQueries.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should list available search form names', () => {
|
||||
const forms = builder.getSearchConfigurationDetails();
|
||||
|
||||
expect(forms).toEqual([
|
||||
{ index: 0, name: 'config1', default: true, selected: true },
|
||||
{ index: 1, name: 'config2', default: false, selected: false },
|
||||
{ index: 2, name: 'SEARCH.UNKNOWN_FORM', default: false, selected: false }
|
||||
]);
|
||||
});
|
||||
|
||||
it('should allow the user switch the form', () => {
|
||||
builder.updateSelectedConfiguration(1);
|
||||
|
||||
expect(builder.categories.length).toBe(1);
|
||||
expect(builder.filterQueries.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should keep the selected configuration value', () => {
|
||||
builder.updateSelectedConfiguration(1);
|
||||
const forms = builder.getSearchConfigurationDetails();
|
||||
|
||||
expect(forms).toEqual([
|
||||
{ index: 0, name: 'config1', default: true, selected: false },
|
||||
{ index: 1, name: 'config2', default: false, selected: true },
|
||||
{ index: 2, name: 'SEARCH.UNKNOWN_FORM', default: false, selected: false }
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -17,7 +17,7 @@
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AlfrescoApiService, AppConfigService } from '@alfresco/adf-core';
|
||||
import { SearchConfiguration } from './search-configuration.interface';
|
||||
import { SearchConfiguration } from './models/search-configuration.interface';
|
||||
import { BaseQueryBuilderService } from './base-query-builder.service';
|
||||
|
||||
@Injectable()
|
||||
|
@@ -40,6 +40,7 @@ import { SEARCH_QUERY_SERVICE_TOKEN } from './search-query-service.token';
|
||||
import { SearchQueryBuilderService } from './search-query-builder.service';
|
||||
import { SearchFilterContainerComponent } from './components/search-filter-container/search-filter-container.component';
|
||||
import { SearchDatetimeRangeComponent } from './components/search-datetime-range/search-datetime-range.component';
|
||||
import { SearchFormComponent } from './components/search-form/search-form.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -65,7 +66,8 @@ import { SearchDatetimeRangeComponent } from './components/search-datetime-range
|
||||
SearchDateRangeComponent,
|
||||
SearchDatetimeRangeComponent,
|
||||
SearchSortingPickerComponent,
|
||||
SearchFilterContainerComponent
|
||||
SearchFilterContainerComponent,
|
||||
SearchFormComponent
|
||||
],
|
||||
exports: [
|
||||
SearchComponent,
|
||||
@@ -83,7 +85,8 @@ import { SearchDatetimeRangeComponent } from './components/search-datetime-range
|
||||
SearchDateRangeComponent,
|
||||
SearchDatetimeRangeComponent,
|
||||
SearchSortingPickerComponent,
|
||||
SearchFilterContainerComponent
|
||||
SearchFilterContainerComponent,
|
||||
SearchFormComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: SEARCH_QUERY_SERVICE_TOKEN, useExisting: SearchQueryBuilderService },
|
||||
|
@@ -498,6 +498,404 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"search-configuration": {
|
||||
"description": "Search configuration parameters",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"categories"
|
||||
],
|
||||
"properties": {
|
||||
"include": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"filterQueries": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"query"
|
||||
],
|
||||
"properties": {
|
||||
"query": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"filterWithContains": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"resetButton": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"facetFields": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"fields"
|
||||
],
|
||||
"properties": {
|
||||
"expanded": {
|
||||
"description": "Toggles expanded state of the facet field",
|
||||
"type": "boolean"
|
||||
},
|
||||
"fields": {
|
||||
"description": "List of custom facet fields",
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"field",
|
||||
"mincount",
|
||||
"label"
|
||||
],
|
||||
"properties": {
|
||||
"field": {
|
||||
"type": "string",
|
||||
"description": "This specifies the facet field."
|
||||
},
|
||||
"mincount": {
|
||||
"type": "number",
|
||||
"description": "This specifies the minimum count required for a facet field to be included in the response. The default value is 1."
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "This specifies the label to include in place of the facet field."
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string",
|
||||
"description": "This restricts the possible constraints to only indexed values with a specified prefix."
|
||||
},
|
||||
"limit": {
|
||||
"type": "number",
|
||||
"description": "Maximum number of results"
|
||||
},
|
||||
"pageSize": {
|
||||
"type": "number",
|
||||
"description": "Display page size"
|
||||
},
|
||||
"offset": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"facetIntervals": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"intervals"
|
||||
],
|
||||
"properties": {
|
||||
"intervals": {
|
||||
"description": "List of facet intervals",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"label",
|
||||
"field",
|
||||
"sets"
|
||||
],
|
||||
"properties": {
|
||||
"label": {
|
||||
"description": "This specifies the label to use to identify the field facet.",
|
||||
"type": "string"
|
||||
},
|
||||
"field": {
|
||||
"description": "This specifies the field to facet on.",
|
||||
"type": "string"
|
||||
},
|
||||
"sets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"label",
|
||||
"start",
|
||||
"end"
|
||||
],
|
||||
"properties": {
|
||||
"label": {
|
||||
"description": "This specifies the label to use to identify the set.",
|
||||
"type": "string"
|
||||
},
|
||||
"start": {
|
||||
"description": "This specifies the start of the range.",
|
||||
"type": "string"
|
||||
},
|
||||
"end": {
|
||||
"description": "This specifies the end of the range.",
|
||||
"type": "string"
|
||||
},
|
||||
"startInclusive": {
|
||||
"description": "When true, the set will include values greater or equal to 'start'. The default value is true.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"endInclusive": {
|
||||
"description": "When true, the set will include values less than or equal to 'end'. The default value is true.",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"pageSize": {
|
||||
"type": "number",
|
||||
"description": "Display page size"
|
||||
},
|
||||
"mincount": {
|
||||
"type": "number",
|
||||
"description": "This specifies the minimum count required for a facet interval to be displayed. The default value is 1."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"expanded": {
|
||||
"description": "Toggles expanded state of the facet intervals",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"facetQueries": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"label",
|
||||
"queries"
|
||||
],
|
||||
"properties": {
|
||||
"label": {
|
||||
"description": "Label text for the default facet queries group",
|
||||
"type": "string"
|
||||
},
|
||||
"pageSize": {
|
||||
"description": "Default page size for the facet queries groups",
|
||||
"type": "number"
|
||||
},
|
||||
"expanded": {
|
||||
"description": "Toggles expanded state of the facet queries groups",
|
||||
"type": "boolean"
|
||||
},
|
||||
"mincount": {
|
||||
"description": "This specifies the minimum count required for a facet query to be displayed. The default value is 1.",
|
||||
"type": "number"
|
||||
},
|
||||
"queries": {
|
||||
"description": "List of custom facet queries",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"query",
|
||||
"label"
|
||||
],
|
||||
"properties": {
|
||||
"query": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"description": "Unique identifier for the query",
|
||||
"type": "string"
|
||||
},
|
||||
"group": {
|
||||
"description": "The group that the facet query belongs to. If no group is defined, the facet query will appear under the default facet queries group label",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"categories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"id": {},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"expanded": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"component": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"selector",
|
||||
"settings"
|
||||
],
|
||||
"properties": {
|
||||
"selector": {
|
||||
"description": "Unique component runtime identifier",
|
||||
"type": "string"
|
||||
},
|
||||
"settings": {
|
||||
"description": "Component-specific settings",
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"highlight": {
|
||||
"type": "object",
|
||||
"description": " Request that highlight fragments to be added to result set rows The properties reflect SOLR highlighting parameters.",
|
||||
"properties": {
|
||||
"prefix": {
|
||||
"description": "The string used to mark the start of a highlight in a fragment",
|
||||
"type": "string"
|
||||
},
|
||||
"postfix": {
|
||||
"description": "The string used to mark the end of a highlight in a fragment",
|
||||
"type": "string"
|
||||
},
|
||||
"snippetCount": {
|
||||
"description": "The maximum number of distinct highlight snippets to return for each highlight field",
|
||||
"type": "number"
|
||||
},
|
||||
"fragmentSize": {
|
||||
"description": "The character length of each snippet",
|
||||
"type": "number"
|
||||
},
|
||||
"maxAnalyzedChars": {
|
||||
"description": "The number of characters to be considered for highlighting. Matches after this count will not be shown",
|
||||
"type": "number"
|
||||
},
|
||||
"mergeContiguous": {
|
||||
"description": "If fragments over lap they can be merged into one larger fragment",
|
||||
"type": "boolean"
|
||||
},
|
||||
"usePhraseHighlighter": {
|
||||
"description": "Should phrases be identified",
|
||||
"type": "boolean"
|
||||
},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"description": "The fields to highlight and field specific configuration properties for each field",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"field": {
|
||||
"description": "The name of the field to highlight",
|
||||
"type": "string"
|
||||
},
|
||||
"snippetCount": {
|
||||
"type": "number"
|
||||
},
|
||||
"fragmentSize": {
|
||||
"type": "number"
|
||||
},
|
||||
"mergeContiguous": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"postfix": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sorting": {
|
||||
"type" : "object",
|
||||
"description": "Sorting options and defaults",
|
||||
"required": [
|
||||
"options"
|
||||
],
|
||||
"properties": {
|
||||
"options": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"description": "Sorting options available for users to choose from",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"key",
|
||||
"label",
|
||||
"type",
|
||||
"field",
|
||||
"ascending"
|
||||
],
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"field": {
|
||||
"type": "string"
|
||||
},
|
||||
"ascending": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
"description": "Predefined sorting to execute by default",
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"field": {
|
||||
"type": "string"
|
||||
},
|
||||
"ascending": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"description": "The name of search configuration",
|
||||
"type": "string"
|
||||
},
|
||||
"default": {
|
||||
"description": "Apply current search configuration by default",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
@@ -1123,394 +1521,19 @@
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"description": "Search configuration parameters",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"categories"
|
||||
],
|
||||
"properties": {
|
||||
"include": {
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Search configuration",
|
||||
"$ref": "#/definitions/search-configuration"
|
||||
},
|
||||
{
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"description": "Multiple search configuration",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"filterQueries": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"query"
|
||||
],
|
||||
"properties": {
|
||||
"query": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"filterWithContains": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"resetButton": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"facetFields": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"fields"
|
||||
],
|
||||
"properties": {
|
||||
"expanded": {
|
||||
"description": "Toggles expanded state of the facet field",
|
||||
"type": "boolean"
|
||||
},
|
||||
"fields": {
|
||||
"description": "List of custom facet fields",
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"field",
|
||||
"mincount",
|
||||
"label"
|
||||
],
|
||||
"properties": {
|
||||
"field": {
|
||||
"type": "string",
|
||||
"description": "This specifies the facet field."
|
||||
},
|
||||
"mincount": {
|
||||
"type": "number",
|
||||
"description": "This specifies the minimum count required for a facet field to be included in the response. The default value is 1."
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "This specifies the label to include in place of the facet field."
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string",
|
||||
"description": "This restricts the possible constraints to only indexed values with a specified prefix."
|
||||
},
|
||||
"limit": {
|
||||
"type": "number",
|
||||
"description": "Maximum number of results"
|
||||
},
|
||||
"pageSize": {
|
||||
"type": "number",
|
||||
"description": "Display page size"
|
||||
},
|
||||
"offset": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"facetIntervals": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"intervals"
|
||||
],
|
||||
"properties": {
|
||||
"intervals": {
|
||||
"description": "List of facet intervals",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"label",
|
||||
"field",
|
||||
"sets"
|
||||
],
|
||||
"properties": {
|
||||
"label": {
|
||||
"description": "This specifies the label to use to identify the field facet.",
|
||||
"type": "string"
|
||||
},
|
||||
"field": {
|
||||
"description": "This specifies the field to facet on.",
|
||||
"type": "string"
|
||||
},
|
||||
"sets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"label",
|
||||
"start",
|
||||
"end"
|
||||
],
|
||||
"properties": {
|
||||
"label": {
|
||||
"description": "This specifies the label to use to identify the set.",
|
||||
"type": "string"
|
||||
},
|
||||
"start": {
|
||||
"description": "This specifies the start of the range.",
|
||||
"type": "string"
|
||||
},
|
||||
"end": {
|
||||
"description": "This specifies the end of the range.",
|
||||
"type": "string"
|
||||
},
|
||||
"startInclusive": {
|
||||
"description": "When true, the set will include values greater or equal to 'start'. The default value is true.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"endInclusive": {
|
||||
"description": "When true, the set will include values less than or equal to 'end'. The default value is true.",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"pageSize": {
|
||||
"type": "number",
|
||||
"description": "Display page size"
|
||||
},
|
||||
"mincount": {
|
||||
"type": "number",
|
||||
"description": "This specifies the minimum count required for a facet interval to be displayed. The default value is 1."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"expanded": {
|
||||
"description": "Toggles expanded state of the facet intervals",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"facetQueries": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"label",
|
||||
"queries"
|
||||
],
|
||||
"properties": {
|
||||
"label": {
|
||||
"description": "Label text for the default facet queries group",
|
||||
"type": "string"
|
||||
},
|
||||
"pageSize": {
|
||||
"description": "Default page size for the facet queries groups",
|
||||
"type": "number"
|
||||
},
|
||||
"expanded": {
|
||||
"description": "Toggles expanded state of the facet queries groups",
|
||||
"type": "boolean"
|
||||
},
|
||||
"mincount": {
|
||||
"description": "This specifies the minimum count required for a facet query to be displayed. The default value is 1.",
|
||||
"type": "number"
|
||||
},
|
||||
"queries": {
|
||||
"description": "List of custom facet queries",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"query",
|
||||
"label"
|
||||
],
|
||||
"properties": {
|
||||
"query": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"description": "Unique identifier for the query",
|
||||
"type": "string"
|
||||
},
|
||||
"group": {
|
||||
"description": "The group that the facet query belongs to. If no group is defined, the facet query will appear under the default facet queries group label",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"categories": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"id": {},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"expanded": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"component": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"selector",
|
||||
"settings"
|
||||
],
|
||||
"properties": {
|
||||
"selector": {
|
||||
"description": "Unique component runtime identifier",
|
||||
"type": "string"
|
||||
},
|
||||
"settings": {
|
||||
"description": "Component-specific settings",
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"highlight": {
|
||||
"type": "object",
|
||||
"description": " Request that highlight fragments to be added to result set rows The properties reflect SOLR highlighting parameters.",
|
||||
"properties": {
|
||||
"prefix": {
|
||||
"description": "The string used to mark the start of a highlight in a fragment",
|
||||
"type": "string"
|
||||
},
|
||||
"postfix": {
|
||||
"description": "The string used to mark the end of a highlight in a fragment",
|
||||
"type": "string"
|
||||
},
|
||||
"snippetCount": {
|
||||
"description": "The maximum number of distinct highlight snippets to return for each highlight field",
|
||||
"type": "number"
|
||||
},
|
||||
"fragmentSize": {
|
||||
"description": "The character length of each snippet",
|
||||
"type": "number"
|
||||
},
|
||||
"maxAnalyzedChars": {
|
||||
"description": "The number of characters to be considered for highlighting. Matches after this count will not be shown",
|
||||
"type": "number"
|
||||
},
|
||||
"mergeContiguous": {
|
||||
"description": "If fragments over lap they can be merged into one larger fragment",
|
||||
"type": "boolean"
|
||||
},
|
||||
"usePhraseHighlighter": {
|
||||
"description": "Should phrases be identified",
|
||||
"type": "boolean"
|
||||
},
|
||||
"fields": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"description": "The fields to highlight and field specific configuration properties for each field",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"field": {
|
||||
"description": "The name of the field to highlight",
|
||||
"type": "string"
|
||||
},
|
||||
"snippetCount": {
|
||||
"type": "number"
|
||||
},
|
||||
"fragmentSize": {
|
||||
"type": "number"
|
||||
},
|
||||
"mergeContiguous": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string"
|
||||
},
|
||||
"postfix": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sorting": {
|
||||
"type" : "object",
|
||||
"description": "Sorting options and defaults",
|
||||
"required": [
|
||||
"options"
|
||||
],
|
||||
"properties": {
|
||||
"options": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"description": "Sorting options available for users to choose from",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"key",
|
||||
"label",
|
||||
"type",
|
||||
"field",
|
||||
"ascending"
|
||||
],
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"field": {
|
||||
"type": "string"
|
||||
},
|
||||
"ascending": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
"description": "Predefined sorting to execute by default",
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"field": {
|
||||
"type": "string"
|
||||
},
|
||||
"ascending": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"$ref": "#/definitions/search-configuration"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"adf-viewer": {
|
||||
"description": "Viewer default properties",
|
||||
|
@@ -14,5 +14,4 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './src/public-api';
|
||||
|
Reference in New Issue
Block a user