1
0
mirror of https://gitlab.nic.cz/turris/reforis/foris-js.git synced 2024-09-21 10:04:20 +02:00
foris-js/src/form/hooks.js

106 lines
2.6 KiB
JavaScript
Raw Normal View History

2019-08-23 15:20:22 +02:00
/*
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
*
* This is free software, licensed under the GNU General Public License v3.
* See /LICENSE for more information.
*/
2019-08-27 15:28:29 +02:00
import { useCallback, useEffect, useReducer } from "react";
import update from "immutability-helper";
2019-08-23 15:20:22 +02:00
2019-09-25 13:56:08 +02:00
import { useAPIGet } from "api/get";
2019-08-27 17:46:45 +02:00
import { useWSForisModule } from "webSockets/hooks";
2019-08-23 15:20:22 +02:00
2019-08-27 15:28:29 +02:00
const FORM_ACTIONS = {
updateValue: 1,
resetData: 2,
};
2019-10-10 17:25:00 +02:00
export function useForm(validator, dataPreprocessor) {
2019-08-23 15:20:22 +02:00
const [state, dispatch] = useReducer(formReducer, {
data: null,
initialData: null,
errors: {},
});
2019-08-27 15:28:29 +02:00
const onFormReload = useCallback((data) => {
2019-08-23 15:20:22 +02:00
dispatch({
type: FORM_ACTIONS.resetData,
2019-08-27 15:28:29 +02:00
data,
2019-10-10 17:25:00 +02:00
dataPreprocessor,
2019-08-27 15:28:29 +02:00
validator,
2019-08-23 15:20:22 +02:00
});
2019-10-10 17:25:00 +02:00
}, [dataPreprocessor, validator]);
2019-08-23 15:20:22 +02:00
2019-08-27 15:28:29 +02:00
const onFormChangeHandler = useCallback((updateRule) => (event) => {
dispatch({
type: FORM_ACTIONS.updateValue,
value: getChangedValue(event.target),
updateRule,
validator,
});
}, [validator]);
2019-10-10 17:25:00 +02:00
2019-08-23 15:20:22 +02:00
return [
state,
onFormChangeHandler,
onFormReload,
2019-08-27 15:28:29 +02:00
];
2019-08-23 15:20:22 +02:00
}
function formReducer(state, action) {
switch (action.type) {
2019-08-27 15:28:29 +02:00
case FORM_ACTIONS.updateValue: {
const newData = update(state.data, action.updateRule(action.value));
const errors = action.validator(newData);
return {
...state,
data: newData,
errors,
};
}
case FORM_ACTIONS.resetData: {
2019-10-10 17:25:00 +02:00
if (!action.data) {
return { ...state, initialData: state.data };
}
const data = action.dataPreprocessor ? action.dataPreprocessor(action.data) : action.data;
2019-08-27 15:28:29 +02:00
return {
2019-10-10 17:25:00 +02:00
data,
initialData: data,
errors: action.data ? action.validator(data) : undefined,
2019-08-27 15:28:29 +02:00
};
}
default: {
throw new Error();
}
2019-08-23 15:20:22 +02:00
}
}
function getChangedValue(target) {
2019-08-27 15:28:29 +02:00
let { value } = target;
if (target.type === "checkbox") {
2019-08-23 15:20:22 +02:00
value = target.checked;
2019-08-27 15:28:29 +02:00
} else if (target.type === "number") {
2019-08-23 15:20:22 +02:00
const parsedValue = parseInt(value);
2019-08-27 16:09:18 +02:00
value = Number.isNaN(parsedValue) ? value : parsedValue;
2019-10-10 17:25:00 +02:00
} else if (target.type === "file") {
// Return first file (we don't need multiple yet)
[value] = target.files;
2019-08-23 15:20:22 +02:00
}
2019-08-27 15:28:29 +02:00
return value;
2019-08-23 15:20:22 +02:00
}
export function useForisModule(ws, config) {
const [APIGetState, get] = useAPIGet(config.endpoint);
const [WSData] = useWSForisModule(ws, config.wsModule, config.wsAction);
useEffect(() => {
get();
}, [WSData, get]);
return [APIGetState];
}