1
0
mirror of https://gitlab.nic.cz/turris/reforis/foris-js.git synced 2024-09-27 11:04:19 +02:00
foris-js/src/api/hooks.js

121 lines
3.4 KiB
JavaScript
Raw Normal View History

/*
* 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-11-15 14:16:37 +01:00
import {
useCallback, useEffect, useReducer, useState,
} from "react";
2019-12-26 23:34:59 +01:00
import { ForisURLs } from "../forisUrls";
2019-11-15 14:16:37 +01:00
import {
API_ACTIONS, API_METHODS, API_STATE, getErrorPayload, HEADERS, TIMEOUT,
} from "./utils";
const DATA_METHODS = ["POST", "PATCH", "PUT"];
function createAPIHook(method) {
2019-12-06 10:27:48 +01:00
return (urlRoot, contentType) => {
const [state, dispatch] = useReducer(APIReducer, {
state: API_STATE.INIT,
data: null,
});
2019-12-06 10:27:48 +01:00
const sendRequest = useCallback(async ({ data, suffix } = {}) => {
const headers = { ...HEADERS };
if (contentType) {
headers["Content-Type"] = contentType;
}
dispatch({ type: API_ACTIONS.INIT });
try {
2019-12-06 10:27:48 +01:00
// Prepare request
const request = API_METHODS[method];
const config = {
timeout: TIMEOUT,
headers,
};
2019-12-06 10:27:48 +01:00
const url = suffix ? `${urlRoot}/${suffix}` : urlRoot;
// Make request
let result;
if (DATA_METHODS.includes(method)) {
result = await request(url, data, config);
} else {
result = await request(url, config);
}
2019-12-06 10:27:48 +01:00
// Process request result
dispatch({
type: API_ACTIONS.SUCCESS,
payload: result.data,
});
} catch (error) {
dispatch({
type: API_ACTIONS.FAILURE,
2019-11-12 15:26:54 +01:00
status: error.response && error.response.status,
payload: getErrorPayload(error),
});
}
2019-12-06 10:27:48 +01:00
}, [urlRoot, contentType]);
return [state, sendRequest];
};
}
function APIReducer(state, action) {
switch (action.type) {
case API_ACTIONS.INIT:
return {
...state,
state: API_STATE.SENDING,
};
case API_ACTIONS.SUCCESS:
return {
state: API_STATE.SUCCESS,
data: action.payload,
};
case API_ACTIONS.FAILURE:
if (action.status === 403) {
window.location.assign(ForisURLs.login);
}
return {
state: API_STATE.ERROR,
data: action.payload,
};
default:
throw new Error();
}
}
const useAPIGet = createAPIHook("GET");
const useAPIPost = createAPIHook("POST");
const useAPIPatch = createAPIHook("PATCH");
const useAPIPut = createAPIHook("PUT");
const useAPIDelete = createAPIHook("DELETE");
export {
useAPIGet, useAPIPost, useAPIPatch, useAPIPut, useAPIDelete,
};
2019-11-15 12:54:12 +01:00
2019-11-15 14:16:37 +01:00
export function useAPIPolling(endpoint, delay = 1000, until) { // delay ms
2019-11-15 12:54:12 +01:00
const [state, setState] = useState({ state: API_STATE.INIT });
const [getResponse, get] = useAPIGet(endpoint);
2019-11-15 12:54:12 +01:00
useEffect(() => {
if (getResponse.state !== API_STATE.INIT) {
setState(getResponse);
2019-11-15 12:54:12 +01:00
}
}, [getResponse]);
2019-11-15 12:54:12 +01:00
useEffect(() => {
2019-11-15 14:16:37 +01:00
if (until) {
2019-11-15 12:54:12 +01:00
const interval = setInterval(get, delay);
return () => clearInterval(interval);
}
2019-11-15 14:16:37 +01:00
}, [until, delay, get]);
2019-11-15 12:54:12 +01:00
return [state];
}