Skip to content

Commit

Permalink
[ACS-7284] injectable search configuration (#9448)
Browse files Browse the repository at this point in the history
* injectable search configuration

* update docs
  • Loading branch information
DenysVuika committed Mar 18, 2024
1 parent 9616b50 commit a09d1cf
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 16 deletions.
14 changes: 14 additions & 0 deletions docs/content-services/services/search-query-builder.service.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,20 @@ constructor(queryBuilder: SearchQueryBuilderService) {

> **Note:** From ADF 3.0.0, the query contains the `"facetFormat": "V2"` parameter so that all the responses have the same structure whether they come from search queries containing facetFields, facetQueries, grouped facetQueries or facetIntervals.
## Runtime Configuration

You can provide search configuration at runtime using the `ADF_SEARCH_CONFIGURATION` injection token.
The value should expose the [SearchConfiguration](https://github.com/Alfresco/alfresco-ng2-components/blob/develop/lib/content-services/src/lib/search/models/search-configuration.interface.ts#L25) interface.

```ts
@NgModule({
providers: [
{ provide: ADF_SEARCH_CONFIGURATION, useValue: {/*...*/} }
]
})
class AppModule {}
```

## See also

- [Search Configuration Guide](../../user-guide/search-configuration-guide.md)
Expand Down
2 changes: 2 additions & 0 deletions lib/content-services/src/lib/search/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export * from './models/search-form.interface';
export * from './models/tabbed-facet-field.interface';

export * from './search-query-service.token';
export * from './search-configuration.token';

export * from './services/search-header-query-builder.service';
export * from './services/search-facet-filters.service';
export * from './services/search-filter.service';
Expand Down
21 changes: 21 additions & 0 deletions lib/content-services/src/lib/search/search-configuration.token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*!
* @license
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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 { InjectionToken } from '@angular/core';
import { SearchConfiguration } from './models/search-configuration.interface';

export const ADF_SEARCH_CONFIGURATION = new InjectionToken<SearchConfiguration>('Custom search configuration settings');
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,45 @@ import { AlfrescoApiService, AppConfigService } from '@alfresco/adf-core';
import { FacetField } from '../models/facet-field.interface';
import { TestBed } from '@angular/core/testing';
import { ContentTestingModule } from '../../testing/content.testing.module';
import { ADF_SEARCH_CONFIGURATION } from '../search-configuration.token';

describe('SearchQueryBuilder (runtime config)', () => {
const runtimeConfig: SearchConfiguration = {};

beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContentTestingModule],
providers: [
{ provide: ADF_SEARCH_CONFIGURATION, useValue: runtimeConfig }
]
});
});

const buildConfig = (searchSettings): AppConfigService => {
const config = TestBed.inject(AppConfigService);
config.config.search = searchSettings;
return config;
};

it('should use custom search configuration via dependency injection', () => {
const builder = TestBed.inject(SearchQueryBuilderService);
const currentConfig = builder.loadConfiguration();

expect(currentConfig).toEqual(runtimeConfig);
});

it('should prioritise runtime config over configuration file', () => {
const config: SearchConfiguration = {
categories: [{ id: 'cat1', enabled: true } as any, { id: 'cat2', enabled: true } as any],
filterQueries: [{ query: 'query1' }, { query: 'query2' }]
};
const alfrescoApiService = TestBed.inject(AlfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig(config), alfrescoApiService, runtimeConfig);
const currentConfig = builder.loadConfiguration();

expect(currentConfig).toEqual(runtimeConfig);
});
});

