mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-12 20:43:08 +00:00
search documentation start
This commit is contained in:
@@ -2,11 +2,19 @@ import { autoserialize } from 'cerialize';
|
|||||||
import { Metadatum } from '../core/shared/metadatum.model';
|
import { Metadatum } from '../core/shared/metadatum.model';
|
||||||
import { ListableObject } from '../shared/object-collection/shared/listable-object.model';
|
import { ListableObject } from '../shared/object-collection/shared/listable-object.model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a normalized version of a search result object of a certain DSpaceObject
|
||||||
|
*/
|
||||||
export class NormalizedSearchResult implements ListableObject {
|
export class NormalizedSearchResult implements ListableObject {
|
||||||
|
/**
|
||||||
|
* The UUID of the DSpaceObject that was found
|
||||||
|
*/
|
||||||
@autoserialize
|
@autoserialize
|
||||||
dspaceObject: string;
|
dspaceObject: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The metadata that was used to find this item, hithighlighted
|
||||||
|
*/
|
||||||
@autoserialize
|
@autoserialize
|
||||||
hitHighlights: Metadatum[];
|
hitHighlights: Metadatum[];
|
||||||
|
|
||||||
|
@@ -3,9 +3,19 @@ import { PaginationComponentOptions } from '../shared/pagination/pagination-comp
|
|||||||
import { isNotEmpty } from '../shared/empty.util';
|
import { isNotEmpty } from '../shared/empty.util';
|
||||||
import { SearchOptions } from './search-options.model';
|
import { SearchOptions } from './search-options.model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This model class represents all parameters needed to request information about a certain page of a search request, in a certain order
|
||||||
|
*/
|
||||||
export class PaginatedSearchOptions extends SearchOptions {
|
export class PaginatedSearchOptions extends SearchOptions {
|
||||||
pagination?: PaginationComponentOptions;
|
pagination?: PaginationComponentOptions;
|
||||||
sort?: SortOptions;
|
sort?: SortOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to generate the URL that can be used to request a certain page with specific sort options
|
||||||
|
* @param {string} url The URL to the REST endpoint
|
||||||
|
* @param {string[]} args A list of query arguments that should be included in the URL
|
||||||
|
* @returns {string} URL with all paginated search options and passed arguments as query parameters
|
||||||
|
*/
|
||||||
toRestUrl(url: string, args: string[] = []): string {
|
toRestUrl(url: string, args: string[] = []): string {
|
||||||
if (isNotEmpty(this.sort)) {
|
if (isNotEmpty(this.sort)) {
|
||||||
args.push(`sort=${this.sort.field},${this.sort.direction}`);
|
args.push(`sort=${this.sort.field},${this.sort.direction}`);
|
||||||
|
@@ -22,41 +22,78 @@ export const SearchFilterActionTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class SearchFilterAction implements Action {
|
export class SearchFilterAction implements Action {
|
||||||
|
/**
|
||||||
|
* Name of the filter the action is performed on, used to identify the filter
|
||||||
|
*/
|
||||||
filterName: string;
|
filterName: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type of action that will be performed
|
||||||
|
*/
|
||||||
type;
|
type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize with the filter's name
|
||||||
|
* @param {string} name of the filter
|
||||||
|
*/
|
||||||
constructor(name: string) {
|
constructor(name: string) {
|
||||||
this.filterName = name;
|
this.filterName = name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tslint:disable:max-classes-per-file */
|
/* tslint:disable:max-classes-per-file */
|
||||||
|
/**
|
||||||
|
* Used to collapse a filter
|
||||||
|
*/
|
||||||
export class SearchFilterCollapseAction extends SearchFilterAction {
|
export class SearchFilterCollapseAction extends SearchFilterAction {
|
||||||
type = SearchFilterActionTypes.COLLAPSE;
|
type = SearchFilterActionTypes.COLLAPSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to expand a filter
|
||||||
|
*/
|
||||||
export class SearchFilterExpandAction extends SearchFilterAction {
|
export class SearchFilterExpandAction extends SearchFilterAction {
|
||||||
type = SearchFilterActionTypes.EXPAND;
|
type = SearchFilterActionTypes.EXPAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to collapse a filter when it's expanded and expand it when it's collapsed
|
||||||
|
*/
|
||||||
export class SearchFilterToggleAction extends SearchFilterAction {
|
export class SearchFilterToggleAction extends SearchFilterAction {
|
||||||
type = SearchFilterActionTypes.TOGGLE;
|
type = SearchFilterActionTypes.TOGGLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to set the initial state of a filter to collapsed
|
||||||
|
*/
|
||||||
export class SearchFilterInitialCollapseAction extends SearchFilterAction {
|
export class SearchFilterInitialCollapseAction extends SearchFilterAction {
|
||||||
type = SearchFilterActionTypes.INITIAL_COLLAPSE;
|
type = SearchFilterActionTypes.INITIAL_COLLAPSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to set the initial state of a filter to expanded
|
||||||
|
*/
|
||||||
export class SearchFilterInitialExpandAction extends SearchFilterAction {
|
export class SearchFilterInitialExpandAction extends SearchFilterAction {
|
||||||
type = SearchFilterActionTypes.INITIAL_EXPAND;
|
type = SearchFilterActionTypes.INITIAL_EXPAND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to set the state of a filter to the previous page
|
||||||
|
*/
|
||||||
export class SearchFilterDecrementPageAction extends SearchFilterAction {
|
export class SearchFilterDecrementPageAction extends SearchFilterAction {
|
||||||
type = SearchFilterActionTypes.DECREMENT_PAGE;
|
type = SearchFilterActionTypes.DECREMENT_PAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to set the state of a filter to the next page
|
||||||
|
*/
|
||||||
export class SearchFilterIncrementPageAction extends SearchFilterAction {
|
export class SearchFilterIncrementPageAction extends SearchFilterAction {
|
||||||
type = SearchFilterActionTypes.INCREMENT_PAGE;
|
type = SearchFilterActionTypes.INCREMENT_PAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to set the state of a filter to the first page
|
||||||
|
*/
|
||||||
export class SearchFilterResetPageAction extends SearchFilterAction {
|
export class SearchFilterResetPageAction extends SearchFilterAction {
|
||||||
type = SearchFilterActionTypes.RESET_PAGE;
|
type = SearchFilterActionTypes.RESET_PAGE;
|
||||||
}
|
}
|
||||||
|
@@ -18,13 +18,28 @@ import { isNotEmpty } from '../../../shared/empty.util';
|
|||||||
animations: [slide],
|
animations: [slide],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a part of the filter section for a single type of filter
|
||||||
|
*/
|
||||||
export class SearchFilterComponent implements OnInit {
|
export class SearchFilterComponent implements OnInit {
|
||||||
|
/**
|
||||||
|
* The filter config for this component
|
||||||
|
*/
|
||||||
@Input() filter: SearchFilterConfig;
|
@Input() filter: SearchFilterConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True when the filter is 100% collapsed in the UI
|
||||||
|
*/
|
||||||
collapsed;
|
collapsed;
|
||||||
|
|
||||||
constructor(private filterService: SearchFilterService) {
|
constructor(private filterService: SearchFilterService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests the current set values for this filter
|
||||||
|
* If the filter config is open by default OR the filter has at least one value, the filter should be initially expanded
|
||||||
|
* Else, the filter should initially be collapsed
|
||||||
|
*/
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.getSelectedValues().first().subscribe((isActive) => {
|
this.getSelectedValues().first().subscribe((isActive) => {
|
||||||
if (this.filter.isOpenByDefault || isNotEmpty(isActive)) {
|
if (this.filter.isOpenByDefault || isNotEmpty(isActive)) {
|
||||||
@@ -35,34 +50,58 @@ export class SearchFilterComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the state for this filter to collapsed when it's expanded and to expanded it when it's collapsed
|
||||||
|
*/
|
||||||
toggle() {
|
toggle() {
|
||||||
this.filterService.toggle(this.filter.name);
|
this.filterService.toggle(this.filter.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the filter is currently collapsed
|
||||||
|
* @returns {Observable<boolean>} Emits true when the current state of the filter is collapsed, false when it's expanded
|
||||||
|
*/
|
||||||
isCollapsed(): Observable<boolean> {
|
isCollapsed(): Observable<boolean> {
|
||||||
return this.filterService.isCollapsed(this.filter.name);
|
return this.filterService.isCollapsed(this.filter.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the initial state to collapsed
|
||||||
|
*/
|
||||||
initialCollapse() {
|
initialCollapse() {
|
||||||
this.filterService.initialCollapse(this.filter.name);
|
this.filterService.initialCollapse(this.filter.name);
|
||||||
this.collapsed = true;
|
this.collapsed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the initial state to expanded
|
||||||
|
*/
|
||||||
initialExpand() {
|
initialExpand() {
|
||||||
this.filterService.initialExpand(this.filter.name);
|
this.filterService.initialExpand(this.filter.name);
|
||||||
this.collapsed = false;
|
this.collapsed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Observable<string[]>} Emits a list of all values that are currently active for this filter
|
||||||
|
*/
|
||||||
getSelectedValues(): Observable<string[]> {
|
getSelectedValues(): Observable<string[]> {
|
||||||
return this.filterService.getSelectedValuesForFilter(this.filter);
|
return this.filterService.getSelectedValuesForFilter(this.filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to change this.collapsed to false when the slide animation ends and is sliding open
|
||||||
|
* @param event The animation event
|
||||||
|
*/
|
||||||
finishSlide(event: any): void {
|
finishSlide(event: any): void {
|
||||||
if (event.fromState === 'collapsed') {
|
if (event.fromState === 'collapsed') {
|
||||||
this.collapsed = false;
|
this.collapsed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to change this.collapsed to true when the slide animation starts and is sliding closed
|
||||||
|
* @param event The animation event
|
||||||
|
*/
|
||||||
startSlide(event: any): void {
|
startSlide(event: any): void {
|
||||||
if (event.toState === 'collapsed') {
|
if (event.toState === 'collapsed') {
|
||||||
this.collapsed = true;
|
this.collapsed = true;
|
||||||
|
@@ -1,17 +1,29 @@
|
|||||||
import { SearchFilterAction, SearchFilterActionTypes } from './search-filter.actions';
|
import { SearchFilterAction, SearchFilterActionTypes } from './search-filter.actions';
|
||||||
import { isEmpty } from '../../../shared/empty.util';
|
import { isEmpty } from '../../../shared/empty.util';
|
||||||
|
|
||||||
|
/*
|
||||||
|
Interface that represents the state for a single filters
|
||||||
|
*/
|
||||||
export interface SearchFilterState {
|
export interface SearchFilterState {
|
||||||
filterCollapsed: boolean,
|
filterCollapsed: boolean,
|
||||||
page: number
|
page: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Interface that represents the state for all available filters
|
||||||
|
*/
|
||||||
export interface SearchFiltersState {
|
export interface SearchFiltersState {
|
||||||
[name: string]: SearchFilterState
|
[name: string]: SearchFilterState
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: SearchFiltersState = Object.create(null);
|
const initialState: SearchFiltersState = Object.create(null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a search filter action on the current state
|
||||||
|
* @param {SearchFiltersState} state The state before the action is performed
|
||||||
|
* @param {SearchFilterAction} action The action that should be performed
|
||||||
|
* @returns {SearchFiltersState} The state after the action is performed
|
||||||
|
*/
|
||||||
export function filterReducer(state = initialState, action: SearchFilterAction): SearchFiltersState {
|
export function filterReducer(state = initialState, action: SearchFilterAction): SearchFiltersState {
|
||||||
|
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
|
@@ -5,26 +5,40 @@ import { SearchFilterConfig } from '../search-service/search-filter-config.model
|
|||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { SearchFilterService } from './search-filter/search-filter.service';
|
import { SearchFilterService } from './search-filter/search-filter.service';
|
||||||
|
|
||||||
/**
|
|
||||||
* This component renders a simple item page.
|
|
||||||
* The route parameter 'id' is used to request the item it represents.
|
|
||||||
* All fields of the item that should be displayed, are defined in its template.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-search-filters',
|
selector: 'ds-search-filters',
|
||||||
styleUrls: ['./search-filters.component.scss'],
|
styleUrls: ['./search-filters.component.scss'],
|
||||||
templateUrl: './search-filters.component.html',
|
templateUrl: './search-filters.component.html',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component represents the part of the search sidebar that contains filters.
|
||||||
|
*/
|
||||||
export class SearchFiltersComponent {
|
export class SearchFiltersComponent {
|
||||||
|
/**
|
||||||
|
* An observable containing configuration about which filters are shown and how they are shown
|
||||||
|
*/
|
||||||
filters: Observable<RemoteData<SearchFilterConfig[]>>;
|
filters: Observable<RemoteData<SearchFilterConfig[]>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of all filters that are currently active with their value set to null.
|
||||||
|
* Used to reset all filters at once
|
||||||
|
*/
|
||||||
clearParams;
|
clearParams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize instance variables
|
||||||
|
* @param {SearchService} searchService
|
||||||
|
* @param {SearchFilterService} filterService
|
||||||
|
*/
|
||||||
constructor(private searchService: SearchService, private filterService: SearchFilterService) {
|
constructor(private searchService: SearchService, private filterService: SearchFilterService) {
|
||||||
this.filters = searchService.getConfig();
|
this.filters = searchService.getConfig();
|
||||||
this.clearParams = filterService.getCurrentFrontendFilters().map((filters) => {Object.keys(filters).forEach((f) => filters[f] = null); return filters;});
|
this.clearParams = filterService.getCurrentFrontendFilters().map((filters) => {Object.keys(filters).forEach((f) => filters[f] = null); return filters;});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string} The base path to the search page
|
||||||
|
*/
|
||||||
getSearchLink() {
|
getSearchLink() {
|
||||||
return this.searchService.getSearchLink();
|
return this.searchService.getSearchLink();
|
||||||
}
|
}
|
||||||
|
@@ -2,17 +2,30 @@ import { isNotEmpty } from '../shared/empty.util';
|
|||||||
import { URLCombiner } from '../core/url-combiner/url-combiner';
|
import { URLCombiner } from '../core/url-combiner/url-combiner';
|
||||||
import 'core-js/library/fn/object/entries';
|
import 'core-js/library/fn/object/entries';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This enumeration represents all possible ways of representing the a group of objects
|
||||||
|
*/
|
||||||
|
|
||||||
export enum ViewMode {
|
export enum ViewMode {
|
||||||
List = 'list',
|
List = 'list',
|
||||||
Grid = 'grid'
|
Grid = 'grid'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This model class represents all parameters needed to request information about a certain search request
|
||||||
|
*/
|
||||||
export class SearchOptions {
|
export class SearchOptions {
|
||||||
view?: ViewMode = ViewMode.List;
|
view?: ViewMode = ViewMode.List;
|
||||||
scope?: string;
|
scope?: string;
|
||||||
query?: string;
|
query?: string;
|
||||||
filters?: any;
|
filters?: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to generate the URL that can be used request information about a search request
|
||||||
|
* @param {string} url The URL to the REST endpoint
|
||||||
|
* @param {string[]} args A list of query arguments that should be included in the URL
|
||||||
|
* @returns {string} URL with all search options and passed arguments as query parameters
|
||||||
|
*/
|
||||||
toRestUrl(url: string, args: string[] = []): string {
|
toRestUrl(url: string, args: string[] = []): string {
|
||||||
|
|
||||||
if (isNotEmpty(this.query)) {
|
if (isNotEmpty(this.query)) {
|
||||||
|
@@ -28,6 +28,10 @@ import { SearchSidebarService } from './search-sidebar/search-sidebar.service';
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
animations: [pushInOut]
|
animations: [pushInOut]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component represents the whole search page
|
||||||
|
*/
|
||||||
export class SearchPageComponent implements OnInit {
|
export class SearchPageComponent implements OnInit {
|
||||||
|
|
||||||
resultsRD$: Observable<RemoteData<PaginatedList<SearchResult<DSpaceObject>>>>;
|
resultsRD$: Observable<RemoteData<PaginatedList<SearchResult<DSpaceObject>>>>;
|
||||||
@@ -54,6 +58,13 @@ export class SearchPageComponent implements OnInit {
|
|||||||
this.isXsOrSm$ = this.windowService.isXsOrSm();
|
this.isXsOrSm$ = this.windowService.isXsOrSm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listening to changes in the paginated search options
|
||||||
|
* If something changes, update the search results
|
||||||
|
*
|
||||||
|
* Listen to changes in the scope
|
||||||
|
* If something changes, update the list of scopes for the dropdown
|
||||||
|
*/
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.searchOptions$ = this.filterService.getPaginatedSearchOptions(this.defaults);
|
this.searchOptions$ = this.filterService.getPaginatedSearchOptions(this.defaults);
|
||||||
this.resultsRD$ = this.searchOptions$.pipe(
|
this.resultsRD$ = this.searchOptions$.pipe(
|
||||||
@@ -66,18 +77,31 @@ export class SearchPageComponent implements OnInit {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sidebar to a collapsed state
|
||||||
|
*/
|
||||||
public closeSidebar(): void {
|
public closeSidebar(): void {
|
||||||
this.sidebarService.collapse()
|
this.sidebarService.collapse()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sidebar to a expanded state
|
||||||
|
*/
|
||||||
public openSidebar(): void {
|
public openSidebar(): void {
|
||||||
this.sidebarService.expand();
|
this.sidebarService.expand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the sidebar is correct
|
||||||
|
* @returns {Observable<boolean>} emits true if the sidebar is currently collapsed, false if it is expanded
|
||||||
|
*/
|
||||||
public isSidebarCollapsed(): Observable<boolean> {
|
public isSidebarCollapsed(): Observable<boolean> {
|
||||||
return this.sidebarService.isCollapsed;
|
return this.sidebarService.isCollapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {string} The base path to the search page
|
||||||
|
*/
|
||||||
public getSearchLink(): string {
|
public getSearchLink(): string {
|
||||||
return this.service.getSearchLink();
|
return this.service.getSearchLink();
|
||||||
}
|
}
|
||||||
|
@@ -2,9 +2,18 @@ import { DSpaceObject } from '../core/shared/dspace-object.model';
|
|||||||
import { Metadatum } from '../core/shared/metadatum.model';
|
import { Metadatum } from '../core/shared/metadatum.model';
|
||||||
import { ListableObject } from '../shared/object-collection/shared/listable-object.model';
|
import { ListableObject } from '../shared/object-collection/shared/listable-object.model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a search result object of a certain (<T>) DSpaceObject
|
||||||
|
*/
|
||||||
export class SearchResult<T extends DSpaceObject> implements ListableObject {
|
export class SearchResult<T extends DSpaceObject> implements ListableObject {
|
||||||
|
/**
|
||||||
|
* The DSpaceObject that was found
|
||||||
|
*/
|
||||||
dspaceObject: T;
|
dspaceObject: T;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The metadata that was used to find this item, hithighlighted
|
||||||
|
*/
|
||||||
hitHighlights: Metadatum[];
|
hitHighlights: Metadatum[];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user