mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-26 17:24:56 +00:00
[ADF-2242] Search on custom sources is not working. (#2904)
* [ADF-2242] Search on custom sources is not working. fix search on custom sources * [ADF-2242] added unit tests * [ADF-2242] reverted change * [ADF-2242] simplify code on search method and make extra call only when having custom dropdown defined
This commit is contained in:
parent
5ee9b09a21
commit
78c6a68e51
@ -18,7 +18,7 @@
|
|||||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { MinimalNodeEntryEntity, SiteEntry } from 'alfresco-js-api';
|
import { MinimalNodeEntryEntity, SiteEntry, SitePaging } from 'alfresco-js-api';
|
||||||
import {
|
import {
|
||||||
AlfrescoApiService,
|
AlfrescoApiService,
|
||||||
ContentService,
|
ContentService,
|
||||||
@ -59,7 +59,9 @@ describe('ContentNodeSelectorComponent', () => {
|
|||||||
let component: ContentNodeSelectorPanelComponent;
|
let component: ContentNodeSelectorPanelComponent;
|
||||||
let fixture: ComponentFixture<ContentNodeSelectorPanelComponent>;
|
let fixture: ComponentFixture<ContentNodeSelectorPanelComponent>;
|
||||||
let searchService: SearchService;
|
let searchService: SearchService;
|
||||||
|
let contentNodeSelectorService: ContentNodeSelectorService;
|
||||||
let searchSpy: jasmine.Spy;
|
let searchSpy: jasmine.Spy;
|
||||||
|
let cnSearchSpy: jasmine.Spy;
|
||||||
|
|
||||||
let _observer: Observer<NodePaging>;
|
let _observer: Observer<NodePaging>;
|
||||||
|
|
||||||
@ -124,6 +126,8 @@ describe('ContentNodeSelectorComponent', () => {
|
|||||||
component.debounceSearch = 0;
|
component.debounceSearch = 0;
|
||||||
|
|
||||||
searchService = TestBed.get(SearchService);
|
searchService = TestBed.get(SearchService);
|
||||||
|
contentNodeSelectorService = TestBed.get(ContentNodeSelectorService);
|
||||||
|
cnSearchSpy = spyOn(contentNodeSelectorService, 'search').and.callThrough();
|
||||||
searchSpy = spyOn(searchService, 'searchByQueryBody').and.callFake(() => {
|
searchSpy = spyOn(searchService, 'searchByQueryBody').and.callFake(() => {
|
||||||
return Observable.create((observer: Observer<NodePaging>) => {
|
return Observable.create((observer: Observer<NodePaging>) => {
|
||||||
_observer = observer;
|
_observer = observer;
|
||||||
@ -259,6 +263,7 @@ describe('ContentNodeSelectorComponent', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('Search functionality', () => {
|
describe('Search functionality', () => {
|
||||||
|
let getCorrespondingNodeIdsSpy;
|
||||||
|
|
||||||
function defaultSearchOptions(searchTerm, rootNodeId = undefined, skipCount = 0) {
|
function defaultSearchOptions(searchTerm, rootNodeId = undefined, skipCount = 0) {
|
||||||
|
|
||||||
@ -292,6 +297,13 @@ describe('ContentNodeSelectorComponent', () => {
|
|||||||
|
|
||||||
spyOn(documentListService, 'getFolderNode').and.returnValue(Promise.resolve(expectedDefaultFolderNode));
|
spyOn(documentListService, 'getFolderNode').and.returnValue(Promise.resolve(expectedDefaultFolderNode));
|
||||||
spyOn(component.documentList, 'loadFolderNodesByFolderNodeId').and.returnValue(Promise.resolve());
|
spyOn(component.documentList, 'loadFolderNodesByFolderNodeId').and.returnValue(Promise.resolve());
|
||||||
|
getCorrespondingNodeIdsSpy = spyOn(component.documentList, 'getCorrespondingNodeIds').and
|
||||||
|
.callFake(id => {
|
||||||
|
if (id === '-sites-') {
|
||||||
|
return new Promise((resolve) => resolve(['123456testId', '09876543testId']));
|
||||||
|
}
|
||||||
|
return new Promise((resolve) => resolve([id]));
|
||||||
|
});
|
||||||
|
|
||||||
component.currentFolderId = 'cat-girl-nuku-nuku';
|
component.currentFolderId = 'cat-girl-nuku-nuku';
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@ -324,9 +336,82 @@ describe('ContentNodeSelectorComponent', () => {
|
|||||||
|
|
||||||
component.siteChanged(<SiteEntry> { entry: { guid: 'namek' } });
|
component.siteChanged(<SiteEntry> { entry: { guid: 'namek' } });
|
||||||
|
|
||||||
expect(searchSpy.calls.count()).toBe(2, 'Search count should be two after the site change');
|
fixture.whenStable().then(() => {
|
||||||
expect(searchSpy.calls.argsFor(1)).toEqual([defaultSearchOptions('vegeta', 'namek')] );
|
expect(searchSpy.calls.count()).toBe(2, 'Search count should be two after the site change');
|
||||||
done();
|
expect(searchSpy.calls.argsFor(1)).toEqual([defaultSearchOptions('vegeta', 'namek')] );
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the content node selector\'s search with the right parameters on changing the site selectbox\'s value', (done) => {
|
||||||
|
typeToSearchBox('vegeta');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(cnSearchSpy.calls.count()).toBe(1);
|
||||||
|
|
||||||
|
component.siteChanged(<SiteEntry> { entry: { guid: '-sites-' } });
|
||||||
|
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(cnSearchSpy).toHaveBeenCalled();
|
||||||
|
expect(cnSearchSpy.calls.count()).toBe(2);
|
||||||
|
expect(cnSearchSpy).toHaveBeenCalledWith('vegeta', '-sites-', 0, 25);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the content node selector\'s search with the right parameters on changing the site selectbox\'s value from a custom dropdown menu', (done) => {
|
||||||
|
component.dropdownSiteList = <SitePaging> {list: {entries: [<SiteEntry> { entry: { guid: '-sites-' } }, <SiteEntry> { entry: { guid: 'namek' } }]}};
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
typeToSearchBox('vegeta');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(cnSearchSpy.calls.count()).toBe(1);
|
||||||
|
|
||||||
|
component.siteChanged(<SiteEntry> { entry: { guid: '-sites-' } });
|
||||||
|
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(cnSearchSpy).toHaveBeenCalled();
|
||||||
|
expect(cnSearchSpy.calls.count()).toBe(2);
|
||||||
|
expect(cnSearchSpy).toHaveBeenCalledWith('vegeta', '-sites-', 0, 25, ['123456testId', '09876543testId']);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get the corresponding node ids before the search call on changing the site selectbox\'s value from a custom dropdown menu', (done) => {
|
||||||
|
component.dropdownSiteList = <SitePaging> {list: {entries: [<SiteEntry> { entry: { guid: '-sites-' } }, <SiteEntry> { entry: { guid: 'namek' } }]}};
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
typeToSearchBox('vegeta');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(getCorrespondingNodeIdsSpy.calls.count()).toBe(1, 'getCorrespondingNodeIdsSpy calls count should be one after only one search');
|
||||||
|
|
||||||
|
component.siteChanged(<SiteEntry> { entry: { guid: 'namek' } });
|
||||||
|
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(getCorrespondingNodeIdsSpy.calls.count()).toBe(2, 'getCorrespondingNodeIdsSpy calls count should be two after the site change');
|
||||||
|
expect(getCorrespondingNodeIdsSpy.calls.allArgs()).toEqual([[undefined], ['namek']]);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT get the corresponding node ids before the search call on changing the site selectbox\'s value from default dropdown menu', (done) => {
|
||||||
|
typeToSearchBox('vegeta');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(getCorrespondingNodeIdsSpy.calls.count()).toBe(0, 'getCorrespondingNodeIdsSpy should not be called');
|
||||||
|
|
||||||
|
component.siteChanged(<SiteEntry> { entry: { guid: 'namek' } });
|
||||||
|
|
||||||
|
fixture.whenStable().then(() => {
|
||||||
|
expect(getCorrespondingNodeIdsSpy).not.toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
});
|
||||||
}, 300);
|
}, 300);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -523,7 +608,9 @@ describe('ContentNodeSelectorComponent', () => {
|
|||||||
|
|
||||||
component.getNextPageOfSearch({ skipCount });
|
component.getNextPageOfSearch({ skipCount });
|
||||||
|
|
||||||
expect(searchSpy).toHaveBeenCalledWith(defaultSearchOptions('kakarot', undefined, skipCount));
|
fixture.whenStable().then(() => {
|
||||||
|
expect(searchSpy).toHaveBeenCalledWith(defaultSearchOptions('kakarot', undefined, skipCount));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be shown when pagination\'s hasMoreItems is true', () => {
|
it('should be shown when pagination\'s hasMoreItems is true', () => {
|
||||||
|
@ -220,8 +220,19 @@ export class ContentNodeSelectorPanelComponent implements OnInit {
|
|||||||
private querySearch(): void {
|
private querySearch(): void {
|
||||||
this.loadingSearchResults = true;
|
this.loadingSearchResults = true;
|
||||||
|
|
||||||
this.contentNodeSelectorService.search(this.searchTerm, this.siteId, this.skipCount, this.pageSize)
|
if (this.dropdownSiteList) {
|
||||||
.subscribe(this.showSearchResults.bind(this));
|
this.documentList.getCorrespondingNodeIds(this.siteId)
|
||||||
|
.then(nodeIds => {
|
||||||
|
this.contentNodeSelectorService.search(this.searchTerm, this.siteId, this.skipCount, this.pageSize, nodeIds)
|
||||||
|
.subscribe(this.showSearchResults.bind(this));
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.showSearchResults({list: {entries: []}});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.contentNodeSelectorService.search(this.searchTerm, this.siteId, this.skipCount, this.pageSize)
|
||||||
|
.subscribe(this.showSearchResults.bind(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,4 +103,22 @@ describe('ContentNodeSelectorService', () => {
|
|||||||
|
|
||||||
expect(search.query.filterQueries).not.toContain({ query: 'ANCESTOR:\'workspace://SpacesStore/null\'' });
|
expect(search.query.filterQueries).not.toContain({ query: 'ANCESTOR:\'workspace://SpacesStore/null\'' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should filter for the extra provided ancestors if defined', () => {
|
||||||
|
service.search('nuka cola quantum', 'diamond-city', 0, 25, ['extra-diamond-city']);
|
||||||
|
|
||||||
|
expect(search.query.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', () => {
|
||||||
|
service.search('nuka cola quantum', 'diamond-city', 0, 25, []);
|
||||||
|
|
||||||
|
expect(search.query.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', () => {
|
||||||
|
service.search('nuka cola quantum', 'diamond-city', 0, 25, ['diamond-city']);
|
||||||
|
|
||||||
|
expect(search.query.filterQueries).toContain({ query: 'ANCESTOR:\'workspace://SpacesStore/diamond-city\'' });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -32,13 +32,26 @@ export class ContentNodeSelectorService {
|
|||||||
* Performs a search for content node selection
|
* Performs a search for content node selection
|
||||||
*
|
*
|
||||||
* @param searchTerm The term to search for
|
* @param searchTerm The term to search for
|
||||||
* @param skipCount From where to start the loading
|
|
||||||
* @param rootNodeId The root is to start the search from
|
* @param rootNodeId The root is to start the search from
|
||||||
|
* @param skipCount From where to start the loading
|
||||||
* @param maxItems How many items to load
|
* @param maxItems How many items to load
|
||||||
|
* @param [extraNodeIds] List of extra node ids to search from. This last parameter is necessary when
|
||||||
|
* the rootNodeId is one of the supported aliases (e.g. '-my-', '-root-', '-mysites-', etc.)
|
||||||
|
* and search is not supported for that alias, but can be performed on its corresponding nodes.
|
||||||
*/
|
*/
|
||||||
public search(searchTerm: string, rootNodeId: string = null, skipCount: number = 0, maxItems: number = 25): Observable<NodePaging> {
|
public search(searchTerm: string, rootNodeId: string = null, skipCount: number = 0, maxItems: number = 25, extraNodeIds?: string[]): Observable<NodePaging> {
|
||||||
|
|
||||||
const parentFiltering = rootNodeId ? [ { query: `ANCESTOR:'workspace://SpacesStore/${rootNodeId}'` } ] : [];
|
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}` } ] : [];
|
||||||
|
|
||||||
let defaultSearchNode: any = {
|
let defaultSearchNode: any = {
|
||||||
query: {
|
query: {
|
||||||
|
@ -671,33 +671,7 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
|
|||||||
}
|
}
|
||||||
|
|
||||||
private loadRecent(merge: boolean = false): void {
|
private loadRecent(merge: boolean = false): void {
|
||||||
this.apiService.peopleApi.getPerson('-me-')
|
this.getRecentFiles('-me-')
|
||||||
.then((person: PersonEntry) => {
|
|
||||||
const username = person.entry.id;
|
|
||||||
const query = {
|
|
||||||
query: {
|
|
||||||
query: '*',
|
|
||||||
language: 'afts'
|
|
||||||
},
|
|
||||||
filterQueries: [
|
|
||||||
{ query: `cm:modified:[NOW/DAY-30DAYS TO NOW/DAY+1DAY]` },
|
|
||||||
{ query: `cm:modifier:${username} OR cm:creator:${username}` },
|
|
||||||
{ query: `TYPE:"content" AND -TYPE:"app:filelink" AND -TYPE:"fm:post"` }
|
|
||||||
],
|
|
||||||
include: ['path', 'properties', 'allowableOperations'],
|
|
||||||
sort: [{
|
|
||||||
type: 'FIELD',
|
|
||||||
field: 'cm:modified',
|
|
||||||
ascending: false
|
|
||||||
}],
|
|
||||||
paging: {
|
|
||||||
maxItems: this.maxItems,
|
|
||||||
skipCount: this.skipCount
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return this.apiService.searchApi.search(query);
|
|
||||||
})
|
|
||||||
.then((page: NodePaging) => this.onPageLoaded(page, merge))
|
.then((page: NodePaging) => this.onPageLoaded(page, merge))
|
||||||
.catch(error => this.error.emit(error));
|
.catch(error => this.error.emit(error));
|
||||||
}
|
}
|
||||||
@ -930,4 +904,68 @@ export class DocumentListComponent implements OnInit, OnChanges, OnDestroy, Afte
|
|||||||
this.contextActionHandlerSubscription = null;
|
this.contextActionHandlerSubscription = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCorrespondingNodeIds(nodeId: string): Promise<string[]> {
|
||||||
|
if (nodeId === '-trashcan-') {
|
||||||
|
return this.apiService.nodesApi.getDeletedNodes()
|
||||||
|
.then(result => result.list.entries.map(node => node.entry.id));
|
||||||
|
|
||||||
|
} else if (nodeId === '-sharedlinks-') {
|
||||||
|
return this.apiService.sharedLinksApi.findSharedLinks()
|
||||||
|
.then(result => result.list.entries.map(node => node.entry.nodeId));
|
||||||
|
|
||||||
|
} else if (nodeId === '-sites-') {
|
||||||
|
return this.apiService.sitesApi.getSites()
|
||||||
|
.then(result => result.list.entries.map(node => node.entry.guid));
|
||||||
|
|
||||||
|
} else if (nodeId === '-mysites-') {
|
||||||
|
return this.apiService.peopleApi.getSiteMembership('-me-')
|
||||||
|
.then(result => result.list.entries.map(node => node.entry.guid));
|
||||||
|
|
||||||
|
} else if (nodeId === '-favorites-') {
|
||||||
|
return this.apiService.favoritesApi.getFavorites('-me-')
|
||||||
|
.then(result => result.list.entries.map(node => node.entry.targetGuid));
|
||||||
|
|
||||||
|
} else if (nodeId === '-recent-') {
|
||||||
|
return this.getRecentFiles('-me-')
|
||||||
|
.then(result => result.list.entries.map(node => node.entry.id));
|
||||||
|
|
||||||
|
} else if (nodeId) {
|
||||||
|
return this.documentListService.getFolderNode(nodeId)
|
||||||
|
.then(node => [ node.id ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
resolve([]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getRecentFiles(personId: string): Promise<NodePaging> {
|
||||||
|
return this.apiService.peopleApi.getPerson(personId)
|
||||||
|
.then((person: PersonEntry) => {
|
||||||
|
const username = person.entry.id;
|
||||||
|
const query = {
|
||||||
|
query: {
|
||||||
|
query: '*',
|
||||||
|
language: 'afts'
|
||||||
|
},
|
||||||
|
filterQueries: [
|
||||||
|
{ query: `cm:modified:[NOW/DAY-30DAYS TO NOW/DAY+1DAY]` },
|
||||||
|
{ query: `cm:modifier:${username} OR cm:creator:${username}` },
|
||||||
|
{ query: `TYPE:"content" AND -TYPE:"app:filelink" AND -TYPE:"fm:post"` }
|
||||||
|
],
|
||||||
|
include: ['path', 'properties', 'allowableOperations'],
|
||||||
|
sort: [{
|
||||||
|
type: 'FIELD',
|
||||||
|
field: 'cm:modified',
|
||||||
|
ascending: false
|
||||||
|
}],
|
||||||
|
paging: {
|
||||||
|
maxItems: this.maxItems,
|
||||||
|
skipCount: this.skipCount
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return this.apiService.searchApi.search(query);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user