mirror of
https://github.com/Choices-js/Choices.git
synced 2024-06-03 14:32:11 +02:00
Further type additons
This commit is contained in:
parent
5a47867a19
commit
d93358e1e4
|
@ -1,7 +1,33 @@
|
||||||
import { Action } from 'redux';
|
|
||||||
import { ACTION_TYPES } from '../constants';
|
import { ACTION_TYPES } from '../constants';
|
||||||
import { Choice } from '../interfaces';
|
import { Choice } from '../interfaces';
|
||||||
|
|
||||||
|
export interface AddChoiceAction {
|
||||||
|
type: typeof ACTION_TYPES.ADD_CHOICE;
|
||||||
|
id: number;
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
groupId: number;
|
||||||
|
disabled: boolean;
|
||||||
|
elementId: number;
|
||||||
|
customProperties: object;
|
||||||
|
placeholder: boolean;
|
||||||
|
keyCode: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterChoicesAction {
|
||||||
|
type: typeof ACTION_TYPES.FILTER_CHOICES;
|
||||||
|
results: Choice[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ActivateChoicesAction {
|
||||||
|
type: typeof ACTION_TYPES.ACTIVATE_CHOICES;
|
||||||
|
active: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClearChoicesAction {
|
||||||
|
type: typeof ACTION_TYPES.CLEAR_CHOICES;
|
||||||
|
}
|
||||||
|
|
||||||
export const addChoice = ({
|
export const addChoice = ({
|
||||||
value,
|
value,
|
||||||
label,
|
label,
|
||||||
|
@ -12,7 +38,7 @@ export const addChoice = ({
|
||||||
customProperties,
|
customProperties,
|
||||||
placeholder,
|
placeholder,
|
||||||
keyCode,
|
keyCode,
|
||||||
}): Action & Choice => ({
|
}): AddChoiceAction => ({
|
||||||
type: ACTION_TYPES.ADD_CHOICE,
|
type: ACTION_TYPES.ADD_CHOICE,
|
||||||
value,
|
value,
|
||||||
label,
|
label,
|
||||||
|
@ -25,20 +51,16 @@ export const addChoice = ({
|
||||||
keyCode,
|
keyCode,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const filterChoices = (
|
export const filterChoices = (results: Choice[]): FilterChoicesAction => ({
|
||||||
results: Choice[],
|
|
||||||
): Action & { results: Choice[] } => ({
|
|
||||||
type: ACTION_TYPES.FILTER_CHOICES,
|
type: ACTION_TYPES.FILTER_CHOICES,
|
||||||
results,
|
results,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const activateChoices = (
|
export const activateChoices = (active = true): ActivateChoicesAction => ({
|
||||||
active = true,
|
|
||||||
): Action & { active: boolean } => ({
|
|
||||||
type: ACTION_TYPES.ACTIVATE_CHOICES,
|
type: ACTION_TYPES.ACTIVATE_CHOICES,
|
||||||
active,
|
active,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const clearChoices = (): Action => ({
|
export const clearChoices = (): ClearChoicesAction => ({
|
||||||
type: ACTION_TYPES.CLEAR_CHOICES,
|
type: ACTION_TYPES.CLEAR_CHOICES,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,13 +1,24 @@
|
||||||
import { Action } from 'redux';
|
|
||||||
import { ACTION_TYPES } from '../constants';
|
import { ACTION_TYPES } from '../constants';
|
||||||
import { Group } from '../interfaces';
|
|
||||||
|
export interface AddGroupAction {
|
||||||
|
type: typeof ACTION_TYPES.ADD_GROUP;
|
||||||
|
id: number;
|
||||||
|
value: string;
|
||||||
|
active: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export const addGroup = ({
|
export const addGroup = ({
|
||||||
value,
|
value,
|
||||||
id,
|
id,
|
||||||
active,
|
active,
|
||||||
disabled,
|
disabled,
|
||||||
}: Group): Action & Group => ({
|
}: {
|
||||||
|
id: number;
|
||||||
|
value: string;
|
||||||
|
active: boolean;
|
||||||
|
disabled: boolean;
|
||||||
|
}): AddGroupAction => ({
|
||||||
type: ACTION_TYPES.ADD_GROUP,
|
type: ACTION_TYPES.ADD_GROUP,
|
||||||
value,
|
value,
|
||||||
id,
|
id,
|
||||||
|
|
|
@ -1,6 +1,28 @@
|
||||||
import { Action } from 'redux';
|
|
||||||
import { ACTION_TYPES } from '../constants';
|
import { ACTION_TYPES } from '../constants';
|
||||||
import { Item } from '../interfaces';
|
|
||||||
|
export interface AddItemAction {
|
||||||
|
type: typeof ACTION_TYPES.ADD_ITEM;
|
||||||
|
id: number;
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
choiceId: number;
|
||||||
|
groupId: number;
|
||||||
|
customProperties: object;
|
||||||
|
placeholder: boolean;
|
||||||
|
keyCode: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RemoveItemAction {
|
||||||
|
type: typeof ACTION_TYPES.REMOVE_ITEM;
|
||||||
|
id: number;
|
||||||
|
choiceId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HighlightItemAction {
|
||||||
|
type: typeof ACTION_TYPES.HIGHLIGHT_ITEM;
|
||||||
|
id: number;
|
||||||
|
highlighted: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export const addItem = ({
|
export const addItem = ({
|
||||||
value,
|
value,
|
||||||
|
@ -11,7 +33,16 @@ export const addItem = ({
|
||||||
customProperties,
|
customProperties,
|
||||||
placeholder,
|
placeholder,
|
||||||
keyCode,
|
keyCode,
|
||||||
}: Item): Action & Item => ({
|
}: {
|
||||||
|
id: number;
|
||||||
|
value: string;
|
||||||
|
label: string;
|
||||||
|
choiceId: number;
|
||||||
|
groupId: number;
|
||||||
|
customProperties: object;
|
||||||
|
placeholder: boolean;
|
||||||
|
keyCode: number;
|
||||||
|
}): AddItemAction => ({
|
||||||
type: ACTION_TYPES.ADD_ITEM,
|
type: ACTION_TYPES.ADD_ITEM,
|
||||||
value,
|
value,
|
||||||
label,
|
label,
|
||||||
|
@ -23,10 +54,7 @@ export const addItem = ({
|
||||||
keyCode,
|
keyCode,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const removeItem = (
|
export const removeItem = (id: number, choiceId: number): RemoveItemAction => ({
|
||||||
id: number,
|
|
||||||
choiceId: number,
|
|
||||||
): Action & { id: number; choiceId: number } => ({
|
|
||||||
type: ACTION_TYPES.REMOVE_ITEM,
|
type: ACTION_TYPES.REMOVE_ITEM,
|
||||||
id,
|
id,
|
||||||
choiceId,
|
choiceId,
|
||||||
|
@ -35,7 +63,7 @@ export const removeItem = (
|
||||||
export const highlightItem = (
|
export const highlightItem = (
|
||||||
id: number,
|
id: number,
|
||||||
highlighted: boolean,
|
highlighted: boolean,
|
||||||
): Action & { id: number; highlighted: boolean } => ({
|
): HighlightItemAction => ({
|
||||||
type: ACTION_TYPES.HIGHLIGHT_ITEM,
|
type: ACTION_TYPES.HIGHLIGHT_ITEM,
|
||||||
id,
|
id,
|
||||||
highlighted,
|
highlighted,
|
||||||
|
|
|
@ -1,18 +1,30 @@
|
||||||
import { Action } from 'redux';
|
|
||||||
import { State } from '../interfaces';
|
import { State } from '../interfaces';
|
||||||
|
import { ACTION_TYPES } from '../constants';
|
||||||
|
|
||||||
export const clearAll = (): Action => ({
|
export interface ClearAllAction {
|
||||||
type: 'CLEAR_ALL',
|
type: typeof ACTION_TYPES.CLEAR_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResetToAction {
|
||||||
|
type: typeof ACTION_TYPES.RESET_TO;
|
||||||
|
state: State;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SetIsLoadingAction {
|
||||||
|
type: typeof ACTION_TYPES.SET_IS_LOADING;
|
||||||
|
isLoading: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const clearAll = (): ClearAllAction => ({
|
||||||
|
type: ACTION_TYPES.CLEAR_ALL,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const resetTo = (state: State): Action & { state: State } => ({
|
export const resetTo = (state: State): ResetToAction => ({
|
||||||
type: 'RESET_TO',
|
type: ACTION_TYPES.RESET_TO,
|
||||||
state,
|
state,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const setIsLoading = (
|
export const setIsLoading = (isLoading: boolean): SetIsLoadingAction => ({
|
||||||
isLoading: boolean,
|
type: ACTION_TYPES.SET_IS_LOADING,
|
||||||
): Action & { isLoading: boolean } => ({
|
|
||||||
type: 'SET_IS_LOADING',
|
|
||||||
isLoading,
|
isLoading,
|
||||||
});
|
});
|
||||||
|
|
|
@ -370,7 +370,7 @@ class Choices {
|
||||||
}
|
}
|
||||||
|
|
||||||
highlightItem(item: Item, runEvent = true): this {
|
highlightItem(item: Item, runEvent = true): this {
|
||||||
if (!item) {
|
if (!item || !item.id) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +392,7 @@ class Choices {
|
||||||
}
|
}
|
||||||
|
|
||||||
unhighlightItem(item: Item): this {
|
unhighlightItem(item: Item): this {
|
||||||
if (!item) {
|
if (!item || !item.id) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -967,7 +967,9 @@ class Choices {
|
||||||
|
|
||||||
if (this._isTextElement) {
|
if (this._isTextElement) {
|
||||||
// Update the value of the hidden input
|
// Update the value of the hidden input
|
||||||
this.passedElement.value = items;
|
this.passedElement.value = items
|
||||||
|
.map(({ value }) => value)
|
||||||
|
.join(this.config.delimiter);
|
||||||
} else {
|
} else {
|
||||||
// Update the options of the hidden input
|
// Update the options of the hidden input
|
||||||
(this.passedElement as WrappedSelect).options = items;
|
(this.passedElement as WrappedSelect).options = items;
|
||||||
|
@ -1912,22 +1914,20 @@ class Choices {
|
||||||
label = null,
|
label = null,
|
||||||
choiceId = -1,
|
choiceId = -1,
|
||||||
groupId = -1,
|
groupId = -1,
|
||||||
customProperties = null,
|
customProperties = {},
|
||||||
placeholder = false,
|
placeholder = false,
|
||||||
keyCode = null,
|
keyCode = -1,
|
||||||
}: {
|
}: {
|
||||||
value: string;
|
value: string;
|
||||||
label?: string | null;
|
label?: string | null;
|
||||||
choiceId?: number;
|
choiceId?: number;
|
||||||
groupId?: number;
|
groupId?: number;
|
||||||
customProperties?: object | null;
|
customProperties?: object;
|
||||||
placeholder?: boolean;
|
placeholder?: boolean;
|
||||||
keyCode?: number | null;
|
keyCode?: number;
|
||||||
}): void {
|
}): void {
|
||||||
let passedValue = typeof value === 'string' ? value.trim() : value;
|
let passedValue = typeof value === 'string' ? value.trim() : value;
|
||||||
|
|
||||||
const passedKeyCode = keyCode;
|
|
||||||
const passedCustomProperties = customProperties;
|
|
||||||
const { items } = this._store;
|
const { items } = this._store;
|
||||||
const passedLabel = label || passedValue;
|
const passedLabel = label || passedValue;
|
||||||
const passedOptionId = choiceId || -1;
|
const passedOptionId = choiceId || -1;
|
||||||
|
@ -1953,7 +1953,7 @@ class Choices {
|
||||||
groupId,
|
groupId,
|
||||||
customProperties,
|
customProperties,
|
||||||
placeholder,
|
placeholder,
|
||||||
keyCode: passedKeyCode,
|
keyCode,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1966,9 +1966,9 @@ class Choices {
|
||||||
id,
|
id,
|
||||||
value: passedValue,
|
value: passedValue,
|
||||||
label: passedLabel,
|
label: passedLabel,
|
||||||
customProperties: passedCustomProperties,
|
customProperties,
|
||||||
groupValue: group && group.value ? group.value : null,
|
groupValue: group && group.value ? group.value : null,
|
||||||
keyCode: passedKeyCode,
|
keyCode,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1977,6 +1977,10 @@ class Choices {
|
||||||
const group =
|
const group =
|
||||||
groupId && groupId >= 0 ? this._store.getGroupById(groupId) : null;
|
groupId && groupId >= 0 ? this._store.getGroupById(groupId) : null;
|
||||||
|
|
||||||
|
if (!id || !choiceId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this._store.dispatch(removeItem(id, choiceId));
|
this._store.dispatch(removeItem(id, choiceId));
|
||||||
this.passedElement.triggerEvent(EVENTS.removeItem, {
|
this.passedElement.triggerEvent(EVENTS.removeItem, {
|
||||||
id,
|
id,
|
||||||
|
@ -1993,18 +1997,18 @@ class Choices {
|
||||||
isSelected = false,
|
isSelected = false,
|
||||||
isDisabled = false,
|
isDisabled = false,
|
||||||
groupId = -1,
|
groupId = -1,
|
||||||
customProperties = null,
|
customProperties = {},
|
||||||
placeholder = false,
|
placeholder = false,
|
||||||
keyCode = null,
|
keyCode = -1,
|
||||||
}: {
|
}: {
|
||||||
value: string;
|
value: string;
|
||||||
label?: string | null;
|
label?: string | null;
|
||||||
isSelected?: boolean;
|
isSelected?: boolean;
|
||||||
isDisabled?: boolean;
|
isDisabled?: boolean;
|
||||||
groupId?: number;
|
groupId?: number;
|
||||||
customProperties?: Record<string, any> | null;
|
customProperties?: Record<string, any>;
|
||||||
placeholder?: boolean;
|
placeholder?: boolean;
|
||||||
keyCode?: number | null;
|
keyCode?: number;
|
||||||
}): void {
|
}): void {
|
||||||
if (typeof value === 'undefined' || value === null) {
|
if (typeof value === 'undefined' || value === null) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -22,11 +22,8 @@ export default class WrappedInput extends WrappedElement {
|
||||||
return this.element.value;
|
return this.element.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
set value(items: Item[]): void {
|
set value(value: string) {
|
||||||
const itemValues = items.map(({ value }) => value);
|
this.element.setAttribute('value', value);
|
||||||
const joinedValues = itemValues.join(this.delimiter);
|
this.element.value = value;
|
||||||
|
|
||||||
this.element.setAttribute('value', joinedValues);
|
|
||||||
this.element.value = joinedValues;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,6 +106,8 @@ export const ACTION_TYPES: Record<ActionType, ActionType> = {
|
||||||
REMOVE_ITEM: 'REMOVE_ITEM',
|
REMOVE_ITEM: 'REMOVE_ITEM',
|
||||||
HIGHLIGHT_ITEM: 'HIGHLIGHT_ITEM',
|
HIGHLIGHT_ITEM: 'HIGHLIGHT_ITEM',
|
||||||
CLEAR_ALL: 'CLEAR_ALL',
|
CLEAR_ALL: 'CLEAR_ALL',
|
||||||
|
RESET_TO: 'RESET_TO',
|
||||||
|
SET_IS_LOADING: 'SET_IS_LOADING',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const KEY_CODES: KeyCodeMap = {
|
export const KEY_CODES: KeyCodeMap = {
|
||||||
|
|
|
@ -29,6 +29,7 @@ export interface Choice {
|
||||||
selected?: boolean;
|
selected?: boolean;
|
||||||
value: string;
|
value: string;
|
||||||
score?: number;
|
score?: number;
|
||||||
|
choices?: Choice[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Group {
|
export interface Group {
|
||||||
|
@ -39,7 +40,6 @@ export interface Group {
|
||||||
}
|
}
|
||||||
export interface Item extends Choice {
|
export interface Item extends Choice {
|
||||||
choiceId?: number;
|
choiceId?: number;
|
||||||
keyCode?: number;
|
|
||||||
highlighted?: boolean;
|
highlighted?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +179,9 @@ export type ActionType =
|
||||||
| 'ADD_ITEM'
|
| 'ADD_ITEM'
|
||||||
| 'REMOVE_ITEM'
|
| 'REMOVE_ITEM'
|
||||||
| 'HIGHLIGHT_ITEM'
|
| 'HIGHLIGHT_ITEM'
|
||||||
| 'CLEAR_ALL';
|
| 'CLEAR_ALL'
|
||||||
|
| 'RESET_TO'
|
||||||
|
| 'SET_IS_LOADING';
|
||||||
|
|
||||||
export interface Templates {
|
export interface Templates {
|
||||||
containerOuter: (
|
containerOuter: (
|
||||||
|
@ -813,9 +815,9 @@ export interface Notice {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
choices: Choice[];
|
choices: object[];
|
||||||
groups: Group[];
|
groups: object[];
|
||||||
items: Item[];
|
items: object[];
|
||||||
general: {
|
general: {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { EventMap } from '../interfaces';
|
import { EventMap, Choice } from '../interfaces';
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
|
@ -126,10 +126,12 @@ export const sortByAlpha = (
|
||||||
numeric: true,
|
numeric: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const sortByScore = (
|
export const sortByScore = (a: Choice, b: Choice): number => {
|
||||||
a: { score: number },
|
const { score: scoreA = 0 } = a;
|
||||||
b: { score: number },
|
const { score: scoreB = 0 } = b;
|
||||||
): number => a.score - b.score;
|
|
||||||
|
return scoreA - scoreB;
|
||||||
|
};
|
||||||
|
|
||||||
export const dispatchEvent = (
|
export const dispatchEvent = (
|
||||||
element: HTMLElement,
|
element: HTMLElement,
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
import { Action } from 'redux';
|
import { Choice, State } from '../interfaces';
|
||||||
import { Choice, Item } from '../interfaces';
|
import {
|
||||||
|
AddChoiceAction,
|
||||||
|
FilterChoicesAction,
|
||||||
|
ActivateChoicesAction,
|
||||||
|
ClearChoicesAction,
|
||||||
|
} from '../actions/choices';
|
||||||
|
import { AddItemAction, RemoveItemAction } from '../actions/items';
|
||||||
|
|
||||||
export const defaultState = [];
|
export const defaultState = [];
|
||||||
|
|
||||||
|
@ -8,53 +14,53 @@ interface Result {
|
||||||
score: number;
|
score: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ActionTypes =
|
||||||
|
| AddChoiceAction
|
||||||
|
| FilterChoicesAction
|
||||||
|
| ActivateChoicesAction
|
||||||
|
| ClearChoicesAction
|
||||||
|
| AddItemAction
|
||||||
|
| RemoveItemAction;
|
||||||
|
|
||||||
export default function choices(
|
export default function choices(
|
||||||
state: Choice[] = defaultState,
|
state: Choice[] = defaultState,
|
||||||
action: Action,
|
action: ActionTypes,
|
||||||
): Choice[] {
|
): State['choices'] {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'ADD_CHOICE': {
|
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,
|
||||||
|
keyCode: null,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A disabled choice appears in the choice dropdown but cannot be selected
|
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)
|
A selected choice has been added to the passed input's value (added as an item)
|
||||||
An active choice appears within the choice dropdown
|
An active choice appears within the choice dropdown
|
||||||
*/
|
*/
|
||||||
return [
|
return [...state, choice];
|
||||||
...state,
|
|
||||||
{
|
|
||||||
id: action.id,
|
|
||||||
elementId: action.elementId,
|
|
||||||
groupId: action.groupId,
|
|
||||||
value: action.value,
|
|
||||||
label: action.label || action.value,
|
|
||||||
disabled: action.disabled || false,
|
|
||||||
selected: false,
|
|
||||||
active: true,
|
|
||||||
score: 9999,
|
|
||||||
customProperties: action.customProperties,
|
|
||||||
placeholder: action.placeholder || false,
|
|
||||||
keyCode: null,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'ADD_ITEM': {
|
case 'ADD_ITEM': {
|
||||||
// If all choices need to be activated
|
const addItemAction = action as AddItemAction;
|
||||||
if (action.activateOptions) {
|
|
||||||
return state.map(obj => {
|
|
||||||
const choice = obj;
|
|
||||||
choice.active = action.active;
|
|
||||||
|
|
||||||
return choice;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// When an item is added and it has an associated choice,
|
// When an item is added and it has an associated choice,
|
||||||
// we want to disable it so it can't be chosen again
|
// we want to disable it so it can't be chosen again
|
||||||
if (action.choiceId > -1) {
|
if (addItemAction.choiceId > -1) {
|
||||||
return state.map(obj => {
|
return state.map(obj => {
|
||||||
const choice = obj;
|
const choice = obj;
|
||||||
if (choice.id === parseInt(action.choiceId, 10)) {
|
if (choice.id === parseInt(`${addItemAction.choiceId}`, 10)) {
|
||||||
choice.selected = true;
|
choice.selected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,12 +72,14 @@ export default function choices(
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'REMOVE_ITEM': {
|
case 'REMOVE_ITEM': {
|
||||||
|
const removeItemAction = action as RemoveItemAction;
|
||||||
|
|
||||||
// When an item is removed and it has an associated choice,
|
// When an item is removed and it has an associated choice,
|
||||||
// we want to re-enable it so it can be chosen again
|
// we want to re-enable it so it can be chosen again
|
||||||
if (action.choiceId && action.choiceId > -1) {
|
if (removeItemAction.choiceId && removeItemAction.choiceId > -1) {
|
||||||
return state.map(obj => {
|
return state.map(obj => {
|
||||||
const choice = obj;
|
const choice = obj;
|
||||||
if (choice.id === parseInt(`${action.choiceId}`, 10)) {
|
if (choice.id === parseInt(`${removeItemAction.choiceId}`, 10)) {
|
||||||
choice.selected = false;
|
choice.selected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,28 +91,34 @@ export default function choices(
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'FILTER_CHOICES': {
|
case 'FILTER_CHOICES': {
|
||||||
|
const filterChoicesAction = action as FilterChoicesAction;
|
||||||
|
|
||||||
return state.map(obj => {
|
return state.map(obj => {
|
||||||
const choice = obj;
|
const choice = obj;
|
||||||
// Set active state based on whether choice is
|
// Set active state based on whether choice is
|
||||||
// within filtered results
|
// within filtered results
|
||||||
choice.active = action.results.some(({ item, score }: Result) => {
|
choice.active = filterChoicesAction.results.some(
|
||||||
if (item.id === choice.id) {
|
({ item, score }: Result) => {
|
||||||
choice.score = score;
|
if (item.id === choice.id) {
|
||||||
|
choice.score = score;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return choice;
|
return choice;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'ACTIVATE_CHOICES': {
|
case 'ACTIVATE_CHOICES': {
|
||||||
|
const activateChoicesAction = action as ActivateChoicesAction;
|
||||||
|
|
||||||
return state.map(obj => {
|
return state.map(obj => {
|
||||||
const choice = obj;
|
const choice = obj;
|
||||||
choice.active = action.active;
|
choice.active = activateChoicesAction.active;
|
||||||
|
|
||||||
return choice;
|
return choice;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
import { Action } from 'redux';
|
import { SetIsLoadingAction } from '../actions/misc';
|
||||||
|
import { State } from '../interfaces';
|
||||||
|
|
||||||
export const defaultState = {
|
export const defaultState = {
|
||||||
loading: false,
|
loading: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ActionTypes = SetIsLoadingAction;
|
||||||
|
|
||||||
const general = (
|
const general = (
|
||||||
state = defaultState,
|
state = defaultState,
|
||||||
action: Action & { isLoading: boolean },
|
action: ActionTypes,
|
||||||
): { loading: boolean } => {
|
): State['general'] => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'SET_IS_LOADING': {
|
case 'SET_IS_LOADING': {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,21 +1,26 @@
|
||||||
import { Action } from 'redux';
|
import { Group, State } from '../interfaces';
|
||||||
import { Group } from '../interfaces';
|
import { AddGroupAction } from '../actions/groups';
|
||||||
|
import { ClearChoicesAction } from '../actions/choices';
|
||||||
|
|
||||||
export const defaultState = [];
|
export const defaultState = [];
|
||||||
|
|
||||||
|
type ActionTypes = AddGroupAction | ClearChoicesAction;
|
||||||
|
|
||||||
export default function groups(
|
export default function groups(
|
||||||
state: Group[] = defaultState,
|
state: Group[] = defaultState,
|
||||||
action: Action & Group,
|
action: ActionTypes,
|
||||||
): Group[] {
|
): State['groups'] {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'ADD_GROUP': {
|
case 'ADD_GROUP': {
|
||||||
|
const addGroupAction = action as AddGroupAction;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
...state,
|
...state,
|
||||||
{
|
{
|
||||||
id: action.id,
|
id: addGroupAction.id,
|
||||||
value: action.value,
|
value: addGroupAction.value,
|
||||||
active: action.active,
|
active: addGroupAction.active,
|
||||||
disabled: action.disabled,
|
disabled: addGroupAction.disabled,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ const appReducer = combineReducers({
|
||||||
general,
|
general,
|
||||||
});
|
});
|
||||||
|
|
||||||
const rootReducer = (passedState, action) => {
|
const rootReducer = (passedState, action): object => {
|
||||||
let state = passedState;
|
let state = passedState;
|
||||||
// If we are clearing all items, groups and options we reassign
|
// If we are clearing all items, groups and options we reassign
|
||||||
// state and then pass that state to our proper reducer. This isn't
|
// state and then pass that state to our proper reducer. This isn't
|
||||||
|
|
|
@ -16,7 +16,7 @@ describe('reducers/items', () => {
|
||||||
const customProperties = {
|
const customProperties = {
|
||||||
property: 'value',
|
property: 'value',
|
||||||
};
|
};
|
||||||
const placeholder = 'This is a placeholder';
|
const placeholder = true;
|
||||||
const keyCode = 10;
|
const keyCode = 10;
|
||||||
|
|
||||||
describe('passing expected values', () => {
|
describe('passing expected values', () => {
|
||||||
|
|
|
@ -1,27 +1,34 @@
|
||||||
import { Action } from 'redux';
|
import { Item, State } from '../interfaces';
|
||||||
import { Item } from '../interfaces';
|
import {
|
||||||
|
AddItemAction,
|
||||||
|
RemoveItemAction,
|
||||||
|
HighlightItemAction,
|
||||||
|
} from '../actions/items';
|
||||||
|
|
||||||
export const defaultState = [];
|
export const defaultState = [];
|
||||||
|
|
||||||
|
type ActionTypes = AddItemAction | RemoveItemAction | HighlightItemAction;
|
||||||
|
|
||||||
export default function items(
|
export default function items(
|
||||||
state: Item[] = defaultState,
|
state: Item[] = defaultState,
|
||||||
action: Action & Item,
|
action: ActionTypes,
|
||||||
): Item[] {
|
): State['items'] {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'ADD_ITEM': {
|
case 'ADD_ITEM': {
|
||||||
|
const addItemAction = action as AddItemAction;
|
||||||
// Add object to items array
|
// Add object to items array
|
||||||
const newState = [
|
const newState = [
|
||||||
...state,
|
...state,
|
||||||
{
|
{
|
||||||
id: action.id,
|
id: addItemAction.id,
|
||||||
choiceId: action.choiceId,
|
choiceId: addItemAction.choiceId,
|
||||||
groupId: action.groupId,
|
groupId: addItemAction.groupId,
|
||||||
value: action.value,
|
value: addItemAction.value,
|
||||||
label: action.label,
|
label: addItemAction.label,
|
||||||
active: true,
|
active: true,
|
||||||
highlighted: false,
|
highlighted: false,
|
||||||
customProperties: action.customProperties,
|
customProperties: addItemAction.customProperties,
|
||||||
placeholder: action.placeholder || false,
|
placeholder: addItemAction.placeholder || false,
|
||||||
keyCode: null,
|
keyCode: null,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -47,10 +54,12 @@ export default function items(
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'HIGHLIGHT_ITEM': {
|
case 'HIGHLIGHT_ITEM': {
|
||||||
|
const highlightItemAction = action as HighlightItemAction;
|
||||||
|
|
||||||
return state.map(obj => {
|
return state.map(obj => {
|
||||||
const item = obj;
|
const item = obj;
|
||||||
if (item.id === action.id) {
|
if (item.id === highlightItemAction.id) {
|
||||||
item.highlighted = action.highlighted;
|
item.highlighted = highlightItemAction.highlighted;
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
|
|
Loading…
Reference in a new issue