eldewrito-menu/packages/frontend/src/website/redux/ui/index.js

132 lines
2.7 KiB
JavaScript

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;