mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-06-30 18:15:11 +00:00
[ACS-4565] add search for categories tree in admin cc (#8279)
* ACS-4565 Added possibility to search categories * ACS-4565 Fixed unit test * ACS-4565 Fixed lint issue * ACS-4565 Removed extra empty line * ACS-4565 Replaced tags label with categories label in unit tests * ACS-4565 Replaced tags label with categories label in doc
This commit is contained in:
parent
477d49eaee
commit
02dcd4fb48
@ -13,11 +13,12 @@ Datasource service for category tree.
|
|||||||
|
|
||||||
### Methods
|
### Methods
|
||||||
|
|
||||||
- **getSubNodes**(parentNodeId: `string`, skipCount?: `number`, maxItems?: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TreeResponse<CategoryNode>`](../../../lib/content-services/src/lib/tree/models/tree-response.interface.ts)`>`<br/>
|
- **getSubNodes**(parentNodeId: `string`, skipCount?: `number`, maxItems?: `number`, name?: `string`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TreeResponse<CategoryNode>`](../../../lib/content-services/src/lib/tree/models/tree-response.interface.ts)`>`<br/>
|
||||||
Gets categories as nodes for category tree.
|
Gets categories as nodes for category tree.
|
||||||
- _parentNodeId:_ `string` - Identifier of a parent category
|
- _parentNodeId:_ `string` - Identifier of a parent category
|
||||||
- _skipCount:_ `number` - Number of top categories to skip
|
- _skipCount:_ `number` - Number of top categories to skip
|
||||||
- _maxItems:_ `number` - Maximum number of subcategories returned from Observable
|
- _maxItems:_ `number` - Maximum number of subcategories returned from Observable
|
||||||
|
- _name:_ `string` - Optional parameter which specifies if categories should be filtered out by name or not. If not specified then returns categories without filtering.
|
||||||
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TreeResponse<CategoryNode>`](../../../lib/content-services/src/lib/tree/models/tree-response.interface.ts)`>` - TreeResponse object containing pagination object and list on nodes
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`TreeResponse<CategoryNode>`](../../../lib/content-services/src/lib/tree/models/tree-response.interface.ts)`>` - TreeResponse object containing pagination object and list on nodes
|
||||||
|
|
||||||
## Details
|
## Details
|
||||||
|
@ -33,6 +33,12 @@ Manages categories in Content Services.
|
|||||||
Deletes category.
|
Deletes category.
|
||||||
- _categoryId:_ `string` - Identifier of a category
|
- _categoryId:_ `string` - Identifier of a category
|
||||||
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<void>` - Null object when the operation completes
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<void>` - Null object when the operation completes
|
||||||
|
- **searchCategories**(name: `string`, skipCount: `number`, maxItems?: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ResultSetPaging`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/search-rest-api/docs/ResultSetPaging.md)`>`<br/>
|
||||||
|
Searches categories by their name.
|
||||||
|
- _name:_ `string` - Value for name which should be used during searching categories.
|
||||||
|
- _skipCount:_ `number` - Specify how many first results should be skipped. Default 0.
|
||||||
|
- _maxItems:_ `number` - Specify max number of returned categories. Default is specified by UserPreferencesService.
|
||||||
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ResultSetPaging`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/search-rest-api/docs/ResultSetPaging.md)`>` - Found categories which name contains searched name.
|
||||||
|
|
||||||
## Details
|
## Details
|
||||||
|
|
||||||
|
@ -18,7 +18,8 @@ Accesses the Content Services Search API.
|
|||||||
- _term:_ `string` - Term to search for
|
- _term:_ `string` - Term to search for
|
||||||
- _options:_ [`SearchOptions`](lib/content-services/src/lib/search/services/search.service.ts) - (Optional) Options for delivery of the search results
|
- _options:_ [`SearchOptions`](lib/content-services/src/lib/search/services/search.service.ts) - (Optional) Options for delivery of the search results
|
||||||
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodePaging`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/content-rest-api/docs/NodePaging.md)`>` - List of nodes resulting from the search
|
- **Returns** [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`NodePaging`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/content-rest-api/docs/NodePaging.md)`>` - List of nodes resulting from the search
|
||||||
- **search**(searchTerm: `string`, maxResults: `number`, skipCount: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ResultSetPaging`](https://github.com/Alfresco/alfresco-js-api/blob/develop/src/api/search-rest-api/docs/ResultSetPaging.md)`>`<br/>
|
- **search**(searchTerm: `string`, maxResults: `number`, skipCount: `number`): [`Observable`](http://reactivex.io/documentation/observable.html)`<`[`ResultSetPaging`]
|
||||||
|
- `>`<br/>
|
||||||
Performs a search.
|
Performs a search.
|
||||||
- _searchTerm:_ `string` - Term to search for
|
- _searchTerm:_ `string` - Term to search for
|
||||||
- _maxResults:_ `number` - Maximum number of items in the list of results
|
- _maxResults:_ `number` - Maximum number of items in the list of results
|
||||||
|
@ -16,7 +16,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CategoryEntry, CategoryPaging } from '@alfresco/js-api';
|
import {
|
||||||
|
CategoryEntry,
|
||||||
|
CategoryPaging, Pagination, PathInfo, ResultNode,
|
||||||
|
ResultSetPaging,
|
||||||
|
ResultSetPagingList,
|
||||||
|
ResultSetRowEntry
|
||||||
|
} from '@alfresco/js-api';
|
||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
@ -26,6 +32,29 @@ export class CategoryServiceMock {
|
|||||||
return parentNodeId ? of(this.getChildrenLevelResponse(skipCount, maxItems)) : of(this.getRootLevelResponse(skipCount, maxItems));
|
return parentNodeId ? of(this.getChildrenLevelResponse(skipCount, maxItems)) : of(this.getRootLevelResponse(skipCount, maxItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public searchCategories(): Observable<ResultSetPaging> {
|
||||||
|
const result = new ResultSetPaging();
|
||||||
|
result.list = new ResultSetPagingList();
|
||||||
|
const category1 = new ResultSetRowEntry();
|
||||||
|
category1.entry = new ResultNode();
|
||||||
|
category1.entry.name = 'some name';
|
||||||
|
category1.entry.id = 'some id 1';
|
||||||
|
category1.entry.parentId = 'parent id 1';
|
||||||
|
category1.entry.path = new PathInfo();
|
||||||
|
category1.entry.path.name = '/categories/General';
|
||||||
|
const category2 = new ResultSetRowEntry();
|
||||||
|
category2.entry = new ResultNode();
|
||||||
|
category2.entry.name = 'some other name';
|
||||||
|
category2.entry.id = 'some id 2';
|
||||||
|
category2.entry.parentId = 'parent id 2';
|
||||||
|
category2.entry.path = new PathInfo();
|
||||||
|
category2.entry.path.name = '/categories/General/Language';
|
||||||
|
result.list.entries = [category1, category2];
|
||||||
|
result.list.pagination = new Pagination();
|
||||||
|
result.list.pagination.count = 2;
|
||||||
|
return of(result);
|
||||||
|
}
|
||||||
|
|
||||||
private getRootLevelResponse(skipCount?: number, maxItems?: number): CategoryPaging {
|
private getRootLevelResponse(skipCount?: number, maxItems?: number): CategoryPaging {
|
||||||
const rootCategoryEntry: CategoryEntry = {entry: {id: 'testId', name: 'testNode', parentId: '-root-', hasChildren: true}};
|
const rootCategoryEntry: CategoryEntry = {entry: {id: 'testId', name: 'testNode', parentId: '-root-', hasChildren: true}};
|
||||||
return {list: {pagination: {skipCount, maxItems, hasMoreItems: false}, entries: [rootCategoryEntry]}};
|
return {list: {pagination: {skipCount, maxItems, hasMoreItems: false}, entries: [rootCategoryEntry]}};
|
||||||
|
@ -18,13 +18,15 @@
|
|||||||
import { CoreTestingModule } from '@alfresco/adf-core';
|
import { CoreTestingModule } from '@alfresco/adf-core';
|
||||||
import { fakeAsync, TestBed } from '@angular/core/testing';
|
import { fakeAsync, TestBed } from '@angular/core/testing';
|
||||||
import { CategoryService } from '../services/category.service';
|
import { CategoryService } from '../services/category.service';
|
||||||
import { CategoryTreeDatasourceService } from './category-tree-datasource.service';
|
import { CategoryNode, CategoryTreeDatasourceService } from '@alfresco/adf-content-services';
|
||||||
import { CategoryServiceMock } from '../mock/category-mock.service';
|
import { CategoryServiceMock } from '../mock/category-mock.service';
|
||||||
import { TreeNodeType, TreeResponse } from '../../tree';
|
import { TreeNodeType, TreeResponse } from '../../tree';
|
||||||
import { CategoryNode } from '../models/category-node.interface';
|
import { EMPTY } from 'rxjs';
|
||||||
|
import { Pagination } from '@alfresco/js-api';
|
||||||
|
|
||||||
describe('CategoryTreeDatasourceService', () => {
|
describe('CategoryTreeDatasourceService', () => {
|
||||||
let categoryTreeDatasourceService: CategoryTreeDatasourceService;
|
let categoryTreeDatasourceService: CategoryTreeDatasourceService;
|
||||||
|
let categoryService: CategoryService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
@ -37,6 +39,7 @@ describe('CategoryTreeDatasourceService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
categoryTreeDatasourceService = TestBed.inject(CategoryTreeDatasourceService);
|
categoryTreeDatasourceService = TestBed.inject(CategoryTreeDatasourceService);
|
||||||
|
categoryService = TestBed.inject(CategoryService);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get root level categories', fakeAsync(() => {
|
it('should get root level categories', fakeAsync(() => {
|
||||||
@ -69,4 +72,43 @@ describe('CategoryTreeDatasourceService', () => {
|
|||||||
expect(treeResponse.entries[1].nodeType).toBe(TreeNodeType.LoadMoreNode);
|
expect(treeResponse.entries[1].nodeType).toBe(TreeNodeType.LoadMoreNode);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should call searchCategories on CategoryService if value of name parameter is defined', () => {
|
||||||
|
spyOn(categoryService, 'searchCategories').and.returnValue(EMPTY);
|
||||||
|
const skipCount = 10;
|
||||||
|
const maxItems = 100;
|
||||||
|
const name = 'name';
|
||||||
|
|
||||||
|
categoryTreeDatasourceService.getSubNodes('id', skipCount, maxItems, name);
|
||||||
|
expect(categoryService.searchCategories).toHaveBeenCalledWith(name, skipCount, maxItems);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return observable which emits correct categories', (done) => {
|
||||||
|
categoryTreeDatasourceService.getSubNodes('id', undefined, undefined, 'name')
|
||||||
|
.subscribe((response) => {
|
||||||
|
const pagination = new Pagination();
|
||||||
|
pagination.count = 2;
|
||||||
|
expect(response).toEqual({
|
||||||
|
pagination,
|
||||||
|
entries: [{
|
||||||
|
id: 'some id 1',
|
||||||
|
nodeName: 'some name',
|
||||||
|
parentId: 'parent id 1',
|
||||||
|
level: 0,
|
||||||
|
nodeType: TreeNodeType.RegularNode,
|
||||||
|
hasChildren: false,
|
||||||
|
isLoading: false
|
||||||
|
}, {
|
||||||
|
id: 'some id 2',
|
||||||
|
nodeName: 'Language/some other name',
|
||||||
|
parentId: 'parent id 2',
|
||||||
|
level: 0,
|
||||||
|
nodeType: TreeNodeType.RegularNode,
|
||||||
|
hasChildren: false,
|
||||||
|
isLoading: false
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -16,9 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { TreeNodeType } from '../../tree/models/tree-node.interface';
|
import { TreeNodeType, TreeResponse, TreeService } from '../../tree';
|
||||||
import { TreeResponse } from '../../tree/models/tree-response.interface';
|
|
||||||
import { TreeService } from '../../tree/services/tree.service';
|
|
||||||
import { CategoryNode } from '../models/category-node.interface';
|
import { CategoryNode } from '../models/category-node.interface';
|
||||||
import { CategoryService } from './category.service';
|
import { CategoryService } from './category.service';
|
||||||
import { CategoryEntry, CategoryPaging } from '@alfresco/js-api';
|
import { CategoryEntry, CategoryPaging } from '@alfresco/js-api';
|
||||||
@ -32,8 +30,8 @@ export class CategoryTreeDatasourceService extends TreeService<CategoryNode> {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public getSubNodes(parentNodeId: string, skipCount?: number, maxItems?: number): Observable<TreeResponse<CategoryNode>> {
|
public getSubNodes(parentNodeId: string, skipCount?: number, maxItems?: number, name?: string): Observable<TreeResponse<CategoryNode>> {
|
||||||
return this.categoryService.getSubcategories(parentNodeId, skipCount, maxItems).pipe(map((response: CategoryPaging) => {
|
return !name ? this.categoryService.getSubcategories(parentNodeId, skipCount, maxItems).pipe(map((response: CategoryPaging) => {
|
||||||
const parentNode: CategoryNode = this.getParentNode(parentNodeId);
|
const parentNode: CategoryNode = this.getParentNode(parentNodeId);
|
||||||
const nodesList: CategoryNode[] = response.list.entries.map((entry: CategoryEntry) => {
|
const nodesList: CategoryNode[] = response.list.entries.map((entry: CategoryEntry) => {
|
||||||
return {
|
return {
|
||||||
@ -60,6 +58,25 @@ export class CategoryTreeDatasourceService extends TreeService<CategoryNode> {
|
|||||||
}
|
}
|
||||||
const treeResponse: TreeResponse<CategoryNode> = {entries: nodesList, pagination: response.list.pagination};
|
const treeResponse: TreeResponse<CategoryNode> = {entries: nodesList, pagination: response.list.pagination};
|
||||||
return treeResponse;
|
return treeResponse;
|
||||||
|
})) : this.categoryService.searchCategories(name, skipCount, maxItems).pipe(map((pagingResult) => {
|
||||||
|
const nextAfterGeneralPathPartIndex = 3;
|
||||||
|
const pathSeparator = '/';
|
||||||
|
return {
|
||||||
|
entries: pagingResult.list.entries.map((category) => {
|
||||||
|
const path = category.entry.path.name.split(pathSeparator).slice(nextAfterGeneralPathPartIndex)
|
||||||
|
.join(pathSeparator);
|
||||||
|
return {
|
||||||
|
id: category.entry.id,
|
||||||
|
nodeName: path ? `${path}/${category.entry.name}` : category.entry.name,
|
||||||
|
parentId: category.entry.parentId,
|
||||||
|
level: 0,
|
||||||
|
nodeType: TreeNodeType.RegularNode,
|
||||||
|
hasChildren: false,
|
||||||
|
isLoading: false
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
pagination: pagingResult.list.pagination
|
||||||
|
};
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,22 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { CoreTestingModule } from '@alfresco/adf-core';
|
import { CoreTestingModule, UserPreferencesService } from '@alfresco/adf-core';
|
||||||
import { CategoryBody, CategoryEntry, CategoryPaging } from '@alfresco/js-api';
|
import {
|
||||||
|
CategoryBody,
|
||||||
|
CategoryEntry,
|
||||||
|
CategoryPaging, PathInfo,
|
||||||
|
RequestQuery, ResultNode,
|
||||||
|
ResultSetPaging,
|
||||||
|
ResultSetPagingList, ResultSetRowEntry
|
||||||
|
} from '@alfresco/js-api';
|
||||||
import { fakeAsync, TestBed } from '@angular/core/testing';
|
import { fakeAsync, TestBed } from '@angular/core/testing';
|
||||||
import { CategoryService } from './category.service';
|
import { CategoryService } from './category.service';
|
||||||
|
|
||||||
describe('CategoryService', () => {
|
describe('CategoryService', () => {
|
||||||
let categoryService: CategoryService;
|
let categoryService: CategoryService;
|
||||||
|
let userPreferencesService: UserPreferencesService;
|
||||||
|
|
||||||
const fakeParentCategoryId = 'testParentId';
|
const fakeParentCategoryId = 'testParentId';
|
||||||
const fakeCategoriesResponse: CategoryPaging = { list: { pagination: {}, entries: [] }};
|
const fakeCategoriesResponse: CategoryPaging = { list: { pagination: {}, entries: [] }};
|
||||||
const fakeCategoryEntry: CategoryEntry = { entry: { id: 'testId', name: 'testName' }};
|
const fakeCategoryEntry: CategoryEntry = { entry: { id: 'testId', name: 'testName' }};
|
||||||
@ -35,6 +44,7 @@ describe('CategoryService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
categoryService = TestBed.inject(CategoryService);
|
categoryService = TestBed.inject(CategoryService);
|
||||||
|
userPreferencesService = TestBed.inject(UserPreferencesService);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch categories with provided parentId', fakeAsync(() => {
|
it('should fetch categories with provided parentId', fakeAsync(() => {
|
||||||
@ -71,4 +81,66 @@ describe('CategoryService', () => {
|
|||||||
expect(deleteSpy).toHaveBeenCalledOnceWith(fakeParentCategoryId);
|
expect(deleteSpy).toHaveBeenCalledOnceWith(fakeParentCategoryId);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
describe('searchCategories', () => {
|
||||||
|
const defaultMaxItems = 25;
|
||||||
|
|
||||||
|
let result: ResultSetPaging;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOnProperty(userPreferencesService, 'paginationSize').and.returnValue(defaultMaxItems);
|
||||||
|
result = new ResultSetPaging();
|
||||||
|
result.list = new ResultSetPagingList();
|
||||||
|
const category = new ResultSetRowEntry();
|
||||||
|
category.entry = new ResultNode();
|
||||||
|
category.entry.name = 'some name';
|
||||||
|
category.entry.path = new PathInfo();
|
||||||
|
category.entry.path.name = '/categories/General';
|
||||||
|
result.list.entries = [category];
|
||||||
|
spyOn(categoryService.searchApi, 'search').and.returnValue(Promise.resolve(result));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call search on searchApi with correct parameters when specified all parameters', () => {
|
||||||
|
const name = 'name';
|
||||||
|
const skipCount = 10;
|
||||||
|
const maxItems = 100;
|
||||||
|
|
||||||
|
categoryService.searchCategories(name, skipCount, maxItems);
|
||||||
|
expect(categoryService.searchApi.search).toHaveBeenCalledWith({
|
||||||
|
query: {
|
||||||
|
language: RequestQuery.LanguageEnum.Afts,
|
||||||
|
query: `cm:name:"*${name}*" AND TYPE:'cm:category' AND PATH:"/cm:categoryRoot/cm:generalclassifiable//*"`
|
||||||
|
},
|
||||||
|
paging: {
|
||||||
|
skipCount,
|
||||||
|
maxItems
|
||||||
|
},
|
||||||
|
include: ['path']
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call search on searchApi with default parameters when skipped optional parameters', () => {
|
||||||
|
const name = 'name';
|
||||||
|
|
||||||
|
categoryService.searchCategories(name);
|
||||||
|
expect(categoryService.searchApi.search).toHaveBeenCalledWith({
|
||||||
|
query: {
|
||||||
|
language: RequestQuery.LanguageEnum.Afts,
|
||||||
|
query: `cm:name:"*${name}*" AND TYPE:'cm:category' AND PATH:"/cm:categoryRoot/cm:generalclassifiable//*"`
|
||||||
|
},
|
||||||
|
paging: {
|
||||||
|
skipCount: 0,
|
||||||
|
maxItems: defaultMaxItems
|
||||||
|
},
|
||||||
|
include: ['path']
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return observable which emits paging object for categories', (done) => {
|
||||||
|
categoryService.searchCategories('name').subscribe((paging) => {
|
||||||
|
expect(paging).toBe(result);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -16,20 +16,34 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { AlfrescoApiService } from '@alfresco/adf-core';
|
import { AlfrescoApiService, UserPreferencesService } from '@alfresco/adf-core';
|
||||||
import { CategoriesApi, CategoryBody, CategoryEntry, CategoryPaging } from '@alfresco/js-api';
|
import {
|
||||||
|
CategoriesApi,
|
||||||
|
CategoryBody,
|
||||||
|
CategoryEntry,
|
||||||
|
CategoryPaging,
|
||||||
|
RequestQuery,
|
||||||
|
ResultSetPaging,
|
||||||
|
SearchApi
|
||||||
|
} from '@alfresco/js-api';
|
||||||
import { from, Observable } from 'rxjs';
|
import { from, Observable } from 'rxjs';
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class CategoryService {
|
export class CategoryService {
|
||||||
private _categoriesApi: CategoriesApi;
|
private _categoriesApi: CategoriesApi;
|
||||||
|
private _searchApi: SearchApi;
|
||||||
|
|
||||||
get categoriesApi(): CategoriesApi {
|
get categoriesApi(): CategoriesApi {
|
||||||
this._categoriesApi = this._categoriesApi ?? new CategoriesApi(this.apiService.getInstance());
|
this._categoriesApi = this._categoriesApi ?? new CategoriesApi(this.apiService.getInstance());
|
||||||
return this._categoriesApi;
|
return this._categoriesApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(private apiService: AlfrescoApiService) {}
|
get searchApi(): SearchApi {
|
||||||
|
this._searchApi = this._searchApi ?? new SearchApi(this.apiService.getInstance());
|
||||||
|
return this._searchApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(private apiService: AlfrescoApiService, private userPreferencesService: UserPreferencesService) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get subcategories of a given parent category
|
* Get subcategories of a given parent category
|
||||||
@ -74,4 +88,27 @@ export class CategoryService {
|
|||||||
deleteCategory(categoryId: string): Observable<void> {
|
deleteCategory(categoryId: string): Observable<void> {
|
||||||
return from(this.categoriesApi.deleteCategory(categoryId));
|
return from(this.categoriesApi.deleteCategory(categoryId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches categories by their name.
|
||||||
|
*
|
||||||
|
* @param name Value for name which should be used during searching categories.
|
||||||
|
* @param skipCount Specify how many first results should be skipped. Default 0.
|
||||||
|
* @param maxItems Specify max number of returned categories. Default is specified by UserPreferencesService.
|
||||||
|
* @return Observable<ResultSetPaging> Found categories which name contains searched name.
|
||||||
|
*/
|
||||||
|
searchCategories(name: string, skipCount = 0, maxItems?: number): Observable<ResultSetPaging> {
|
||||||
|
maxItems = maxItems || this.userPreferencesService.paginationSize;
|
||||||
|
return from(this.searchApi.search({
|
||||||
|
query: {
|
||||||
|
language: RequestQuery.LanguageEnum.Afts,
|
||||||
|
query: `cm:name:"*${name}*" AND TYPE:'cm:category' AND PATH:"/cm:categoryRoot/cm:generalclassifiable//*"`
|
||||||
|
},
|
||||||
|
paging: {
|
||||||
|
skipCount,
|
||||||
|
maxItems
|
||||||
|
},
|
||||||
|
include: ['path']
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,9 +156,9 @@ describe('TreeComponent', () => {
|
|||||||
it('should clear the selection and load root nodes on refresh', () => {
|
it('should clear the selection and load root nodes on refresh', () => {
|
||||||
const selectionSpy = spyOn(component.treeNodesSelection, 'clear');
|
const selectionSpy = spyOn(component.treeNodesSelection, 'clear');
|
||||||
const getNodesSpy = spyOn(component.treeService, 'getSubNodes').and.callThrough();
|
const getNodesSpy = spyOn(component.treeService, 'getSubNodes').and.callThrough();
|
||||||
component.refreshTree(0, 25);
|
component.refreshTree(0, 25, 'some term');
|
||||||
expect(selectionSpy).toHaveBeenCalled();
|
expect(selectionSpy).toHaveBeenCalled();
|
||||||
expect(getNodesSpy).toHaveBeenCalledWith('-root-', 0, 25);
|
expect(getNodesSpy).toHaveBeenCalledWith('-root-', 0, 25, 'some term');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call correct server method on collapsing node', () => {
|
it('should call correct server method on collapsing node', () => {
|
||||||
|
@ -122,11 +122,12 @@ export class TreeComponent<T extends TreeNode> implements OnInit {
|
|||||||
*
|
*
|
||||||
* @param skipCount Number of root nodes to skip.
|
* @param skipCount Number of root nodes to skip.
|
||||||
* @param maxItems Maximum number of nodes returned from Observable.
|
* @param maxItems Maximum number of nodes returned from Observable.
|
||||||
|
* @param searchTerm Specifies if categories should be filtered out by name or not. If not specified then returns categories without filtering.
|
||||||
*/
|
*/
|
||||||
public refreshTree(skipCount?: number, maxItems?: number): void {
|
public refreshTree(skipCount?: number, maxItems?: number, searchTerm?: string): void {
|
||||||
this.loadingRootSource.next(true);
|
this.loadingRootSource.next(true);
|
||||||
this.treeNodesSelection.clear();
|
this.treeNodesSelection.clear();
|
||||||
this.treeService.getSubNodes('-root-', skipCount, maxItems).subscribe((response: TreeResponse<T>) => {
|
this.treeService.getSubNodes('-root-', skipCount, maxItems, searchTerm).subscribe((response: TreeResponse<T>) => {
|
||||||
this.treeService.treeNodes = response.entries;
|
this.treeService.treeNodes = response.entries;
|
||||||
this.treeNodesSelection.deselect(...response.entries);
|
this.treeNodesSelection.deselect(...response.entries);
|
||||||
this.paginationChanged.emit(response.pagination);
|
this.paginationChanged.emit(response.pagination);
|
||||||
|
@ -42,7 +42,7 @@ export abstract class TreeService<T extends TreeNode> extends DataSource<T> {
|
|||||||
this.treeNodes = [];
|
this.treeNodes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract getSubNodes(parentNodeId: string, skipCount?: number, maxItems?: number): Observable<TreeResponse<T>>;
|
public abstract getSubNodes(parentNodeId: string, skipCount?: number, maxItems?: number, searchTerm?: string): Observable<TreeResponse<T>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expands node applying subnodes to it.
|
* Expands node applying subnodes to it.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user