describe('SearchQueryBuilder', () => {
beforeEach(() => {
Expand All @@ -29,7 +68,7 @@ describe('SearchQueryBuilder', () => {
});
});

const buildConfig = (searchSettings): AppConfigService => {
const buildConfig = (searchSettings = {}): AppConfigService => {
const config = TestBed.inject(AppConfigService);
config.config.search = searchSettings;
return config;
Expand Down Expand Up @@ -57,22 +96,22 @@ describe('SearchQueryBuilder', () => {

it('should have empty user query by default', () => {
const alfrescoApiService = TestBed.inject(AlfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig({}), alfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig(), alfrescoApiService);
expect(builder.userQuery).toBe('');
});

it('should wrap user query with brackets', () => {
const alfrescoApiService = TestBed.inject(AlfrescoApiService);

const builder = new SearchQueryBuilderService(buildConfig({}), alfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig(), alfrescoApiService);
builder.userQuery = 'my query';
expect(builder.userQuery).toEqual('(my query)');
});

it('should trim user query value', () => {
const alfrescoApiService = TestBed.inject(AlfrescoApiService);

const builder = new SearchQueryBuilderService(buildConfig({}), alfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig(), alfrescoApiService);
builder.userQuery = ' something ';
expect(builder.userQuery).toEqual('(something)');
});
Expand Down Expand Up @@ -106,7 +145,7 @@ describe('SearchQueryBuilder', () => {
it('should add new filter query', () => {
const alfrescoApiService = TestBed.inject(AlfrescoApiService);

const builder = new SearchQueryBuilderService(buildConfig({}), alfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig(), alfrescoApiService);

builder.addFilterQuery('q1');

Expand All @@ -117,7 +156,7 @@ describe('SearchQueryBuilder', () => {
it('should not add empty filter query', () => {
const alfrescoApiService = TestBed.inject(AlfrescoApiService);

const builder = new SearchQueryBuilderService(buildConfig({}), alfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig(), alfrescoApiService);

builder.addFilterQuery(null);
builder.addFilterQuery('');
Expand All @@ -128,7 +167,7 @@ describe('SearchQueryBuilder', () => {
it('should not add duplicate filter query', () => {
const alfrescoApiService = TestBed.inject(AlfrescoApiService);

const builder = new SearchQueryBuilderService(buildConfig({}), alfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig(), alfrescoApiService);

builder.addFilterQuery('q1');
builder.addFilterQuery('q1');
Expand All @@ -141,7 +180,7 @@ describe('SearchQueryBuilder', () => {
it('should remove filter query', () => {
const alfrescoApiService = TestBed.inject(AlfrescoApiService);

const builder = new SearchQueryBuilderService(buildConfig({}), alfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig(), alfrescoApiService);

builder.addFilterQuery('q1');
builder.addFilterQuery('q2');
Expand All @@ -155,7 +194,7 @@ describe('SearchQueryBuilder', () => {
it('should not remove empty query', () => {
const alfrescoApiService = TestBed.inject(AlfrescoApiService);

const builder = new SearchQueryBuilderService(buildConfig({}), alfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig(), alfrescoApiService);
builder.addFilterQuery('q1');
builder.addFilterQuery('q2');
expect(builder.filterQueries.length).toBe(2);
Expand Down Expand Up @@ -648,7 +687,7 @@ describe('SearchQueryBuilder', () => {
it('should include contain the path and allowableOperations by default', () => {
const alfrescoApiService = TestBed.inject(AlfrescoApiService);

const builder = new SearchQueryBuilderService(buildConfig({}), alfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig(), alfrescoApiService);
builder.userQuery = 'nuka cola quantum';
const searchRequest = builder.buildQuery();

Expand All @@ -672,7 +711,7 @@ describe('SearchQueryBuilder', () => {
it('should the query contain the pagination', () => {
const alfrescoApiService = TestBed.inject(AlfrescoApiService);

const builder = new SearchQueryBuilderService(buildConfig({}), alfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig(), alfrescoApiService);
builder.userQuery = 'nuka cola quantum';
const mockPagination = {
maxItems: 10,
Expand All @@ -687,7 +726,7 @@ describe('SearchQueryBuilder', () => {
it('should the query contain the scope in case it is defined', () => {
const alfrescoApiService = TestBed.inject(AlfrescoApiService);

const builder = new SearchQueryBuilderService(buildConfig({}), alfrescoApiService);
const builder = new SearchQueryBuilderService(buildConfig(), alfrescoApiService);
const mockScope = { locations: 'mock-location' };
builder.userQuery = 'nuka cola quantum';
builder.setScope(mockScope);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,27 @@
* limitations under the License.
*/

import { Injectable } from '@angular/core';
import { Inject, Injectable, Optional } from '@angular/core';
import { AlfrescoApiService, AppConfigService } from '@alfresco/adf-core';
import { SearchConfiguration } from '../models/search-configuration.interface';
import { BaseQueryBuilderService } from './base-query-builder.service';
import { ADF_SEARCH_CONFIGURATION } from '../search-configuration.token';

@Injectable()
export class SearchQueryBuilderService extends BaseQueryBuilderService {

public isFilterServiceActive(): boolean {
return false;
}

constructor(appConfig: AppConfigService, alfrescoApiService: AlfrescoApiService) {
constructor(
appConfig: AppConfigService,
alfrescoApiService: AlfrescoApiService,
@Optional() @Inject(ADF_SEARCH_CONFIGURATION) private configuration?: SearchConfiguration
) {
super(appConfig, alfrescoApiService);
}

public loadConfiguration(): SearchConfiguration {
return this.appConfig.get<SearchConfiguration>('search');
return this.configuration || this.appConfig.get<SearchConfiguration>('search');
}
}

0 comments on commit a09d1cf

Please sign in to comment.