Skip to content
Snippets Groups Projects
Commit e7cc6a07 authored by lotte's avatar lotte
Browse files

search documentation start

parent 8ff036f6
Branches
Tags
No related merge requests found
......@@ -2,11 +2,19 @@ import { autoserialize } from 'cerialize';
import { Metadatum } from '../core/shared/metadatum.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 {
/**
* The UUID of the DSpaceObject that was found
*/
@autoserialize
dspaceObject: string;
/**
* The metadata that was used to find this item, hithighlighted
*/
@autoserialize
hitHighlights: Metadatum[];
......
......@@ -3,9 +3,19 @@ import { PaginationComponentOptions } from '../shared/pagination/pagination-comp
import { isNotEmpty } from '../shared/empty.util';
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 {
pagination?: PaginationComponentOptions;
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 {
if (isNotEmpty(this.sort)) {
args.push(`sort=${this.sort.field},${this.sort.direction}`);
......
......@@ -22,41 +22,78 @@ export const SearchFilterActionTypes = {
};
export class SearchFilterAction implements Action {
/**
* Name of the filter the action is performed on, used to identify the filter
*/
filterName: string;
/**
* Type of action that will be performed
*/
type;
/**
* Initialize with the filter's name
* @param {string} name of the filter
*/
constructor(name: string) {
this.filterName = name;
}
}
/* tslint:disable:max-classes-per-file */
/**
* Used to collapse a filter
*/
export class SearchFilterCollapseAction extends SearchFilterAction {
type = SearchFilterActionTypes.COLLAPSE;
}
/**
* Used to expand a filter
*/
export class SearchFilterExpandAction extends SearchFilterAction {
type = SearchFilterActionTypes.EXPAND;
}
/**
* Used to collapse a filter when it's expanded and expand it when it's collapsed
*/
export class SearchFilterToggleAction extends SearchFilterAction {
type = SearchFilterActionTypes.TOGGLE;
}
/**
* Used to set the initial state of a filter to collapsed
*/
export class SearchFilterInitialCollapseAction extends SearchFilterAction {
type = SearchFilterActionTypes.INITIAL_COLLAPSE;
}
/**
* Used to set the initial state of a filter to expanded
*/
export class SearchFilterInitialExpandAction extends SearchFilterAction {
type = SearchFilterActionTypes.INITIAL_EXPAND;
}
/**
* Used to set the state of a filter to the previous page
*/
export class SearchFilterDecrementPageAction extends SearchFilterAction {
type = SearchFilterActionTypes.DECREMENT_PAGE;
}
/**
* Used to set the state of a filter to the next page
*/
export class SearchFilterIncrementPageAction extends SearchFilterAction {
type = SearchFilterActionTypes.INCREMENT_PAGE;
}
/**
* Used to set the state of a filter to the first page
*/
export class SearchFilterResetPageAction extends SearchFilterAction {
type = SearchFilterActionTypes.RESET_PAGE;
}
......
......@@ -18,13 +18,28 @@ import { isNotEmpty } from '../../../shared/empty.util';
animations: [slide],
})
/**
* Represents a part of the filter section for a single type of filter
*/
export class SearchFilterComponent implements OnInit {
/**
* The filter config for this component
*/
@Input() filter: SearchFilterConfig;
/**
* True when the filter is 100% collapsed in the UI
*/
collapsed;
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() {
this.getSelectedValues().first().subscribe((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() {
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> {
return this.filterService.isCollapsed(this.filter.name);
}
/**
* Changes the initial state to collapsed
*/
initialCollapse() {
this.filterService.initialCollapse(this.filter.name);
this.collapsed = true;
}
/**
* Changes the initial state to expanded
*/
initialExpand() {
this.filterService.initialExpand(this.filter.name);
this.collapsed = false;
}
/**
* @returns {Observable<string[]>} Emits a list of all values that are currently active for this filter
*/
getSelectedValues(): Observable<string[]> {
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 {
if (event.fromState === 'collapsed') {
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 {
if (event.toState === 'collapsed') {
this.collapsed = true;
......
import { SearchFilterAction, SearchFilterActionTypes } from './search-filter.actions';
import { isEmpty } from '../../../shared/empty.util';
/*
Interface that represents the state for a single filters
*/
export interface SearchFilterState {
filterCollapsed: boolean,
page: number
}
/*
Interface that represents the state for all available filters
*/
export interface SearchFiltersState {
[name: string]: SearchFilterState
}
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 {
switch (action.type) {
......
......@@ -5,26 +5,40 @@ import { SearchFilterConfig } from '../search-service/search-filter-config.model
import { Observable } from 'rxjs/Observable';
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({
selector: 'ds-search-filters',
styleUrls: ['./search-filters.component.scss'],
templateUrl: './search-filters.component.html',
})
/**
* This component represents the part of the search sidebar that contains filters.
*/
export class SearchFiltersComponent {
/**
* An observable containing configuration about which filters are shown and how they are shown
*/
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;
/**
* Initialize instance variables
* @param {SearchService} searchService
* @param {SearchFilterService} filterService
*/
constructor(private searchService: SearchService, private filterService: SearchFilterService) {
this.filters = searchService.getConfig();
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() {
return this.searchService.getSearchLink();
}
......
......@@ -2,17 +2,30 @@ import { isNotEmpty } from '../shared/empty.util';
import { URLCombiner } from '../core/url-combiner/url-combiner';
import 'core-js/library/fn/object/entries';
/**
* This enumeration represents all possible ways of representing the a group of objects
*/
export enum ViewMode {
List = 'list',
Grid = 'grid'
}
/**
* This model class represents all parameters needed to request information about a certain search request
*/
export class SearchOptions {
view?: ViewMode = ViewMode.List;
scope?: string;
query?: string;
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 {
if (isNotEmpty(this.query)) {
......
......@@ -28,6 +28,10 @@ import { SearchSidebarService } from './search-sidebar/search-sidebar.service';
changeDetection: ChangeDetectionStrategy.OnPush,
animations: [pushInOut]
})
/**
* This component represents the whole search page
*/
export class SearchPageComponent implements OnInit {
resultsRD$: Observable<RemoteData<PaginatedList<SearchResult<DSpaceObject>>>>;
......@@ -54,6 +58,13 @@ export class SearchPageComponent implements OnInit {
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 {
this.searchOptions$ = this.filterService.getPaginatedSearchOptions(this.defaults);
this.resultsRD$ = this.searchOptions$.pipe(
......@@ -66,18 +77,31 @@ export class SearchPageComponent implements OnInit {
);
}
/**
* Set the sidebar to a collapsed state
*/
public closeSidebar(): void {
this.sidebarService.collapse()
}
/**
* Set the sidebar to a expanded state
*/
public openSidebar(): void {
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> {
return this.sidebarService.isCollapsed;
}
/**
* @returns {string} The base path to the search page
*/
public getSearchLink(): string {
return this.service.getSearchLink();
}
......
......@@ -2,9 +2,18 @@ import { DSpaceObject } from '../core/shared/dspace-object.model';
import { Metadatum } from '../core/shared/metadatum.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 {
/**
* The DSpaceObject that was found
*/
dspaceObject: T;
/**
* The metadata that was used to find this item, hithighlighted
*/
hitHighlights: Metadatum[];
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment