Files
dspace-angular/src/app/shared/search-form/search-form.component.ts

156 lines
4.4 KiB
TypeScript

import { Component, EventEmitter, Input, Output, OnChanges } from '@angular/core';
import { DSpaceObject } from '../../core/shared/dspace-object.model';
import { Router } from '@angular/router';
import { isNotEmpty } from '../empty.util';
import { SearchService } from '../../core/shared/search/search.service';
import { currentPath } from '../utils/route.utils';
import { PaginationService } from '../../core/pagination/pagination.service';
import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ScopeSelectorModalComponent } from './scope-selector-modal/scope-selector-modal.component';
import { take } from 'rxjs/operators';
import { BehaviorSubject } from 'rxjs';
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators';
import { DSONameService } from '../../core/breadcrumbs/dso-name.service';
@Component({
selector: 'ds-search-form',
styleUrls: ['./search-form.component.scss'],
templateUrl: './search-form.component.html'
})
/**
* Component that represents the search form
*/
export class SearchFormComponent implements OnChanges {
/**
* The search query
*/
@Input() query: string;
/**
* True when the search component should show results on the current page
*/
@Input() inPlaceSearch: boolean;
/**
* The currently selected scope object's UUID
*/
@Input()
scope = '';
selectedScope: BehaviorSubject<DSpaceObject> = new BehaviorSubject<DSpaceObject>(undefined);
@Input() currentUrl: string;
/**
* Whether or not the search button should be displayed large
*/
@Input() large = false;
/**
* The brand color of the search button
*/
@Input() brandColor = 'primary';
/**
* The placeholder of the search input
*/
@Input() searchPlaceholder: string;
/**
* Defines whether or not to show the scope selector
*/
@Input() showScopeSelector = false;
/**
* Output the search data on submit
*/
@Output() submitSearch = new EventEmitter<any>();
constructor(
protected router: Router,
protected searchService: SearchService,
protected paginationService: PaginationService,
protected searchConfig: SearchConfigurationService,
protected modalService: NgbModal,
protected dsoService: DSpaceObjectDataService,
public dsoNameService: DSONameService,
) {
}
/**
* Retrieve the scope object from the URL so we can show its name
*/
ngOnChanges(): void {
if (isNotEmpty(this.scope)) {
this.dsoService.findById(this.scope).pipe(getFirstSucceededRemoteDataPayload())
.subscribe((scope: DSpaceObject) => this.selectedScope.next(scope));
}
}
/**
* Updates the search when the form is submitted
* @param data Values submitted using the form
*/
onSubmit(data: any) {
if (isNotEmpty(this.scope)) {
data = Object.assign(data, { scope: this.scope });
}
this.updateSearch(data);
this.submitSearch.emit(data);
}
/**
* Updates the search when the current scope has been changed
* @param {string} scope The new scope
*/
onScopeChange(scope: DSpaceObject) {
this.updateSearch({ scope: scope ? scope.uuid : undefined });
}
/**
* Updates the search URL
* @param data Updated parameters
*/
updateSearch(data: any) {
const queryParams = Object.assign({}, data);
void this.router.navigate(this.getSearchLinkParts(), {
queryParams: queryParams,
queryParamsHandling: 'merge'
});
}
/**
* @returns {string} The base path to the search page, or the current page when inPlaceSearch is true
*/
public getSearchLink(): string {
if (this.inPlaceSearch) {
return currentPath(this.router);
}
return this.searchService.getSearchLink();
}
/**
* @returns {string[]} The base path to the search page, or the current page when inPlaceSearch is true, split in separate pieces
*/
public getSearchLinkParts(): string[] {
if (this.inPlaceSearch) {
return [];
}
return this.getSearchLink().split('/');
}
/**
* Open the scope modal so the user can select DSO as scope
*/
openScopeModal() {
const ref = this.modalService.open(ScopeSelectorModalComponent);
ref.componentInstance.scopeChange.pipe(take(1)).subscribe((scope: DSpaceObject) => {
this.selectedScope.next(scope);
this.onScopeChange(scope);
});
}
}