mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[AAE-3719][AAE-3720] - Fix content node selector search should align with the filtering (#6214)
* Fix content node selector search should align with the filtering * Add a flag to disable optionally the search execution in the filters * Add unit tests * refactoring - Remove content node selector service and use the main search service instead * Fix existing unit tests to align with the new changes * Fix bug when copying a file * add include properties in demo shell search config * revert attach-file-cloud widget * Remove unused import * More unit tests
This commit is contained in:
@@ -119,7 +119,8 @@
|
||||
],
|
||||
"include": [
|
||||
"path",
|
||||
"allowableOperations"
|
||||
"allowableOperations",
|
||||
"properties"
|
||||
],
|
||||
"sorting": {
|
||||
"options": [
|
||||
|
@@ -18,7 +18,7 @@
|
||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { tick, ComponentFixture, TestBed, fakeAsync } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { NodeEntry, Node, SiteEntry, SitePaging, NodePaging, ResultSetPaging } from '@alfresco/js-api';
|
||||
import { NodeEntry, Node, SiteEntry, SitePaging, NodePaging, ResultSetPaging, RequestScope } from '@alfresco/js-api';
|
||||
import { SitesService, setupTestBed, NodesApiService } from '@alfresco/adf-core';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { DropdownBreadcrumbComponent } from '../breadcrumb';
|
||||
@@ -31,7 +31,7 @@ import { CustomResourcesService } from '../document-list/services/custom-resourc
|
||||
import { NodeEntryEvent, ShareDataRow } from '../document-list';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { SearchQueryBuilderService } from '../search';
|
||||
import { ContentNodeSelectorService } from './content-node-selector.service';
|
||||
import { mockQueryBody } from '../mock/search-query.mock';
|
||||
|
||||
const fakeResultSetPaging: ResultSetPaging = {
|
||||
list: {
|
||||
@@ -59,11 +59,9 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
let nodeService: NodesApiService;
|
||||
let sitesService: SitesService;
|
||||
let searchSpy: jasmine.Spy;
|
||||
let cnSearchSpy: jasmine.Spy;
|
||||
const fakeNodeEntry = new Node({ id: 'fakeId' });
|
||||
const nodeEntryEvent = new NodeEntryEvent(fakeNodeEntry);
|
||||
let searchQueryBuilderService: SearchQueryBuilderService;
|
||||
let contentNodeSelectorService: ContentNodeSelectorService;
|
||||
|
||||
function typeToSearchBox(searchTerm = 'string-to-search') {
|
||||
const searchInput = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-search-input"]'));
|
||||
@@ -93,11 +91,9 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
|
||||
nodeService = TestBed.inject(NodesApiService);
|
||||
sitesService = TestBed.inject(SitesService);
|
||||
contentNodeSelectorService = TestBed.inject(ContentNodeSelectorService);
|
||||
searchQueryBuilderService = component.queryBuilderService;
|
||||
|
||||
spyOn(nodeService, 'getNode').and.returnValue(of({ id: 'fake-node', path: { elements: [{ nodeType: 'st:site', name: 'fake-site'}] } }));
|
||||
cnSearchSpy = spyOn(contentNodeSelectorService, 'createQuery').and.callThrough();
|
||||
searchSpy = spyOn(searchQueryBuilderService, 'execute');
|
||||
const fakeSite = new SiteEntry({ entry: { id: 'fake-site', guid: 'fake-site', title: 'fake-site', visibility: 'visible' } });
|
||||
spyOn(sitesService, 'getSite').and.returnValue(of(fakeSite));
|
||||
@@ -362,32 +358,6 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
let customResourcesService: CustomResourcesService;
|
||||
const entry: Node = <Node> { id: 'fakeid'};
|
||||
|
||||
const defaultSearchOptions = (searchTerm, rootNodeId = undefined, skipCount = 0, showFiles = false) => {
|
||||
|
||||
const parentFiltering = rootNodeId ? [{ query: `ANCESTOR:'workspace://SpacesStore/${rootNodeId}'` }] : [];
|
||||
|
||||
const defaultSearchNode: any = {
|
||||
query: {
|
||||
query: searchTerm ? `${searchTerm}*` : searchTerm
|
||||
},
|
||||
include: ['path', 'allowableOperations', 'properties'],
|
||||
paging: {
|
||||
maxItems: 25,
|
||||
skipCount: skipCount
|
||||
},
|
||||
filterQueries: [
|
||||
{ query: `TYPE:'cm:folder'${ showFiles ? " OR TYPE:'cm:content'" : '' }` },
|
||||
{ query: 'NOT cm:creator:System' },
|
||||
...parentFiltering
|
||||
],
|
||||
scope: {
|
||||
locations: 'nodes'
|
||||
}
|
||||
};
|
||||
|
||||
return defaultSearchNode;
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
const documentListService = TestBed.inject(DocumentListService);
|
||||
const expectedDefaultFolderNode = <NodeEntry> { entry: { path: { elements: [] } } };
|
||||
@@ -418,23 +388,79 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should load the results by calling the search api on search change', fakeAsync(() => {
|
||||
typeToSearchBox('kakarot');
|
||||
it('should the user query get updated when the user types in the search input', fakeAsync(() => {
|
||||
const updateSpy = spyOn(searchQueryBuilderService, 'update');
|
||||
typeToSearchBox('search-term');
|
||||
|
||||
tick(debounceSearch);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(searchSpy).toHaveBeenCalledWith(defaultSearchOptions('kakarot'));
|
||||
expect(updateSpy).toHaveBeenCalled();
|
||||
expect(searchQueryBuilderService.userQuery).toEqual('(search-term)');
|
||||
expect(component.searchTerm).toEqual('search-term');
|
||||
}));
|
||||
|
||||
it('should show files in results by calling the search api on search change', fakeAsync(() => {
|
||||
component.showFilesInResult = true;
|
||||
typeToSearchBox('kakarot');
|
||||
it('should perform a search when the queryBody gets updated and it is defined', async () => {
|
||||
searchQueryBuilderService.userQuery = 'search-term';
|
||||
searchQueryBuilderService.update();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(searchSpy).toHaveBeenCalledWith(mockQueryBody);
|
||||
});
|
||||
|
||||
it('should NOT perform a search and clear the results when the queryBody gets updated and it is NOT defined', async () => {
|
||||
spyOn(component, 'clearSearch');
|
||||
|
||||
searchQueryBuilderService.userQuery = '';
|
||||
searchQueryBuilderService.update();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(searchSpy).not.toHaveBeenCalled();
|
||||
expect(component.clearSearch).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should reset the search term when clicking the clear icon', () => {
|
||||
component.searchTerm = 'search-term';
|
||||
searchQueryBuilderService.userQuery = 'search-term';
|
||||
spyOn(component, 'clearSearch');
|
||||
|
||||
fixture.detectChanges();
|
||||
const clearIcon = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-search-clear"]'));
|
||||
clearIcon.nativeElement.click();
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(searchQueryBuilderService.userQuery).toEqual('');
|
||||
expect(component.searchTerm).toEqual('');
|
||||
expect(component.clearSearch).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should load the results by calling the search api on search change', fakeAsync(() => {
|
||||
typeToSearchBox('search-term');
|
||||
|
||||
tick(debounceSearch);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(searchSpy).toHaveBeenCalledWith(defaultSearchOptions('kakarot', undefined, 0, true));
|
||||
expect(searchSpy).toHaveBeenCalledWith(mockQueryBody);
|
||||
}));
|
||||
|
||||
it('should the query include the show files filterQuery', fakeAsync(() => {
|
||||
component.showFilesInResult = true;
|
||||
typeToSearchBox('search-term');
|
||||
|
||||
const expectedQueryBody = mockQueryBody;
|
||||
expectedQueryBody.filterQueries.push({
|
||||
query: `TYPE:'cm:folder' OR TYPE:'cm:content'`
|
||||
});
|
||||
|
||||
tick(debounceSearch);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(searchSpy).toHaveBeenCalledWith(expectedQueryBody);
|
||||
}));
|
||||
|
||||
it('should reset the currently chosen node in case of starting a new search', fakeAsync(() => {
|
||||
@@ -453,8 +479,8 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
expect(component.breadcrumbFolderTitle).toBe('My Sites');
|
||||
});
|
||||
|
||||
it('should call the search api on changing the site selectBox value', fakeAsync(() => {
|
||||
typeToSearchBox('vegeta');
|
||||
it('should perform a search when selecting a site with the correct query', fakeAsync(() => {
|
||||
typeToSearchBox('search-term');
|
||||
|
||||
tick(debounceSearch);
|
||||
|
||||
@@ -462,40 +488,34 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
|
||||
component.siteChanged(<SiteEntry> { entry: { guid: 'namek' } });
|
||||
|
||||
const expectedQueryBody = mockQueryBody;
|
||||
expectedQueryBody.filterQueries = [ { query: `ANCESTOR:'workspace://SpacesStore/namek'`} ];
|
||||
|
||||
expect(searchSpy.calls.count()).toBe(2, 'Search count should be two after the site change');
|
||||
expect(searchSpy.calls.argsFor(1)).toEqual([defaultSearchOptions('vegeta', 'namek')]);
|
||||
}));
|
||||
|
||||
it('should create the query with the right parameters on changing the site selectbox\'s value', fakeAsync(() => {
|
||||
typeToSearchBox('vegeta');
|
||||
|
||||
tick(debounceSearch);
|
||||
expect(cnSearchSpy.calls.count()).toBe(1);
|
||||
|
||||
component.siteChanged(<SiteEntry> { entry: { guid: '-sites-' } });
|
||||
|
||||
expect(cnSearchSpy).toHaveBeenCalled();
|
||||
expect(cnSearchSpy.calls.count()).toBe(2);
|
||||
expect(cnSearchSpy).toHaveBeenCalledWith('vegeta', undefined, 0, 25, [], false);
|
||||
expect(cnSearchSpy).toHaveBeenCalledWith('vegeta', '-sites-', 0, 25, ['123456testId', '09876543testId'], false);
|
||||
expect(searchSpy).toHaveBeenCalledWith(expectedQueryBody);
|
||||
}));
|
||||
|
||||
it('should create the query with the right parameters on changing the site selectBox value from a custom dropdown menu', fakeAsync(() => {
|
||||
component.dropdownSiteList = <SitePaging> { list: { entries: [<SiteEntry> { entry: { guid: '-sites-' } }, <SiteEntry> { entry: { guid: 'namek' } }] } };
|
||||
fixture.detectChanges();
|
||||
|
||||
typeToSearchBox('vegeta');
|
||||
typeToSearchBox('search-term');
|
||||
|
||||
tick(debounceSearch);
|
||||
|
||||
expect(cnSearchSpy.calls.count()).toBe(1);
|
||||
expect(searchSpy.calls.count()).toBe(1);
|
||||
|
||||
component.siteChanged(<SiteEntry> { entry: { guid: '-sites-' } });
|
||||
|
||||
expect(cnSearchSpy).toHaveBeenCalled();
|
||||
expect(cnSearchSpy.calls.count()).toBe(2);
|
||||
expect(cnSearchSpy).toHaveBeenCalledWith('vegeta', undefined, 0, 25, [], false);
|
||||
expect(cnSearchSpy).toHaveBeenCalledWith('vegeta', '-sites-', 0, 25, ['123456testId', '09876543testId'], false);
|
||||
const expectedQueryBodyWithSiteChange = mockQueryBody;
|
||||
expectedQueryBodyWithSiteChange.filterQueries = [
|
||||
{ query: `ANCESTOR:'workspace://SpacesStore/-sites-' OR ANCESTOR:'workspace://SpacesStore/123456testId' OR ANCESTOR:'workspace://SpacesStore/09876543testId'` }
|
||||
];
|
||||
|
||||
expect(searchSpy).toHaveBeenCalled();
|
||||
expect(searchSpy.calls.count()).toBe(2);
|
||||
expect(searchSpy).toHaveBeenCalledWith(mockQueryBody);
|
||||
expect(searchSpy).toHaveBeenCalledWith(expectedQueryBodyWithSiteChange);
|
||||
}));
|
||||
|
||||
it('should get the corresponding node ids on search when a known alias is selected from dropdown', fakeAsync(() => {
|
||||
@@ -601,19 +621,24 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
expect(component.showingSearchResults).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should the query restrict the search to the currentFolderId in case is defined', () => {
|
||||
it('should the query restrict the search to the currentFolderId in case is defined', fakeAsync(() => {
|
||||
component.currentFolderId = 'my-root-id';
|
||||
component.restrictRootToCurrentFolderId = true;
|
||||
component.ngOnInit();
|
||||
component.search('search');
|
||||
typeToSearchBox('search-term');
|
||||
tick(debounceSearch);
|
||||
|
||||
expect(cnSearchSpy).toHaveBeenCalledWith('search', 'my-root-id', 0, 25, [], false);
|
||||
});
|
||||
const expectedQueryBody = mockQueryBody;
|
||||
expectedQueryBody.filterQueries = [ { query: `ANCESTOR:'workspace://SpacesStore/my-root-id'`} ];
|
||||
|
||||
expect(searchSpy).toHaveBeenCalledWith(expectedQueryBody);
|
||||
}));
|
||||
|
||||
it('should emit showingSearch event with true while searching', async () => {
|
||||
spyOn(customResourcesService, 'hasCorrespondingNodeIds').and.returnValue(true);
|
||||
const showingSearchSpy = spyOn(component.showingSearch, 'emit');
|
||||
component.search('search');
|
||||
|
||||
component.queryBuilderService.execute({ query: { query: 'search' } });
|
||||
|
||||
triggerSearchResults(fakeResultSetPaging);
|
||||
fixture.detectChanges();
|
||||
@@ -623,15 +648,16 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
expect(showingSearchSpy).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('should emit showingSearch event with false if you remove search term without clicking on X (icon) icon', async () => {
|
||||
it('should emit showingSearch event with false if you remove search term without clicking on X (icon) icon', fakeAsync(() => {
|
||||
const showingSearchSpy = spyOn(component.showingSearch, 'emit');
|
||||
component.search('');
|
||||
typeToSearchBox('');
|
||||
tick(debounceSearch);
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(component.showingSearchResults).toBe(false);
|
||||
expect(showingSearchSpy).toHaveBeenCalledWith(false);
|
||||
});
|
||||
}));
|
||||
|
||||
it('should emit showingResults event with false when clicking on the X (clear) icon', () => {
|
||||
const showingSearchSpy = spyOn(component.showingSearch, 'emit');
|
||||
@@ -654,7 +680,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
it('should emit showingResults event with false if search api fails', async () => {
|
||||
getCorrespondingNodeIdsSpy.and.throwError('Failed');
|
||||
const showingSearchSpy = spyOn(component.showingSearch, 'emit');
|
||||
component.search('search');
|
||||
component.queryBuilderService.execute({ query: { query: 'search' } });
|
||||
|
||||
triggerSearchResults(fakeResultSetPaging);
|
||||
fixture.detectChanges();
|
||||
@@ -665,13 +691,17 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
});
|
||||
|
||||
it('should the query restrict the search to the site and not to the currentFolderId in case is changed', () => {
|
||||
component.queryBuilderService.userQuery = 'search-term';
|
||||
component.currentFolderId = 'my-root-id';
|
||||
component.restrictRootToCurrentFolderId = true;
|
||||
component.ngOnInit();
|
||||
component.siteChanged(<SiteEntry> { entry: { guid: 'my-site-id' } });
|
||||
component.search('search');
|
||||
|
||||
expect(cnSearchSpy).toHaveBeenCalledWith('search', 'my-site-id', 0, 25, [], false);
|
||||
const expectedQueryBodyWithSiteChange = mockQueryBody;
|
||||
expectedQueryBodyWithSiteChange.filterQueries = [
|
||||
{ query: `ANCESTOR:'workspace://SpacesStore/my-site-id'` }
|
||||
];
|
||||
|
||||
expect(searchSpy).toHaveBeenCalledWith(expectedQueryBodyWithSiteChange);
|
||||
});
|
||||
|
||||
it('should restrict the breadcrumb to the currentFolderId in case restrictedRoot is true', () => {
|
||||
@@ -689,7 +719,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
});
|
||||
|
||||
it('should clear the search field, nodes and chosenNode when deleting the search input', fakeAsync (() => {
|
||||
spyOn(component, 'clear').and.callThrough();
|
||||
spyOn(component, 'clearSearch').and.callThrough();
|
||||
typeToSearchBox('a');
|
||||
|
||||
tick(debounceSearch);
|
||||
@@ -703,7 +733,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(searchSpy.calls.count()).toBe(1, 'no other search has been performed');
|
||||
expect(component.clear).toHaveBeenCalled();
|
||||
expect(component.clearSearch).toHaveBeenCalled();
|
||||
expect(component.folderIdToShow).toBe('cat-girl-nuku-nuku', 'back to the folder in which the search was performed');
|
||||
}));
|
||||
|
||||
@@ -728,7 +758,6 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
component.siteChanged(<SiteEntry> { entry: { guid: 'namek' } });
|
||||
|
||||
expect(searchSpy.calls.count()).toBe(2);
|
||||
expect(searchSpy.calls.argsFor(1)).toEqual([defaultSearchOptions('piccolo', 'namek')]);
|
||||
|
||||
component.clear();
|
||||
|
||||
@@ -845,21 +874,19 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
}, 300);
|
||||
});
|
||||
|
||||
it('should reload the original folderId when clearing the search input', async() => {
|
||||
component.search('mock-type-search');
|
||||
|
||||
triggerSearchResults(fakeResultSetPaging);
|
||||
it('should reload the original folderId when clearing the search input', fakeAsync(() => {
|
||||
typeToSearchBox('search-term');
|
||||
tick(debounceSearch);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(component.folderIdToShow).toBe(null);
|
||||
|
||||
component.clear();
|
||||
typeToSearchBox('');
|
||||
tick(debounceSearch);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(component.folderIdToShow).toBe('cat-girl-nuku-nuku');
|
||||
});
|
||||
}));
|
||||
|
||||
it('should set the folderIdToShow to the default "currentFolderId" if siteId is undefined', (done) => {
|
||||
component.siteChanged(<SiteEntry> { entry: { guid: 'Kame-Sennin Muten Roshi' } });
|
||||
@@ -900,63 +927,50 @@ describe('ContentNodeSelectorPanelComponent', () => {
|
||||
expect(component.searchTerm).toBe('');
|
||||
|
||||
expect(component.infiniteScroll).toBeTruthy();
|
||||
expect(component.pagination.maxItems).toBe(45);
|
||||
expect(component.queryBuilderService.paging.maxItems).toBe(45);
|
||||
expect(searchSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set its loading state to true after search was started', fakeAsync (() => {
|
||||
component.showingSearchResults = true;
|
||||
|
||||
typeToSearchBox('shenron');
|
||||
|
||||
tick(debounceSearch);
|
||||
|
||||
it('should set its loading state to true to perform a new search', async() => {
|
||||
component.prepareDialogForNewSearch(mockQueryBody);
|
||||
fixture.detectChanges();
|
||||
|
||||
tick(debounceSearch);
|
||||
await fixture.whenStable();
|
||||
|
||||
const spinnerSelector = By.css('[data-automation-id="content-node-selector-search-pagination"] [data-automation-id="adf-infinite-pagination-spinner"]');
|
||||
const paginationLoading = fixture.debugElement.query(spinnerSelector);
|
||||
|
||||
expect(paginationLoading).not.toBeNull();
|
||||
}));
|
||||
});
|
||||
|
||||
it('Should infinite pagination target be null when we use it for search ', fakeAsync (() => {
|
||||
component.showingSearchResults = true;
|
||||
|
||||
typeToSearchBox('shenron');
|
||||
|
||||
tick(debounceSearch);
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
tick(debounceSearch);
|
||||
|
||||
expect(component.target).toBeNull();
|
||||
}));
|
||||
|
||||
it('Should infinite pagination target be present when search finish', fakeAsync (() => {
|
||||
component.showingSearchResults = true;
|
||||
|
||||
typeToSearchBox('shenron');
|
||||
|
||||
tick(debounceSearch);
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
typeToSearchBox('');
|
||||
|
||||
tick(debounceSearch);
|
||||
|
||||
it('Should infinite pagination target be present when search finish', () => {
|
||||
triggerSearchResults(fakeResultSetPaging);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.target).not.toBeNull();
|
||||
}));
|
||||
});
|
||||
|
||||
it('Should infinite pagination target on init be the document list', fakeAsync(() => {
|
||||
component.showingSearchResults = true;
|
||||
|
||||
expect(component.target).toEqual(component.documentList);
|
||||
}));
|
||||
|
||||
it('Should set the scope to nodes when the component inits', () => {
|
||||
const expectedScope: RequestScope = { locations: 'nodes' };
|
||||
const setScopeSpy = spyOn(component.queryBuilderService, 'setScope');
|
||||
component.ngOnInit();
|
||||
|
||||
expect(setScopeSpy).toHaveBeenCalledWith(expectedScope);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@@ -29,7 +29,6 @@ import {
|
||||
import {
|
||||
HighlightDirective,
|
||||
UserPreferencesService,
|
||||
PaginationModel,
|
||||
UserPreferenceValues,
|
||||
InfinitePaginationComponent, PaginatedComponent,
|
||||
NodesApiService,
|
||||
@@ -38,11 +37,10 @@ import {
|
||||
FileUploadCompleteEvent
|
||||
} from '@alfresco/adf-core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { Node, NodePaging, Pagination, SiteEntry, SitePaging, NodeEntry } from '@alfresco/js-api';
|
||||
import { Node, NodePaging, Pagination, SiteEntry, SitePaging, NodeEntry, QueryBody, RequestScope } from '@alfresco/js-api';
|
||||
import { DocumentListComponent } from '../document-list/components/document-list.component';
|
||||
import { RowFilter } from '../document-list/data/row-filter.model';
|
||||
import { ImageResolver } from '../document-list/data/image-resolver.model';
|
||||
import { ContentNodeSelectorService } from './content-node-selector.service';
|
||||
import { debounceTime, takeUntil, scan } from 'rxjs/operators';
|
||||
import { CustomResourcesService } from '../document-list/services/custom-resources.service';
|
||||
import { NodeEntryEvent, ShareDataRow } from '../document-list';
|
||||
@@ -69,14 +67,11 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
||||
|
||||
DEFAULT_PAGINATION: Pagination = new Pagination({
|
||||
maxItems: 25,
|
||||
skipCount: 0,
|
||||
totalItems: 0,
|
||||
hasMoreItems: false
|
||||
skipCount: 0
|
||||
});
|
||||
|
||||
private showSiteList = true;
|
||||
private showSearchField = true;
|
||||
private showFiles = false;
|
||||
|
||||
/** If true will restrict the search and breadcrumbs to the currentFolderId */
|
||||
@Input()
|
||||
@@ -196,7 +191,8 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
||||
@Input()
|
||||
set showFilesInResult(value: boolean) {
|
||||
if (value !== undefined && value !== null) {
|
||||
this.showFiles = value;
|
||||
const showFilesQuery = `TYPE:'cm:folder'${value ? " OR TYPE:'cm:content'" : ''}`;
|
||||
this.queryBuilderService.addFilterQuery(showFilesQuery);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,8 +230,6 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
||||
breadcrumbFolderTitle: string | null = null;
|
||||
startSiteGuid: string | null = null;
|
||||
|
||||
pagination: PaginationModel = this.DEFAULT_PAGINATION;
|
||||
|
||||
@ViewChild(InfinitePaginationComponent, { static: true })
|
||||
infinitePaginationComponent: InfinitePaginationComponent;
|
||||
|
||||
@@ -248,8 +242,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(private contentNodeSelectorService: ContentNodeSelectorService,
|
||||
private customResourcesService: CustomResourcesService,
|
||||
constructor(private customResourcesService: CustomResourcesService,
|
||||
@Inject(SEARCH_QUERY_SERVICE_TOKEN) public queryBuilderService: SearchQueryBuilderService,
|
||||
private userPreferencesService: UserPreferencesService,
|
||||
private nodesApiService: NodesApiService,
|
||||
@@ -272,7 +265,23 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
||||
debounceTime(this.debounceSearch),
|
||||
takeUntil(this.onDestroy$)
|
||||
)
|
||||
.subscribe(searchValue => this.search(searchValue));
|
||||
.subscribe(searchValue => {
|
||||
this.searchTerm = searchValue;
|
||||
this.queryBuilderService.userQuery = searchValue;
|
||||
this.queryBuilderService.update();
|
||||
});
|
||||
|
||||
this.queryBuilderService.updated
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe((queryBody: QueryBody) => {
|
||||
if (queryBody) {
|
||||
this.prepareDialogForNewSearch(queryBody);
|
||||
this.queryBuilderService.execute(queryBody);
|
||||
} else {
|
||||
this.resetFolderToShow();
|
||||
this.clearSearch();
|
||||
}
|
||||
});
|
||||
|
||||
this.queryBuilderService.executed
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
@@ -299,6 +308,8 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
||||
this.breadcrumbTransform = this.breadcrumbTransform ? this.breadcrumbTransform : null;
|
||||
this.isSelectionValid = this.isSelectionValid ? this.isSelectionValid : defaultValidation;
|
||||
this.onFileUploadEvent();
|
||||
this.resetPagination();
|
||||
this.setSearchScopeToNodes();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@@ -365,17 +376,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
||||
this.siteId = chosenSite.entry.guid;
|
||||
this.setTitleIfCustomSite(chosenSite);
|
||||
this.siteChange.emit(chosenSite.entry.title);
|
||||
this.updateResults();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the searchTerm attribute and starts a new search
|
||||
*
|
||||
* @param searchTerm string value to search against
|
||||
*/
|
||||
search(searchTerm: string): void {
|
||||
this.searchTerm = searchTerm;
|
||||
this.updateResults();
|
||||
this.queryBuilderService.update();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -393,11 +394,33 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
||||
return folderNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the dialog for a new search
|
||||
*/
|
||||
prepareDialogForNewSearch(queryBody: QueryBody): void {
|
||||
this.target = queryBody ? null : this.documentList;
|
||||
if (this.target) {
|
||||
this.infinitePaginationComponent.reset();
|
||||
}
|
||||
this.folderIdToShow = null;
|
||||
this.loadingSearchResults = true;
|
||||
this.addCorrespondingNodeIdsQuery();
|
||||
this.resetChosenNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the search input and reset to last folder node in which search was performed
|
||||
*/
|
||||
clear(): void {
|
||||
this.clearSearch();
|
||||
this.searchTerm = '';
|
||||
this.queryBuilderService.userQuery = '';
|
||||
this.queryBuilderService.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the folder to be shown with the site selection or the initial landing folder
|
||||
*/
|
||||
resetFolderToShow(): void {
|
||||
this.folderIdToShow = this.siteId || this.currentFolderId;
|
||||
}
|
||||
|
||||
@@ -407,71 +430,52 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
||||
clearSearch() {
|
||||
this.searchTerm = '';
|
||||
this.nodePaging = null;
|
||||
this.pagination.maxItems = this.pageSize;
|
||||
this.resetPagination();
|
||||
this.resetChosenNode();
|
||||
this.showingSearchResults = false;
|
||||
this.showingSearch.emit(this.showingSearchResults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the result list depending on the criteria
|
||||
*/
|
||||
private updateResults(): void {
|
||||
this.target = this.searchTerm.length > 0 ? null : this.documentList;
|
||||
|
||||
if (this.searchTerm.length === 0) {
|
||||
this.clear();
|
||||
} else {
|
||||
this.startNewSearch();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the first page of a new search result
|
||||
*/
|
||||
private startNewSearch(): void {
|
||||
this.nodePaging = null;
|
||||
this.pagination.maxItems = this.pageSize;
|
||||
if (this.target) {
|
||||
this.infinitePaginationComponent.reset();
|
||||
}
|
||||
this.chosenNode = null;
|
||||
this.folderIdToShow = null;
|
||||
this.querySearch();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the call to searchService with the proper parameters
|
||||
*/
|
||||
private querySearch(): void {
|
||||
this.loadingSearchResults = true;
|
||||
private addCorrespondingNodeIdsQuery() {
|
||||
let extraParentFiltering = '';
|
||||
|
||||
if (this.customResourcesService.hasCorrespondingNodeIds(this.siteId)) {
|
||||
this.customResourcesService.getCorrespondingNodeIds(this.siteId)
|
||||
.subscribe((nodeIds) => {
|
||||
const query = this.contentNodeSelectorService.createQuery(this.searchTerm, this.siteId, this.pagination.skipCount, this.pagination.maxItems, nodeIds, this.showFiles);
|
||||
this.queryBuilderService.execute(query);
|
||||
},
|
||||
() => {
|
||||
this.showSearchResults({ list: { entries: [] } });
|
||||
if (nodeIds && nodeIds.length) {
|
||||
nodeIds
|
||||
.filter((id) => id !== this.siteId)
|
||||
.forEach((extraId) => {
|
||||
extraParentFiltering += ` OR ANCESTOR:'workspace://SpacesStore/${extraId}'`;
|
||||
});
|
||||
}
|
||||
const parentFiltering = this.siteId ? `ANCESTOR:'workspace://SpacesStore/${this.siteId}'${extraParentFiltering}` : '';
|
||||
this.queryBuilderService.addFilterQuery(parentFiltering);
|
||||
});
|
||||
} else {
|
||||
const query = this.contentNodeSelectorService.createQuery(this.searchTerm, this.siteId, this.pagination.skipCount, this.pagination.maxItems, [], this.showFiles);
|
||||
this.queryBuilderService.execute(query);
|
||||
const parentFiltering = this.siteId ? `ANCESTOR:'workspace://SpacesStore/${this.siteId}'` : '';
|
||||
this.queryBuilderService.addFilterQuery(parentFiltering);
|
||||
}
|
||||
}
|
||||
|
||||
private setSearchScopeToNodes() {
|
||||
const scope: RequestScope = {
|
||||
locations: 'nodes'
|
||||
};
|
||||
this.queryBuilderService.setScope(scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the results of the search
|
||||
*
|
||||
* @param results Search results
|
||||
*/
|
||||
private showSearchResults(nodePaging: NodePaging): void {
|
||||
private showSearchResults(results: NodePaging): void {
|
||||
this.showingSearchResults = true;
|
||||
this.loadingSearchResults = false;
|
||||
this.showingSearch.emit(this.showingSearchResults);
|
||||
|
||||
this.nodePaging = nodePaging;
|
||||
this.nodePaging = results;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -505,14 +509,15 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
||||
/**
|
||||
* Loads the next batch of search results
|
||||
*
|
||||
* @param event Pagination object
|
||||
* @param pagination Pagination object
|
||||
*/
|
||||
getNextPageOfSearch(pagination: Pagination): void {
|
||||
this.infiniteScroll = true;
|
||||
this.pagination = pagination;
|
||||
this.queryBuilderService.paging.maxItems = pagination.maxItems;
|
||||
this.queryBuilderService.paging.skipCount = pagination.skipCount;
|
||||
|
||||
if (this.searchTerm.length > 0) {
|
||||
this.querySearch();
|
||||
this.queryBuilderService.update();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,8 +546,7 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
onCurrentSelection(nodesEntries: NodeEntry[]): void {
|
||||
const validNodesEntity = nodesEntries.filter((node) => this.isSelectionValid(node.entry));
|
||||
const nodes: Node[] = validNodesEntity.map((node) => node.entry );
|
||||
this.chosenNode = nodes;
|
||||
this.chosenNode = validNodesEntity.map((node) => node.entry );
|
||||
}
|
||||
|
||||
setTitleIfCustomSite(site: SiteEntry) {
|
||||
@@ -578,4 +582,11 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
|
||||
|
||||
return selectedNodes;
|
||||
}
|
||||
|
||||
private resetPagination(): void {
|
||||
this.queryBuilderService.paging = {
|
||||
maxItems: this.pageSize,
|
||||
skipCount: this.DEFAULT_PAGINATION.skipCount
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -1,120 +0,0 @@
|
||||
/*!
|
||||
* @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 { TestBed } from '@angular/core/testing';
|
||||
import { setupTestBed } from '@alfresco/adf-core';
|
||||
import { ContentNodeSelectorService } from './content-node-selector.service';
|
||||
import { ContentTestingModule } from '../testing/content.testing.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
describe('ContentNodeSelectorService', () => {
|
||||
|
||||
let service: ContentNodeSelectorService;
|
||||
|
||||
setupTestBed({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
]
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
service = TestBed.inject(ContentNodeSelectorService);
|
||||
});
|
||||
|
||||
it('should have the proper main query for search string', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum');
|
||||
|
||||
expect(queryBody.query).toEqual({
|
||||
query: 'nuka cola quantum*'
|
||||
});
|
||||
});
|
||||
|
||||
it('should make it including the path and allowableOperations', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum');
|
||||
|
||||
expect(queryBody.include).toEqual(['path', 'allowableOperations', 'properties']);
|
||||
});
|
||||
|
||||
it('should make the search restricted to nodes only', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum');
|
||||
|
||||
expect(queryBody.scope.locations).toEqual('nodes');
|
||||
});
|
||||
|
||||
it('should set the maxItems and paging properly by parameters', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum', null, 10, 100);
|
||||
|
||||
expect(queryBody.paging.maxItems).toEqual(100);
|
||||
expect(queryBody.paging.skipCount).toEqual(10);
|
||||
});
|
||||
|
||||
it('should set the maxItems and paging properly by default', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum');
|
||||
|
||||
expect(queryBody.paging.maxItems).toEqual(25);
|
||||
expect(queryBody.paging.skipCount).toEqual(0);
|
||||
});
|
||||
|
||||
it('should filter the search for folders', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum');
|
||||
|
||||
expect(queryBody.filterQueries).toContain({ query: "TYPE:'cm:folder'" });
|
||||
});
|
||||
|
||||
it('should filter the search for files', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum', null, 0, 25, [], true);
|
||||
|
||||
expect(queryBody.filterQueries).toContain({ query: "TYPE:'cm:folder' OR TYPE:'cm:content'" });
|
||||
});
|
||||
|
||||
it('should filter out the "system-base" entries', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum');
|
||||
|
||||
expect(queryBody.filterQueries).toContain({ query: 'NOT cm:creator:System' });
|
||||
});
|
||||
|
||||
it('should filter for the provided ancestor if defined', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum', 'diamond-city');
|
||||
|
||||
expect(queryBody.filterQueries).toContain({ query: 'ANCESTOR:\'workspace://SpacesStore/diamond-city\'' });
|
||||
});
|
||||
|
||||
it('should NOT filter for the ancestor if NOT defined', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum');
|
||||
|
||||
expect(queryBody.filterQueries).not.toContain({ query: 'ANCESTOR:\'workspace://SpacesStore/null\'' });
|
||||
});
|
||||
|
||||
it('should filter for the extra provided ancestors if defined', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum', 'diamond-city', 0, 25, ['extra-diamond-city']);
|
||||
|
||||
expect(queryBody.filterQueries).toContain({ query: 'ANCESTOR:\'workspace://SpacesStore/diamond-city\' OR ANCESTOR:\'workspace://SpacesStore/extra-diamond-city\'' });
|
||||
});
|
||||
|
||||
it('should NOT filter for extra ancestors if an empty list of ids is provided', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum', 'diamond-city', 0, 25, []);
|
||||
|
||||
expect(queryBody.filterQueries).toContain({ query: 'ANCESTOR:\'workspace://SpacesStore/diamond-city\'' });
|
||||
});
|
||||
|
||||
it('should NOT filter for the extra provided ancestor if it\'s the same as the rootNodeId', () => {
|
||||
const queryBody = service.createQuery('nuka cola quantum', 'diamond-city', 0, 25, ['diamond-city']);
|
||||
|
||||
expect(queryBody.filterQueries).toContain({ query: 'ANCESTOR:\'workspace://SpacesStore/diamond-city\'' });
|
||||
});
|
||||
});
|
@@ -1,62 +0,0 @@
|
||||
/*!
|
||||
* @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 { Injectable } from '@angular/core';
|
||||
import { QueryBody } from '@alfresco/js-api';
|
||||
|
||||
/**
|
||||
* Internal service used by ContentNodeSelector component.
|
||||
*/
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ContentNodeSelectorService {
|
||||
|
||||
createQuery(searchTerm: string, rootNodeId: string = null, skipCount: number = 0, maxItems: number = 25, extraNodeIds?: string[], showFiles?: boolean): QueryBody {
|
||||
let extraParentFiltering = '';
|
||||
|
||||
if (extraNodeIds && extraNodeIds.length) {
|
||||
extraNodeIds
|
||||
.filter((id) => id !== rootNodeId)
|
||||
.forEach((extraId) => {
|
||||
extraParentFiltering += ` OR ANCESTOR:'workspace://SpacesStore/${extraId}'`;
|
||||
});
|
||||
}
|
||||
|
||||
const parentFiltering = rootNodeId ? [{ query: `ANCESTOR:'workspace://SpacesStore/${rootNodeId}'${extraParentFiltering}` }] : [];
|
||||
|
||||
return {
|
||||
query: {
|
||||
query: `${searchTerm}*`
|
||||
},
|
||||
include: ['path', 'allowableOperations', 'properties'],
|
||||
paging: {
|
||||
maxItems: maxItems,
|
||||
skipCount: skipCount
|
||||
},
|
||||
filterQueries: [
|
||||
{ query: `TYPE:'cm:folder'${showFiles ? " OR TYPE:'cm:content'" : ''}` },
|
||||
{ query: 'NOT cm:creator:System' },
|
||||
...parentFiltering
|
||||
],
|
||||
scope: {
|
||||
locations: 'nodes'
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
@@ -19,7 +19,6 @@ export * from './name-location-cell/name-location-cell.component';
|
||||
export * from './content-node-selector.component-data.interface';
|
||||
export * from './content-node-selector-panel.component';
|
||||
export * from './content-node-selector.component';
|
||||
export * from './content-node-selector.service';
|
||||
export * from './content-node-dialog.service';
|
||||
export * from './content-node-selector-panel.service';
|
||||
|
||||
|
@@ -21,3 +21,4 @@ export * from './search.component.mock';
|
||||
export * from './search.service.mock';
|
||||
export * from './search-filter-mock';
|
||||
export * from './sites-dropdown.component.mock';
|
||||
export * from './search-query.mock';
|
||||
|
41
lib/content-services/src/lib/mock/search-query.mock.ts
Normal file
41
lib/content-services/src/lib/mock/search-query.mock.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
/*!
|
||||
* @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 { QueryBody } from '@alfresco/js-api';
|
||||
|
||||
export const mockQueryBody: QueryBody = <QueryBody> {
|
||||
query: {
|
||||
query: '(search-term)',
|
||||
language: 'afts'
|
||||
},
|
||||
include: ['path', 'allowableOperations'],
|
||||
paging: {
|
||||
maxItems: 25,
|
||||
skipCount: 0
|
||||
},
|
||||
fields: undefined,
|
||||
filterQueries: [],
|
||||
facetQueries: null,
|
||||
facetIntervals: null,
|
||||
facetFields: null,
|
||||
sort: [],
|
||||
scope: {
|
||||
locations: 'nodes'
|
||||
},
|
||||
highlight: null,
|
||||
facetFormat: 'V2'
|
||||
};
|
@@ -24,7 +24,8 @@ import {
|
||||
RequestFacetField,
|
||||
RequestSortDefinitionInner,
|
||||
ResultSetPaging,
|
||||
RequestHighlight
|
||||
RequestHighlight,
|
||||
RequestScope
|
||||
} from '@alfresco/js-api';
|
||||
import { SearchCategory } from './search-category.interface';
|
||||
import { FilterQuery } from './filter-query.interface';
|
||||
@@ -52,6 +53,7 @@ export abstract class BaseQueryBuilderService {
|
||||
paging: { maxItems?: number; skipCount?: number } = null;
|
||||
sorting: SearchSortingDefinition[] = [];
|
||||
sortingOptions: SearchSortingDefinition[] = [];
|
||||
private scope: RequestScope;
|
||||
|
||||
protected userFacetBuckets: { [key: string]: FacetFieldBucket[] } = {};
|
||||
|
||||
@@ -193,6 +195,14 @@ export abstract class BaseQueryBuilderService {
|
||||
return null;
|
||||
}
|
||||
|
||||
setScope(scope: RequestScope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
getScope(): RequestScope {
|
||||
return this.scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the current query and triggers the `updated` event.
|
||||
*/
|
||||
@@ -265,6 +275,10 @@ export abstract class BaseQueryBuilderService {
|
||||
highlight: this.highlight
|
||||
};
|
||||
|
||||
if (this.scope) {
|
||||
result['scope'] = this.scope;
|
||||
}
|
||||
|
||||
result['facetFormat'] = 'V2';
|
||||
return result;
|
||||
}
|
||||
|
@@ -618,4 +618,47 @@ describe('SearchQueryBuilder', () => {
|
||||
|
||||
builder.execute();
|
||||
});
|
||||
|
||||
it('should include contain the path and allowableOperations by default', () => {
|
||||
const builder = new SearchQueryBuilderService(buildConfig({}), null);
|
||||
builder.userQuery = 'nuka cola quantum';
|
||||
const queryBody = builder.buildQuery();
|
||||
|
||||
expect(queryBody.include).toEqual(['path', 'allowableOperations']);
|
||||
});
|
||||
|
||||
it('should fetch the include config from the app config', () => {
|
||||
const includeConfig = ['path', 'allowableOperations', 'properties'];
|
||||
const config: SearchConfiguration = {
|
||||
include: includeConfig
|
||||
};
|
||||
const builder = new SearchQueryBuilderService(buildConfig(config), null);
|
||||
builder.userQuery = 'nuka cola quantum';
|
||||
const queryBody = builder.buildQuery();
|
||||
|
||||
expect(queryBody.include).toEqual(includeConfig);
|
||||
});
|
||||
|
||||
it('should the query contain the pagination', () => {
|
||||
const builder = new SearchQueryBuilderService(buildConfig({}), null);
|
||||
builder.userQuery = 'nuka cola quantum';
|
||||
const mockPagination = {
|
||||
maxItems: 10,
|
||||
skipCount: 0
|
||||
};
|
||||
builder.paging = mockPagination;
|
||||
const queryBody = builder.buildQuery();
|
||||
|
||||
expect(queryBody.paging).toEqual(mockPagination);
|
||||
});
|
||||
|
||||
it('should the query contain the scope in case it is defined', () => {
|
||||
const builder = new SearchQueryBuilderService(buildConfig({}), null);
|
||||
const mockScope = { locations: 'mock-location' };
|
||||
builder.userQuery = 'nuka cola quantum';
|
||||
builder.setScope(mockScope);
|
||||
const queryBody = builder.buildQuery();
|
||||
|
||||
expect(queryBody.scope).toEqual(mockScope);
|
||||
});
|
||||
});
|
||||
|
@@ -19,7 +19,7 @@ import { Component, Inject, ViewEncapsulation, ViewChild } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||
import { ExternalAlfrescoApiService, AlfrescoApiService, LoginDialogPanelComponent, SearchService, TranslationService, AuthenticationService, SitesService } from '@alfresco/adf-core';
|
||||
import { AttachFileWidgetDialogComponentData } from './attach-file-widget-dialog-component.interface';
|
||||
import { DocumentListService, ContentNodeSelectorService } from '@alfresco/adf-content-services';
|
||||
import { DocumentListService } from '@alfresco/adf-content-services';
|
||||
import { Node } from '@alfresco/js-api';
|
||||
|
||||
@Component({
|
||||
@@ -31,7 +31,6 @@ import { Node } from '@alfresco/js-api';
|
||||
AuthenticationService,
|
||||
DocumentListService,
|
||||
SitesService,
|
||||
ContentNodeSelectorService,
|
||||
SearchService,
|
||||
{ provide: AlfrescoApiService, useClass: ExternalAlfrescoApiService} ]
|
||||
})
|
||||
|
Reference in New Issue
Block a user