Choices/src/scripts/reducers/choices.ts
Josh Johnson 68313da412
Convert to typescript (#795)
* Typescript config setup

* Add type annotations to components

* Further type additions

* And more...

* Add types to actions

* Add types to templates

* Further type checks

* Further type additons

* Install fuse latest

* Housekeeping

* Remove old type definitions

* Fix remaning type issues

* Fix some failing tests

* Remove types workflow

* Fix failing unit tests

* Resolve back space event regression

* Convert cypress files to .ts

* Fix eslint issues

* Remove cachebusting urls

* Resolve delete button bug

* Resolve regression bugs

* Fix lint script

* Fix lint workflow

* Pass args instead of object to keyboard handlers

* Flatten misc reducer

* Resolve keyboad action test failures

* Use Pick instead of Partial

* Use interfaces in action tests

* Update firefox image

* Incorporate #791

* Incorporate #788
2019-12-23 18:22:54 +00:00

128 lines
3.3 KiB
TypeScript

import { Choice } from '../interfaces';
import {
AddChoiceAction,
FilterChoicesAction,
ActivateChoicesAction,
ClearChoicesAction,
} from '../actions/choices';
import { AddItemAction, RemoveItemAction } from '../actions/items';
export const defaultState = [];
type ActionTypes =
| AddChoiceAction
| FilterChoicesAction
| ActivateChoicesAction
| ClearChoicesAction
| AddItemAction
| RemoveItemAction;
export default function choices(
state: Choice[] = defaultState,
action: ActionTypes,
): Choice[] {
switch (action.type) {
case 'ADD_CHOICE': {
const addChoiceAction = action as AddChoiceAction;
const choice = {
id: addChoiceAction.id,
elementId: addChoiceAction.elementId,
groupId: addChoiceAction.groupId,
value: addChoiceAction.value,
label: addChoiceAction.label || addChoiceAction.value,
disabled: addChoiceAction.disabled || false,
selected: false,
active: true,
score: 9999,
customProperties: addChoiceAction.customProperties,
placeholder: addChoiceAction.placeholder || false,
};
/*
A disabled choice appears in the choice dropdown but cannot be selected
A selected choice has been added to the passed input's value (added as an item)
An active choice appears within the choice dropdown
*/
return [...state, choice as Choice];
}
case 'ADD_ITEM': {
const addItemAction = action as AddItemAction;
// When an item is added and it has an associated choice,
// we want to disable it so it can't be chosen again
if (addItemAction.choiceId > -1) {
return state.map(obj => {
const choice = obj;
if (choice.id === parseInt(`${addItemAction.choiceId}`, 10)) {
choice.selected = true;
}
return choice;
});
}
return state;
}
case 'REMOVE_ITEM': {
const removeItemAction = action as RemoveItemAction;
// When an item is removed and it has an associated choice,
// we want to re-enable it so it can be chosen again
if (removeItemAction.choiceId && removeItemAction.choiceId > -1) {
return state.map(obj => {
const choice = obj;
if (choice.id === parseInt(`${removeItemAction.choiceId}`, 10)) {
choice.selected = false;
}
return choice;
});
}
return state;
}
case 'FILTER_CHOICES': {
const filterChoicesAction = action as FilterChoicesAction;
return state.map(obj => {
const choice = obj;
// Set active state based on whether choice is
// within filtered results
choice.active = filterChoicesAction.results.some(({ item, score }) => {
if (item.id === choice.id) {
choice.score = score;
return true;
}
return false;
});
return choice;
});
}
case 'ACTIVATE_CHOICES': {
const activateChoicesAction = action as ActivateChoicesAction;
return state.map(obj => {
const choice = obj;
choice.active = activateChoicesAction.active;
return choice;
});
}
case 'CLEAR_CHOICES': {
return defaultState;
}
default: {
return state;
}
}
}