mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
138 lines
5.0 KiB
TypeScript
138 lines
5.0 KiB
TypeScript
import { ListableObject } from '../../object-collection/shared/listable-object.model';
|
|
import {
|
|
SelectableListAction,
|
|
SelectableListActionTypes,
|
|
SelectableListSelectAction,
|
|
SelectableListSelectSingleAction,
|
|
SelectableListDeselectAction,
|
|
SelectableListDeselectSingleAction, SelectableListSetSelectionAction
|
|
} from './selectable-list.actions';
|
|
import { hasNoValue } from '../../empty.util';
|
|
|
|
/**
|
|
* Represents the state of all selectable lists in the store
|
|
*/
|
|
export interface SelectableListsState {
|
|
[id: string]: SelectableListState;
|
|
}
|
|
|
|
/**
|
|
* Represents the state of a single selectable list in the store
|
|
*/
|
|
export interface SelectableListState {
|
|
id: string;
|
|
selection: ListableObject[];
|
|
}
|
|
|
|
/**
|
|
* Reducer that handles SelectableListAction to update the SelectableListsState
|
|
* @param {SelectableListsState} state The initial SelectableListsState
|
|
* @param {SelectableListAction} action The Action to be performed on the state
|
|
* @returns {SelectableListsState} The new, reducer SelectableListsState
|
|
*/
|
|
export function selectableListReducer(state: SelectableListsState = {}, action: SelectableListAction): SelectableListsState {
|
|
const listState: SelectableListState = state[action.id] || clearSelection(action.id);
|
|
switch (action.type) {
|
|
case SelectableListActionTypes.SELECT: {
|
|
const newListState = select(listState, action as SelectableListSelectAction);
|
|
return Object.assign({}, state, { [action.id]: newListState });
|
|
}
|
|
case SelectableListActionTypes.SELECT_SINGLE: {
|
|
const newListState = selectSingle(listState, action as SelectableListSelectSingleAction);
|
|
return Object.assign({}, state, { [action.id]: newListState });
|
|
}
|
|
case SelectableListActionTypes.DESELECT: {
|
|
const newListState = deselect(listState, action as SelectableListDeselectAction);
|
|
return Object.assign({}, state, { [action.id]: newListState });
|
|
}
|
|
case SelectableListActionTypes.DESELECT_SINGLE: {
|
|
const newListState = deselectSingle(listState, action as SelectableListDeselectSingleAction);
|
|
return Object.assign({}, state, { [action.id]: newListState });
|
|
}
|
|
case SelectableListActionTypes.SET_SELECTION: {
|
|
const newListState = setList(listState, action as SelectableListSetSelectionAction);
|
|
return Object.assign({}, state, { [action.id]: newListState });
|
|
}
|
|
case SelectableListActionTypes.DESELECT_ALL: {
|
|
const newListState = clearSelection(action.id);
|
|
return Object.assign({}, state, { [action.id]: newListState });
|
|
}
|
|
default: {
|
|
return state;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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) {
|
|
const filteredNewObjects = action.payload.filter((object) => !isObjectInSelection(state.selection, object));
|
|
const newSelection = [...state.selection, ...filteredNewObjects];
|
|
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) {
|
|
let newSelection = state.selection;
|
|
if (!isObjectInSelection(state.selection, action.payload.object)) {
|
|
newSelection = [...state.selection, action.payload.object];
|
|
}
|
|
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) {
|
|
const newSelection = state.selection.filter((selected) => hasNoValue(action.payload.find((object) => object.equals(selected))));
|
|
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) {
|
|
const newSelection = state.selection.filter((selected) => {
|
|
return !selected.equals(action.payload);
|
|
});
|
|
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) {
|
|
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) {
|
|
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) {
|
|
return selection.findIndex((selected) => selected.equals(object)) >= 0
|
|
}
|