added typedoc

This commit is contained in:
lotte
2019-12-19 09:23:13 +01:00
parent 38f3f583f6
commit 0dbea31b0d
20 changed files with 212 additions and 7 deletions

View File

@@ -92,6 +92,14 @@ export class RelationshipService extends DataService<Relationship> {
); );
} }
/**
* Method to create a new relationship
* @param typeId The identifier of the relationship type
* @param item1 The first item of the relationship
* @param item2 The second item of the relationship
* @param leftwardValue The leftward value of the relationship
* @param rightwardValue The rightward value of the relationship
*/
addRelationship(typeId: string, item1: Item, item2: Item, leftwardValue?: string, rightwardValue?: string): Observable<RestResponse> { addRelationship(typeId: string, item1: Item, item2: Item, leftwardValue?: string, rightwardValue?: string): Observable<RestResponse> {
const options: HttpOptions = Object.create({}); const options: HttpOptions = Object.create({});
let headers = new HttpHeaders(); let headers = new HttpHeaders();
@@ -112,6 +120,10 @@ export class RelationshipService extends DataService<Relationship> {
); );
} }
/**
* Method to remove two items of a relationship from the cache using the identifier of the relationship
* @param relationshipId The identifier of the relationship
*/
private removeRelationshipItemsFromCacheByRelationship(relationshipId: string) { private removeRelationshipItemsFromCacheByRelationship(relationshipId: string) {
this.findById(relationshipId).pipe( this.findById(relationshipId).pipe(
getSucceededRemoteData(), getSucceededRemoteData(),
@@ -128,6 +140,10 @@ export class RelationshipService extends DataService<Relationship> {
}) })
} }
/**
* Method to remove an item that's part of a relationship from the cache
* @param item The item to remove from the cache
*/
private removeRelationshipItemsFromCache(item) { private removeRelationshipItemsFromCache(item) {
this.objectCache.remove(item.self); this.objectCache.remove(item.self);
this.requestService.removeByHrefSubstring(item.self); this.requestService.removeByHrefSubstring(item.self);
@@ -258,6 +274,12 @@ export class RelationshipService extends DataService<Relationship> {
); );
} }
/**
* Method to retrieve a relationship based on two items and a relationship type label
* @param item1 The first item in the relationship
* @param item2 The second item in the relationship
* @param label The rightward or leftward type of the relationship
*/
getRelationshipByItemsAndLabel(item1: Item, item2: Item, label: string): Observable<Relationship> { getRelationshipByItemsAndLabel(item1: Item, item2: Item, label: string): Observable<Relationship> {
return this.getItemRelationshipsByLabel(item1, label) return this.getItemRelationshipsByLabel(item1, label)
.pipe( .pipe(
@@ -287,24 +309,51 @@ export class RelationshipService extends DataService<Relationship> {
); );
} }
/**
* Method to set the name variant for specific list and item
* @param listID The list for which to save the name variant
* @param itemID The item ID for which to save the name variant
* @param nameVariant The name variant to save
*/
public setNameVariant(listID: string, itemID: string, nameVariant: string) { public setNameVariant(listID: string, itemID: string, nameVariant: string) {
this.appStore.dispatch(new SetNameVariantAction(listID, itemID, nameVariant)); this.appStore.dispatch(new SetNameVariantAction(listID, itemID, nameVariant));
} }
/**
* Method to retrieve the name variant for a specific list and item
* @param listID The list for which to retrieve the name variant
* @param itemID The item ID for which to retrieve the name variant
*/
public getNameVariant(listID: string, itemID: string): Observable<string> { public getNameVariant(listID: string, itemID: string): Observable<string> {
return this.appStore.pipe( return this.appStore.pipe(
select(relationshipStateSelector(listID, itemID)) select(relationshipStateSelector(listID, itemID))
); );
} }
/**
* Method to remove the name variant for specific list and item
* @param listID The list for which to remove the name variant
* @param itemID The item ID for which to remove the name variant
*/
public removeNameVariant(listID: string, itemID: string) { public removeNameVariant(listID: string, itemID: string) {
this.appStore.dispatch(new RemoveNameVariantAction(listID, itemID)); this.appStore.dispatch(new RemoveNameVariantAction(listID, itemID));
} }
/**
* Method to retrieve all name variants for a single list
* @param listID The id of the list
*/
public getNameVariantsByListID(listID: string) { public getNameVariantsByListID(listID: string) {
return this.appStore.pipe(select(relationshipListStateSelector(listID))); return this.appStore.pipe(select(relationshipListStateSelector(listID)));
} }
/**
* Method to update the name variant on the server
* @param item1 The first item of the relationship
* @param item2 The second item of the relationship
* @param relationshipLabel The leftward or rightward type of the relationship
* @param nameVariant The name variant to set for the matching relationship
*/
public updateNameVariant(item1: Item, item2: Item, relationshipLabel: string, nameVariant: string): Observable<RemoteData<Relationship>> { public updateNameVariant(item1: Item, item2: Item, relationshipLabel: string, nameVariant: string): Observable<RemoteData<Relationship>> {
return this.getRelationshipByItemsAndLabel(item1, item2, relationshipLabel) return this.getRelationshipByItemsAndLabel(item1, item2, relationshipLabel)
.pipe( .pipe(

View File

@@ -195,6 +195,9 @@ export class RouteService {
this.store.dispatch(new SetParameterAction(key, value)); this.store.dispatch(new SetParameterAction(key, value));
} }
/**
* Sets the current route parameters and query parameters in the store
*/
public setCurrentRouteInfo() { public setCurrentRouteInfo() {
combineLatest(this.getRouteParams(), this.route.queryParams) combineLatest(this.getRouteParams(), this.route.queryParams)
.pipe(take(1)) .pipe(take(1))

View File

@@ -5,6 +5,10 @@ import { EquatableObject } from './equatable';
const excludedFromEquals = new Map(); const excludedFromEquals = new Map();
const fieldsForEqualsMap = new Map(); const fieldsForEqualsMap = new Map();
/**
* Decorator function that adds the equatable settings from the given (parent) object
* @param parentCo The constructor of the parent object
*/
export function inheritEquatable(parentCo: GenericConstructor<EquatableObject<any>>) { export function inheritEquatable(parentCo: GenericConstructor<EquatableObject<any>>) {
return function decorator(childCo: GenericConstructor<EquatableObject<any>>) { return function decorator(childCo: GenericConstructor<EquatableObject<any>>) {
const parentExcludedFields = getExcludedFromEqualsFor(parentCo) || []; const parentExcludedFields = getExcludedFromEqualsFor(parentCo) || [];
@@ -21,6 +25,11 @@ export function inheritEquatable(parentCo: GenericConstructor<EquatableObject<an
} }
} }
/**
* Function to mark properties as excluded from the equals method
* @param object The object to exclude the property for
* @param propertyName The name of the property to exclude
*/
export function excludeFromEquals(object: any, propertyName: string): any { export function excludeFromEquals(object: any, propertyName: string): any {
if (!object) { if (!object) {
return; return;
@@ -37,6 +46,10 @@ export function getExcludedFromEqualsFor(constructor: Function): string[] {
return excludedFromEquals.get(constructor) || []; return excludedFromEquals.get(constructor) || [];
} }
/**
* Function to save the fields that are to be used for a certain property in the equals method for the given object
* @param fields The fields to use to equate the property of the object
*/
export function fieldsForEquals(...fields: string[]): any { export function fieldsForEquals(...fields: string[]): any {
return function i(object: any, propertyName: string): any { return function i(object: any, propertyName: string): any {
if (!object) { if (!object) {

View File

@@ -1,6 +1,12 @@
import { getExcludedFromEqualsFor, getFieldsForEquals } from './equals.decorators'; import { getExcludedFromEqualsFor, getFieldsForEquals } from './equals.decorators';
import { hasNoValue, hasValue } from '../../shared/empty.util'; import { hasNoValue, hasValue } from '../../shared/empty.util';
/**
* Method to compare fields of two objects against each other
* @param object1 The first object for the comparison
* @param object2 The second object for the comparison
* @param fieldList The list of property/field names to compare
*/
function equalsByFields(object1, object2, fieldList): boolean { function equalsByFields(object1, object2, fieldList): boolean {
const unequalProperty = fieldList.find((key) => { const unequalProperty = fieldList.find((key) => {
if (object1[key] === object2[key]) { if (object1[key] === object2[key]) {
@@ -27,6 +33,10 @@ function equalsByFields(object1, object2, fieldList): boolean {
return hasNoValue(unequalProperty); return hasNoValue(unequalProperty);
} }
/**
* Abstract class to represent objects that can be compared to each other
* It provides a default way of comparing
*/
export abstract class EquatableObject<T> { export abstract class EquatableObject<T> {
equals(other: T): boolean { equals(other: T): boolean {
if (hasNoValue(other)) { if (hasNoValue(other)) {

View File

@@ -24,7 +24,7 @@ import { NameVariantModalComponent } from '../../name-variant-modal/name-variant
}) })
/** /**
* The component for displaying a list element for an item search result of the type Person * The component for displaying a list element for an item search result of the type OrgUnit
*/ */
export class OrgUnitSearchResultListSubmissionElementComponent extends SearchResultListElementComponent<ItemSearchResult, Item> implements OnInit { export class OrgUnitSearchResultListSubmissionElementComponent extends SearchResultListElementComponent<ItemSearchResult, Item> implements OnInit {
allSuggestions: string[]; allSuggestions: string[];

View File

@@ -1,6 +1,10 @@
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
/**
* This component a pop up for when the user selects a custom name variant during submission for a relationship$
* The user can either choose to decline or accept to save the name variant as a metadata in the entity
*/
@Component({ @Component({
selector: 'ds-name-variant-modal', selector: 'ds-name-variant-modal',
templateUrl: './name-variant-modal.component.html', templateUrl: './name-variant-modal.component.html',

View File

@@ -230,6 +230,9 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
super(componentFactoryResolver, layoutService, validationService); super(componentFactoryResolver, layoutService, validationService);
} }
/**
* Sets up the necessary variables for when this control can be used to add relationships to the submitted item
*/
ngOnInit(): void { ngOnInit(): void {
this.hasRelationLookup = hasValue(this.model.relationship); this.hasRelationLookup = hasValue(this.model.relationship);
if (this.hasRelationLookup) { if (this.hasRelationLookup) {
@@ -314,6 +317,9 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
return this.model.value.pipe(map((list: Array<SearchResult<DSpaceObject>>) => isNotEmpty(list))); return this.model.value.pipe(map((list: Array<SearchResult<DSpaceObject>>) => isNotEmpty(list)));
} }
/**
* Open a modal where the user can select relationships to be added to item being submitted
*/
openLookup() { openLookup() {
this.modalRef = this.modalService.open(DsDynamicLookupRelationModalComponent, { this.modalRef = this.modalService.open(DsDynamicLookupRelationModalComponent, {
size: 'lg' size: 'lg'
@@ -327,12 +333,13 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
modalComp.item = this.item; modalComp.item = this.item;
} }
/**
* Method to remove a selected relationship from the item
* @param object The second item in the relationship, the submitted item being the first
*/
removeSelection(object: SearchResult<Item>) { removeSelection(object: SearchResult<Item>) {
this.selectableListService.deselectSingle(this.listId, object); this.selectableListService.deselectSingle(this.listId, object);
this.store.dispatch(new RemoveRelationshipAction(this.item, object.indexableObject, this.model.relationship.relationshipType)) this.store.dispatch(new RemoveRelationshipAction(this.item, object.indexableObject, this.model.relationship.relationshipType))
// this.zone.runOutsideAngular(
// () => );
} }
/** /**

View File

@@ -4,6 +4,9 @@ import { DynamicFormControlComponent, DynamicFormLayoutService, DynamicFormValid
import { FormGroup } from '@angular/forms'; import { FormGroup } from '@angular/forms';
import { DynamicDisabledModel } from './dynamic-disabled.model'; import { DynamicDisabledModel } from './dynamic-disabled.model';
/**
* Component representing a simple disabled input field
*/
@Component({ @Component({
selector: 'ds-dynamic-disabled', selector: 'ds-dynamic-disabled',
templateUrl: './dynamic-disabled.component.html' templateUrl: './dynamic-disabled.component.html'

View File

@@ -7,6 +7,9 @@ export interface DsDynamicDisabledModelConfig extends DsDynamicInputModelConfig
value?: any; value?: any;
} }
/**
* This model represents the data for a disabled input field
*/
export class DynamicDisabledModel extends DsDynamicInputModel { export class DynamicDisabledModel extends DsDynamicInputModel {
@serializable() readonly type: string = DYNAMIC_FORM_CONTROL_TYPE_DISABLED; @serializable() readonly type: string = DYNAMIC_FORM_CONTROL_TYPE_DISABLED;

View File

@@ -33,6 +33,9 @@ import { MetadataValue } from '../../../../../core/shared/metadata.models';
] ]
}) })
/**
* Represents a modal where the submitter can select items to be added as a certain relationship type to the object being submitted
*/
export class DsDynamicLookupRelationModalComponent implements OnInit, OnDestroy { export class DsDynamicLookupRelationModalComponent implements OnInit, OnDestroy {
label: string; label: string;
relationshipOptions: RelationshipOptions; relationshipOptions: RelationshipOptions;

View File

@@ -11,7 +11,9 @@ export const NameVariantActionTypes = {
}; };
/* tslint:disable:max-classes-per-file */ /* tslint:disable:max-classes-per-file */
/**
* Abstract class for actions that happen to name variants
*/
export abstract class NameVariantListAction implements Action { export abstract class NameVariantListAction implements Action {
type; type;
payload: { payload: {
@@ -24,6 +26,9 @@ export abstract class NameVariantListAction implements Action {
} }
} }
/**
* Action for setting a new name on an item in a certain list
*/
export class SetNameVariantAction extends NameVariantListAction { export class SetNameVariantAction extends NameVariantListAction {
type = NameVariantActionTypes.SET_NAME_VARIANT; type = NameVariantActionTypes.SET_NAME_VARIANT;
payload: { payload: {
@@ -38,6 +43,9 @@ export class SetNameVariantAction extends NameVariantListAction {
} }
} }
/**
* Action for removing a name on an item in a certain list
*/
export class RemoveNameVariantAction extends NameVariantListAction { export class RemoveNameVariantAction extends NameVariantListAction {
type = NameVariantActionTypes.REMOVE_NAME_VARIANT; type = NameVariantActionTypes.REMOVE_NAME_VARIANT;
constructor(listID: string, itemID: string) { constructor(listID: string, itemID: string) {

View File

@@ -72,6 +72,11 @@ export class RelationshipEffects {
) )
); );
/**
* Updates the namevariant in a relationship
* If the relationship is currently being added or removed, it will add the name variant to an update map so it will be sent with the next add request instead
* Otherwise the update is done immediately
*/
@Effect({ dispatch: false }) updateNameVariantsActions$ = this.actions$ @Effect({ dispatch: false }) updateNameVariantsActions$ = this.actions$
.pipe( .pipe(
ofType(RelationshipActionTypes.UPDATE_RELATIONSHIP), ofType(RelationshipActionTypes.UPDATE_RELATIONSHIP),

View File

@@ -33,6 +33,9 @@ import { Context } from '../../../../../../core/shared/context.model';
] ]
}) })
/**
* Tab for inside the lookup model that represents the items that can be used as a relationship in this submission
*/
export class DsDynamicLookupRelationSearchTabComponent implements OnInit, OnDestroy { export class DsDynamicLookupRelationSearchTabComponent implements OnInit, OnDestroy {
@Input() relationship: RelationshipOptions; @Input() relationship: RelationshipOptions;
@Input() listId: string; @Input() listId: string;
@@ -63,6 +66,9 @@ export class DsDynamicLookupRelationSearchTabComponent implements OnInit, OnDest
) { ) {
} }
/**
* Sets up the pagination and fixed query parameters
*/
ngOnInit(): void { ngOnInit(): void {
this.resetRoute(); this.resetRoute();
this.routeService.setParameter('fixedFilterQuery', this.relationship.filter); this.routeService.setParameter('fixedFilterQuery', this.relationship.filter);
@@ -90,12 +96,19 @@ export class DsDynamicLookupRelationSearchTabComponent implements OnInit, OnDest
); );
} }
/**
* Method to reset the route when the window is opened to make sure no strange pagination issues appears
*/
resetRoute() { resetRoute() {
this.router.navigate([], { this.router.navigate([], {
queryParams: Object.assign({}, { page: 1, pageSize: this.initialPagination.pageSize }), queryParams: Object.assign({}, { page: 1, pageSize: this.initialPagination.pageSize }),
}); });
} }
/**
* Selects a page in the store
* @param page The page to select
*/
selectPage(page: Array<SearchResult<Item>>) { selectPage(page: Array<SearchResult<Item>>) {
this.selection$ this.selection$
.pipe(take(1)) .pipe(take(1))
@@ -106,6 +119,10 @@ export class DsDynamicLookupRelationSearchTabComponent implements OnInit, OnDest
this.selectableListService.select(this.listId, page); this.selectableListService.select(this.listId, page);
} }
/**
* Deselects a page in the store
* @param page the page to deselect
*/
deselectPage(page: Array<SearchResult<Item>>) { deselectPage(page: Array<SearchResult<Item>>) {
this.allSelected = false; this.allSelected = false;
this.selection$ this.selection$
@@ -117,6 +134,9 @@ export class DsDynamicLookupRelationSearchTabComponent implements OnInit, OnDest
this.selectableListService.deselect(this.listId, page); this.selectableListService.deselect(this.listId, page);
} }
/**
* Select all items that were found using the current search query
*/
selectAll() { selectAll() {
this.allSelected = true; this.allSelected = true;
this.selectAllLoading = true; this.selectAllLoading = true;
@@ -142,6 +162,9 @@ export class DsDynamicLookupRelationSearchTabComponent implements OnInit, OnDest
); );
} }
/**
* Deselect all items
*/
deselectAll() { deselectAll() {
this.allSelected = false; this.allSelected = false;
this.selection$ this.selection$

View File

@@ -25,6 +25,9 @@ import { Context } from '../../../../../../core/shared/context.model';
] ]
}) })
/**
* Tab for inside the lookup model that represents the currently selected relationships
*/
export class DsDynamicLookupRelationSelectionTabComponent { export class DsDynamicLookupRelationSelectionTabComponent {
@Input() label: string; @Input() label: string;
@Input() listId: string; @Input() listId: string;
@@ -44,6 +47,9 @@ export class DsDynamicLookupRelationSelectionTabComponent {
private searchConfigService: SearchConfigurationService) { private searchConfigService: SearchConfigurationService) {
} }
/**
* Set up the selection and pagination on load
*/
ngOnInit() { ngOnInit() {
this.resetRoute(); this.resetRoute();
this.selectionRD$ = this.searchConfigService.paginatedSearchOptions this.selectionRD$ = this.searchConfigService.paginatedSearchOptions
@@ -70,6 +76,9 @@ export class DsDynamicLookupRelationSelectionTabComponent {
) )
} }
/**
* Method to reset the route when the window is opened to make sure no strange pagination issues appears
*/
resetRoute() { resetRoute() {
this.router.navigate([], { this.router.navigate([], {
queryParams: Object.assign({}, { page: 1, pageSize: this.initialPagination.pageSize }), queryParams: Object.assign({}, { page: 1, pageSize: this.initialPagination.pageSize }),

View File

@@ -1,5 +1,8 @@
const RELATION_METADATA_PREFIX = 'relation.' const RELATION_METADATA_PREFIX = 'relation.'
/**
* The submission options for fields that can represent relationships
*/
export class RelationshipOptions { export class RelationshipOptions {
relationshipType: string; relationshipType: string;
filter: string; filter: string;

View File

@@ -2,6 +2,9 @@ import { FieldParser } from './field-parser';
import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model'; import { FormFieldMetadataValueObject } from '../models/form-field-metadata-value.model';
import { DsDynamicDisabledModelConfig, DynamicDisabledModel } from '../ds-dynamic-form-ui/models/disabled/dynamic-disabled.model'; import { DsDynamicDisabledModelConfig, DynamicDisabledModel } from '../ds-dynamic-form-ui/models/disabled/dynamic-disabled.model';
/**
* Field parser for disabled fields
*/
export class DisabledFieldParser extends FieldParser { export class DisabledFieldParser extends FieldParser {
public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any { public modelFactory(fieldValue?: FormFieldMetadataValueObject | any, label?: boolean): any {

View File

@@ -27,6 +27,9 @@ const fieldParserDeps = [
PARSER_OPTIONS, PARSER_OPTIONS,
]; ];
/**
* Method to retrieve a field parder with its providers based on the input type
*/
export class ParserFactory { export class ParserFactory {
public static getProvider(type: ParserType): StaticProvider { public static getProvider(type: ParserType): StaticProvider {
switch (type) { switch (type) {

View File

@@ -27,6 +27,10 @@ export const ROW_ID_PREFIX = 'df-row-group-config-';
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
/**
* Parser the submission data for a single row
*/
export class RowParser { export class RowParser {
constructor(private parentInjector: Injector) { constructor(private parentInjector: Injector) {
} }

View File

@@ -19,6 +19,9 @@ export const SelectableListActionTypes = {
DESELECT_ALL: type('dspace/selectable-lists/DESELECT_ALL') DESELECT_ALL: type('dspace/selectable-lists/DESELECT_ALL')
}; };
/**
* Abstract action class for actions on selectable lists
*/
/* tslint:disable:max-classes-per-file */ /* tslint:disable:max-classes-per-file */
export abstract class SelectableListAction implements Action { export abstract class SelectableListAction implements Action {
// tslint:disable-next-line:no-shadowed-variable // tslint:disable-next-line:no-shadowed-variable
@@ -27,7 +30,7 @@ export abstract class SelectableListAction implements Action {
} }
/** /**
* Used to select an item in a the selectable list * Action to select objects in a the selectable list
*/ */
export class SelectableListSelectAction extends SelectableListAction { export class SelectableListSelectAction extends SelectableListAction {
payload: ListableObject[]; payload: ListableObject[];
@@ -37,7 +40,9 @@ export class SelectableListSelectAction extends SelectableListAction {
this.payload = objects; this.payload = objects;
} }
} }
/**
* Action to select a single object in a the selectable list
*/
export class SelectableListSelectSingleAction extends SelectableListAction { export class SelectableListSelectSingleAction extends SelectableListAction {
payload: { payload: {
object: ListableObject, object: ListableObject,
@@ -49,6 +54,9 @@ export class SelectableListSelectSingleAction extends SelectableListAction {
} }
} }
/**
* Action to deselect objects in a the selectable list
*/
export class SelectableListDeselectSingleAction extends SelectableListAction { export class SelectableListDeselectSingleAction extends SelectableListAction {
payload: ListableObject; payload: ListableObject;
@@ -58,6 +66,9 @@ export class SelectableListDeselectSingleAction extends SelectableListAction {
} }
} }
/**
* Action to deselect a single object in a the selectable list
*/
export class SelectableListDeselectAction extends SelectableListAction { export class SelectableListDeselectAction extends SelectableListAction {
payload: ListableObject[]; payload: ListableObject[];
@@ -67,6 +78,9 @@ export class SelectableListDeselectAction extends SelectableListAction {
} }
} }
/**
* Action to set a new or overwrite an existing selection
*/
export class SelectableListSetSelectionAction extends SelectableListAction { export class SelectableListSetSelectionAction extends SelectableListAction {
payload: ListableObject[]; payload: ListableObject[];
@@ -76,6 +90,9 @@ export class SelectableListSetSelectionAction extends SelectableListAction {
} }
} }
/**
* Action to deselect all currently selected objects
*/
export class SelectableListDeselectAllAction extends SelectableListAction { export class SelectableListDeselectAllAction extends SelectableListAction {
constructor(id: string) { constructor(id: string) {
super(SelectableListActionTypes.DESELECT_ALL, id); super(SelectableListActionTypes.DESELECT_ALL, id);

View File

@@ -63,12 +63,22 @@ export function selectableListReducer(state: SelectableListsState = {}, action:
} }
} }
/**
* Adds multiple objects to the existing selection state
* @param state The current state
* @param action The action to perform
*/
function select(state: SelectableListState, action: SelectableListSelectAction) { function select(state: SelectableListState, action: SelectableListSelectAction) {
const filteredNewObjects = action.payload.filter((object) => !isObjectInSelection(state.selection, object)); const filteredNewObjects = action.payload.filter((object) => !isObjectInSelection(state.selection, object));
const newSelection = [...state.selection, ...filteredNewObjects]; const newSelection = [...state.selection, ...filteredNewObjects];
return Object.assign({}, state, { selection: newSelection }); return Object.assign({}, state, { selection: newSelection });
} }
/**
* Adds a single object to the existing selection state
* @param state The current state
* @param action The action to perform
*/
function selectSingle(state: SelectableListState, action: SelectableListSelectSingleAction) { function selectSingle(state: SelectableListState, action: SelectableListSelectSingleAction) {
let newSelection = state.selection; let newSelection = state.selection;
if (!isObjectInSelection(state.selection, action.payload.object)) { if (!isObjectInSelection(state.selection, action.payload.object)) {
@@ -77,11 +87,21 @@ function selectSingle(state: SelectableListState, action: SelectableListSelectSi
return Object.assign({}, state, { selection: newSelection }); return Object.assign({}, state, { selection: newSelection });
} }
/**
* Removes multiple objects in the existing selection state
* @param state The current state
* @param action The action to perform
*/
function deselect(state: SelectableListState, action: SelectableListDeselectAction) { function deselect(state: SelectableListState, action: SelectableListDeselectAction) {
const newSelection = state.selection.filter((selected) => hasNoValue(action.payload.find((object) => object.equals(selected)))); const newSelection = state.selection.filter((selected) => hasNoValue(action.payload.find((object) => object.equals(selected))));
return Object.assign({}, state, { selection: newSelection }); return Object.assign({}, state, { selection: newSelection });
} }
/** Removes a single object from the existing selection state
*
* @param state The current state
* @param action The action to perform
*/
function deselectSingle(state: SelectableListState, action: SelectableListDeselectSingleAction) { function deselectSingle(state: SelectableListState, action: SelectableListDeselectSingleAction) {
const newSelection = state.selection.filter((selected) => { const newSelection = state.selection.filter((selected) => {
return !selected.equals(action.payload); return !selected.equals(action.payload);
@@ -89,14 +109,29 @@ function deselectSingle(state: SelectableListState, action: SelectableListDesele
return Object.assign({}, state, { selection: newSelection }); return Object.assign({}, state, { selection: newSelection });
} }
/**
* Sets the selection state of the list
* @param state The current state
* @param action The action to perform
*/
function setList(state: SelectableListState, action: SelectableListSetSelectionAction) { function setList(state: SelectableListState, action: SelectableListSetSelectionAction) {
return Object.assign({}, state, { selection: action.payload }); return Object.assign({}, state, { selection: action.payload });
} }
/**
* Clears the selection
* @param state The current state
* @param action The action to perform
*/
function clearSelection(id: string) { function clearSelection(id: string) {
return { id: id, selection: [] }; return { id: id, selection: [] };
} }
/**
* Checks whether the object is in currently in the selection
* @param state The current state
* @param action The action to perform
*/
function isObjectInSelection(selection: ListableObject[], object: ListableObject) { function isObjectInSelection(selection: ListableObject[], object: ListableObject) {
return selection.findIndex((selected) => selected.equals(object)) >= 0 return selection.findIndex((selected) => selected.equals(object)) >= 0
} }