import shortid from 'shortid'; import check from '../check'; import root from '../root'; export const messageTypes = { STATUS: 0, INFO: 1, WARNING: 2, ERROR: 3, QUESTION: 4, }; export function getTypeName(type) { const matchingTypeItem = Object.entries(messageTypes) .find(item => item[1] === type); if (!matchingTypeItem) { return undefined; } return matchingTypeItem[0]; } export const initialState = { messages: [], }; const myRedux = root.sub('ui').all({ initialState, actions: { add: { params: { id: v => v === undefined || check.string(v), text: v => check.string(v), type: v => v in Object.values(messageTypes), buttons: v => v === undefined || check.array(v), }, reducer: (state, { id, buttons, ...payload }) => { let finalId = id; // generate new unique id if none given if (finalId === undefined) { const hasMatchingId = m => m.id === finalId; do { finalId = shortid.generate(); } while (state.messages.find(hasMatchingId)); } // no buttons => default to "OK" button let finalButtons = buttons; if (!finalButtons) { finalButtons = [ { text: 'OK', // TODO - localization close: true, }, ]; } return ({ ...state, messages: [ ...state.messages, { ...payload, id: finalId, buttons: finalButtons, }, ], }); }, }, update: { params: { id: v => check.string(v), text: v => v === undefined || check.string(v), progress: v => v === undefined || check.inRange(v, 0, 1), }, reducer: (state, { id, ...payload }) => ({ ...state, messages: state.messages.map(m => (m.id === id ? { ...m, ...payload } : m), ), }), }, closeMessage: { params: { id: v => check.string(v), }, reducer: (state, { id }) => ({ ...state, messages: state.messages.filter(m => m.id !== id), }), }, reset: { reducer: () => initialState, }, }, selectors: { generateMessageId: ({ messages }) => { let id; const anyMessageWithId = m => m.id === id; do { id = shortid.generate(); } while (messages.find(anyMessageWithId)); return id; }, getMessages: ({ messages }) => ([...messages]), getMessage: ({ messages }, id) => messages.find(m => m.id === id), }, }); export const { actions, actionTypes, reducer, selectors, } = myRedux;