multiple dsoType allowed in search & in selector modals

This commit is contained in:
Marie Verdonck
2020-08-06 17:13:32 +02:00
parent cc618ebadd
commit e89d064934
24 changed files with 42 additions and 35 deletions

View File

@@ -133,7 +133,7 @@ export class CollectionItemMapperComponent implements OnInit {
return this.searchService.search(Object.assign(new PaginatedSearchOptions(options), {
query: this.buildQuery(collectionRD.payload.id, options.query),
scope: undefined,
dsoType: DSpaceObjectType.ITEM,
dsoTypes: [DSpaceObjectType.ITEM],
sort: this.defaultSortOptions
}), 10000).pipe(
toDSpaceObjectListRD(),

View File

@@ -87,7 +87,7 @@ export class CollectionPageComponent implements OnInit {
scope: id,
pagination: dto.paginationConfig,
sort: dto.sortConfig,
dsoType: DSpaceObjectType.ITEM
dsoTypes: [DSpaceObjectType.ITEM]
})).pipe(toDSpaceObjectListRD()) as Observable<RemoteData<PaginatedList<Item>>>
}),
startWith(undefined) // Make sure switching pages shows loading component

View File

@@ -125,7 +125,7 @@ export class ItemCollectionMapperComponent implements OnInit {
switchMap(([itemCollectionsRD, owningCollectionRD, searchOptions]) => {
return this.searchService.search(Object.assign(new PaginatedSearchOptions(searchOptions), {
query: this.buildQuery([...itemCollectionsRD.payload.page, owningCollectionRD.payload], searchOptions.query),
dsoType: DSpaceObjectType.COLLECTION
dsoTypes: [DSpaceObjectType.COLLECTION]
}), 10000).pipe(
toDSpaceObjectListRD(),
startWith(undefined)

View File

@@ -79,7 +79,7 @@ export class ItemMoveComponent implements OnInit {
loadSuggestions(query): void {
this.collectionSearchResults = this.searchService.search(new PaginatedSearchOptions({
pagination: this.pagination,
dsoType: DSpaceObjectType.COLLECTION,
dsoTypes: [DSpaceObjectType.COLLECTION],
query: query
})).pipe(
first(),

View File

@@ -2,14 +2,14 @@
<input type="search"
class="form-control"
(click)="$event.stopPropagation();"
placeholder="{{'dso-selector.placeholder' | translate: { type: type.toString().toLowerCase() } }}"
placeholder="{{'dso-selector.placeholder' | translate: { type: typesString } }}"
[formControl]="input" dsAutoFocus (keyup.enter)="selectSingleResult()">
</div>
<div class="dropdown-divider"></div>
<div class="scrollable-menu list-group">
<button class="list-group-item list-group-item-action border-0 disabled"
*ngIf="(listEntries$ | async)?.payload.page.length == 0">
{{'dso-selector.no-results' | translate: { type: type.toString().toLowerCase() } }}
{{'dso-selector.no-results' | translate: { type: typesString } }}
</button>
<button *ngFor="let listEntry of (listEntries$ | async)?.payload.page"
class="list-group-item list-group-item-action border-0 list-entry"

View File

@@ -49,7 +49,7 @@ describe('DSOSelectorComponent', () => {
component = fixture.componentInstance;
debugElement = fixture.debugElement;
component.currentDSOId = currentDSOId;
component.type = type;
component.types = [type];
fixture.detectChanges();
});
@@ -61,7 +61,7 @@ describe('DSOSelectorComponent', () => {
it('should initially call the search method on the SearchService with the given DSO uuid', () => {
const searchOptions = new PaginatedSearchOptions({
query: currentDSOId,
dsoType: type,
dsoTypes: [type],
pagination: (component as any).defaultPagination
});

View File

@@ -43,9 +43,12 @@ export class DSOSelectorComponent implements OnInit {
@Input() currentDSOId: string;
/**
* The type of DSpace objects this components shows a list of
* The types of DSpace objects this components shows a list of
*/
@Input() type: DSpaceObjectType;
@Input() types: DSpaceObjectType[];
// list of allowed selectable dsoTypes
typesString: string;
/**
* Emits the selected Object when a user selects it in the list
@@ -91,6 +94,7 @@ export class DSOSelectorComponent implements OnInit {
*/
ngOnInit(): void {
this.input.setValue(this.currentDSOId);
this.typesString = this.types.map((type: string) => type.toString().toLowerCase()).join(', ');
this.listEntries$ = this.input.valueChanges
.pipe(
debounceTime(this.debounceTime),
@@ -99,7 +103,7 @@ export class DSOSelectorComponent implements OnInit {
return this.searchService.search(
new PaginatedSearchOptions({
query: query,
dsoType: this.type !== DSpaceObjectType.DSPACEOBJECT ? this.type : null,
dsoTypes: this.types,
pagination: this.defaultPagination
})
)

View File

@@ -20,7 +20,7 @@ import { DSOSelectorModalWrapperComponent, SelectorActionType } from '../dso-sel
})
export class CreateCollectionParentSelectorComponent extends DSOSelectorModalWrapperComponent implements OnInit {
objectType = DSpaceObjectType.COLLECTION;
selectorType = DSpaceObjectType.COMMUNITY;
selectorTypes = [DSpaceObjectType.COMMUNITY];
action = SelectorActionType.CREATE;
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) {

View File

@@ -14,6 +14,6 @@
</h3>
<h5 class="px-2">{{'dso-selector.create.community.sub-level' | translate}}</h5>
<ds-dso-selector [currentDSOId]="dsoRD?.payload.uuid" [type]="selectorType" (onSelect)="selectObject($event)"></ds-dso-selector>
<ds-dso-selector [currentDSOId]="dsoRD?.payload.uuid" [types]="[selectorType]" (onSelect)="selectObject($event)"></ds-dso-selector>
</div>
</div>

View File

@@ -27,7 +27,7 @@ import {
})
export class CreateCommunityParentSelectorComponent extends DSOSelectorModalWrapperComponent implements OnInit {
objectType = DSpaceObjectType.COMMUNITY;
selectorType = DSpaceObjectType.COMMUNITY;
selectorTypes = [DSpaceObjectType.COMMUNITY];
action = SelectorActionType.CREATE;
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) {

View File

@@ -18,7 +18,7 @@ import { DSOSelectorModalWrapperComponent, SelectorActionType } from '../dso-sel
})
export class CreateItemParentSelectorComponent extends DSOSelectorModalWrapperComponent implements OnInit {
objectType = DSpaceObjectType.ITEM;
selectorType = DSpaceObjectType.COLLECTION;
selectorTypes = [DSpaceObjectType.COLLECTION];
action = SelectorActionType.CREATE;
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) {

View File

@@ -5,6 +5,6 @@
</button>
</div>
<div class="modal-body">
<ds-dso-selector [currentDSOId]="dsoRD?.payload.uuid ? 'search.resourceid:' + dsoRD?.payload.uuid : null" [type]="selectorType" (onSelect)="selectObject($event)"></ds-dso-selector>
<ds-dso-selector [currentDSOId]="dsoRD?.payload.uuid ? 'search.resourceid:' + dsoRD?.payload.uuid : null" [types]="selectorTypes" (onSelect)="selectObject($event)"></ds-dso-selector>
</div>
</div>

View File

@@ -124,7 +124,7 @@ describe('DSOSelectorModalWrapperComponent', () => {
})
class TestComponent extends DSOSelectorModalWrapperComponent implements OnInit {
objectType = DSpaceObjectType.ITEM;
selectorType = DSpaceObjectType.ITEM;
selectorTypes = [DSpaceObjectType.ITEM];
action = SelectorActionType.EDIT;
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute) {

View File

@@ -29,9 +29,9 @@ export abstract class DSOSelectorModalWrapperComponent implements OnInit {
objectType: DSpaceObjectType;
/**
* The type of DSO that can be selected from this list
* The types of DSO that can be selected from this list
*/
selectorType: DSpaceObjectType;
selectorTypes: DSpaceObjectType[];
/**
* The type of action to perform

View File

@@ -20,7 +20,7 @@ import {
})
export class EditCollectionSelectorComponent extends DSOSelectorModalWrapperComponent implements OnInit {
objectType = DSpaceObjectType.COLLECTION;
selectorType = DSpaceObjectType.COLLECTION;
selectorTypes = [DSpaceObjectType.COLLECTION];
action = SelectorActionType.EDIT;
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) {

View File

@@ -21,7 +21,7 @@ import {
export class EditCommunitySelectorComponent extends DSOSelectorModalWrapperComponent implements OnInit {
objectType = DSpaceObjectType.COMMUNITY;
selectorType = DSpaceObjectType.COMMUNITY;
selectorTypes = [DSpaceObjectType.COMMUNITY];
action = SelectorActionType.EDIT;
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) {

View File

@@ -17,7 +17,7 @@ import { DSOSelectorModalWrapperComponent, SelectorActionType } from '../dso-sel
})
export class EditItemSelectorComponent extends DSOSelectorModalWrapperComponent implements OnInit {
objectType = DSpaceObjectType.ITEM;
selectorType = DSpaceObjectType.ITEM;
selectorTypes = [DSpaceObjectType.ITEM];
action = SelectorActionType.EDIT;
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) {

View File

@@ -28,7 +28,7 @@ import { DSOSelectorModalWrapperComponent, SelectorActionType } from '../dso-sel
})
export class ExportMetadataSelectorComponent extends DSOSelectorModalWrapperComponent implements OnInit {
objectType = DSpaceObjectType.DSPACEOBJECT;
selectorType = DSpaceObjectType.DSPACEOBJECT;
selectorTypes = [DSpaceObjectType.COLLECTION, DSpaceObjectType.COMMUNITY];
action = SelectorActionType.EXPORT_METADATA;
constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router,

View File

@@ -13,7 +13,7 @@ describe('PaginatedSearchOptions', () => {
const scope = '0fde1ecb-82cc-425a-b600-ac3576d76b47';
const baseUrl = 'www.rest.com';
beforeEach(() => {
options = new PaginatedSearchOptions({sort: sortOptions, pagination: pageOptions, filters: filters, query: query, scope: scope, dsoType: DSpaceObjectType.ITEM});
options = new PaginatedSearchOptions({sort: sortOptions, pagination: pageOptions, filters: filters, query: query, scope: scope, dsoTypes: [DSpaceObjectType.ITEM]});
});
describe('when toRestUrl is called', () => {

View File

@@ -12,7 +12,7 @@ export class PaginatedSearchOptions extends SearchOptions {
pagination?: PaginationComponentOptions;
sort?: SortOptions;
constructor(options: {configuration?: string, scope?: string, query?: string, dsoType?: DSpaceObjectType, filters?: SearchFilter[], fixedFilter?: any, pagination?: PaginationComponentOptions, sort?: SortOptions}) {
constructor(options: {configuration?: string, scope?: string, query?: string, dsoTypes?: DSpaceObjectType[], filters?: SearchFilter[], fixedFilter?: any, pagination?: PaginationComponentOptions, sort?: SortOptions}) {
super(options);
this.pagination = options.pagination;
this.sort = options.sort;

View File

@@ -10,7 +10,7 @@ describe('SearchOptions', () => {
const scope = '0fde1ecb-82cc-425a-b600-ac3576d76b47';
const baseUrl = 'www.rest.com';
beforeEach(() => {
options = new SearchOptions({ filters: filters, query: query, scope: scope , dsoType: DSpaceObjectType.ITEM});
options = new SearchOptions({ filters: filters, query: query, scope: scope , dsoTypes: [DSpaceObjectType.ITEM]});
});
describe('when toRestUrl is called', () => {

View File

@@ -12,15 +12,15 @@ export class SearchOptions {
view?: ViewMode = ViewMode.ListElement;
scope?: string;
query?: string;
dsoType?: DSpaceObjectType;
dsoTypes?: DSpaceObjectType[];
filters?: any;
fixedFilter?: any;
constructor(options: {configuration?: string, scope?: string, query?: string, dsoType?: DSpaceObjectType, filters?: SearchFilter[], fixedFilter?: any}) {
constructor(options: {configuration?: string, scope?: string, query?: string, dsoTypes?: DSpaceObjectType[], filters?: SearchFilter[], fixedFilter?: any}) {
this.configuration = options.configuration;
this.scope = options.scope;
this.query = options.query;
this.dsoType = options.dsoType;
this.dsoTypes = options.dsoTypes;
this.filters = options.filters;
this.fixedFilter = options.fixedFilter;
}
@@ -44,8 +44,10 @@ export class SearchOptions {
if (isNotEmpty(this.scope)) {
args.push(`scope=${this.scope}`);
}
if (isNotEmpty(this.dsoType)) {
args.push(`dsoType=${this.dsoType}`);
if (isNotEmpty(this.dsoTypes)) {
this.dsoTypes.forEach((dsoType: string) => {
args.push(`dsoType=${dsoType}`);
})
}
if (isNotEmpty(this.filters)) {
this.filters.forEach((filter: SearchFilter) => {

View File

@@ -82,7 +82,7 @@ describe('StatisticsService', () => {
const mockSearch: any = new SearchOptions({
query: 'mock-query',
configuration: 'mock-configuration',
dsoType: DSpaceObjectType.ITEM,
dsoTypes: [DSpaceObjectType.ITEM],
scope: 'mock-scope'
});
@@ -112,7 +112,7 @@ describe('StatisticsService', () => {
const body = JSON.parse(request.body);
it('should specify the dsoType', () => {
expect(body.dsoType).toBe('item');
expect(body.dsoTypes).toBe('item');
});
it('should specify the scope', () => {

View File

@@ -68,8 +68,9 @@ export class StatisticsService {
if (hasValue(searchOptions.configuration)) {
Object.assign(body, { configuration: searchOptions.configuration })
}
if (hasValue(searchOptions.dsoType)) {
Object.assign(body, { dsoType: searchOptions.dsoType.toLowerCase() })
if (isNotEmpty(searchOptions.dsoTypes)) {
// TODO: check if backend statistics search even can handle multiple dsoTypes in body
Object.assign(body, { dsoTypes: searchOptions.dsoTypes.map( dsoType => dsoType.toLowerCase() ) })
}
if (hasValue(searchOptions.scope)) {
Object.assign(body, { scope: searchOptions.scope })