From d658f0b112ec5f12ebcde7914b5de65cd53be3fc Mon Sep 17 00:00:00 2001 From: Maciej Lenartowicz Date: Wed, 25 Sep 2019 11:56:08 +0000 Subject: [PATCH] Resolve "Handle PATCH request" --- Makefile | 4 +- package-lock.json | 2 +- package.json | 2 +- src/api/delete.js | 41 ++++++ src/api/get.js | 65 ++++++++++ src/api/hooks.js | 213 ------------------------------- src/api/patch.js | 40 ++++++ src/api/post.js | 40 ++++++ src/api/utils.js | 69 ++++++++++ src/form/components/ForisForm.js | 2 +- src/form/hooks.js | 2 +- src/index.js | 5 +- 12 files changed, 265 insertions(+), 220 deletions(-) create mode 100644 src/api/delete.js create mode 100644 src/api/get.js delete mode 100644 src/api/hooks.js create mode 100644 src/api/patch.js create mode 100644 src/api/post.js create mode 100644 src/api/utils.js diff --git a/Makefile b/Makefile index a2fc9f0..aab8e26 100644 --- a/Makefile +++ b/Makefile @@ -31,10 +31,10 @@ build-js: publish-beta: npm publish --tag beta -lint-js: +lint: npm run lint -test-js: +test: npm test create-messages: diff --git a/package-lock.json b/package-lock.json index f482faa..d7e36d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "foris", - "version": "0.1.0-beta.2", + "version": "0.1.0-beta.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 63dae32..acad3e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "foris", - "version": "0.1.0-beta.2", + "version": "0.1.0-beta.3", "description": "Set of components and utils for Foris and its plugins.", "author": "CZ.NIC, z.s.p.o.", "repository": { diff --git a/src/api/delete.js b/src/api/delete.js new file mode 100644 index 0000000..c04114d --- /dev/null +++ b/src/api/delete.js @@ -0,0 +1,41 @@ +/* + * 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. + */ + +import { useReducer, useCallback } from "react"; +import axios from "axios"; + +import { + API_ACTIONS, TIMEOUT, HEADERS, APIReducer, +} from "./utils"; + +export function useAPIDelete(url) { + const [state, dispatch] = useReducer(APIReducer, { + isSending: false, + isError: false, + isSuccess: false, + data: null, + }); + + const requestDelete = useCallback(async () => { + dispatch({ type: API_ACTIONS.INIT }); + try { + await axios.delete(url, { + timeout: TIMEOUT, + headers: HEADERS, + }); + dispatch({ type: API_ACTIONS.SUCCESS }); + } catch (error) { + dispatch({ + type: API_ACTIONS.FAILURE, + payload: error.response.data, + status: error.response.status, + }); + } + }, [url]); + + return [state, requestDelete]; +} diff --git a/src/api/get.js b/src/api/get.js new file mode 100644 index 0000000..14c9d69 --- /dev/null +++ b/src/api/get.js @@ -0,0 +1,65 @@ +/* + * 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. + */ + +import { useReducer, useCallback } from "react"; +import axios from "axios"; + +import { ForisURLs } from "forisUrls"; +import { API_ACTIONS, TIMEOUT } from "./utils"; + +const APIGetReducer = (state, action) => { + switch (action.type) { + case API_ACTIONS.INIT: + return { + ...state, + isLoading: true, + isError: false, + }; + case API_ACTIONS.SUCCESS: + return { + ...state, + isLoading: false, + isError: false, + data: action.payload, + }; + case API_ACTIONS.FAILURE: + if (action.status === 403) window.location.assign(ForisURLs.login); + return { + ...state, + isLoading: false, + isError: true, + data: action.payload, + }; + default: + throw new Error(); + } +}; + +export function useAPIGet(url) { + const [state, dispatch] = useReducer(APIGetReducer, { + isLoading: false, + isError: false, + data: null, + }); + const get = useCallback(async () => { + dispatch({ type: API_ACTIONS.INIT }); + try { + const result = await axios.get(url, { + timeout: TIMEOUT, + }); + dispatch({ type: API_ACTIONS.SUCCESS, payload: result.data }); + } catch (error) { + dispatch({ + type: API_ACTIONS.FAILURE, + payload: error.response.data, + status: error.response.status, + }); + } + }, [url]); + + return [state, get]; +} diff --git a/src/api/hooks.js b/src/api/hooks.js deleted file mode 100644 index 4f47bdd..0000000 --- a/src/api/hooks.js +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 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. - */ - -import axios from "axios"; -import { useCallback, useReducer } from "react"; - -import { ForisURLs } from "forisUrls"; - - -const HEADERS = { - Accept: "application/json", - "Content-Type": "application/json", - "X-CSRFToken": getCookie("_csrf_token"), -}; - -function getCookie(name) { - let cookieValue = null; - if (document.cookie && document.cookie !== "") { - const cookies = document.cookie.split(";"); - for (let i = 0; i < cookies.length; i++) { - const cookie = cookies[i].trim(); - // Does this cookie string begin with the name we want? - if (cookie.substring(0, name.length + 1) === (`${name}=`)) { - cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); - break; - } - } - } - return cookieValue; -} - -export const TIMEOUT = 5000; - -const API_ACTIONS = { - INIT: 1, - SUCCESS: 2, - FAILURE: 3, -}; - -const APIGetReducer = (state, action) => { - switch (action.type) { - case API_ACTIONS.INIT: - return { - ...state, - isLoading: true, - isError: false, - }; - case API_ACTIONS.SUCCESS: - return { - ...state, - isLoading: false, - isError: false, - data: action.payload, - }; - case API_ACTIONS.FAILURE: - if (action.status === 403) window.location.assign(ForisURLs.login); - return { - ...state, - isLoading: false, - isError: true, - data: action.payload, - }; - default: - throw new Error(); - } -}; - -export function useAPIGet(url) { - const [state, dispatch] = useReducer(APIGetReducer, { - isLoading: false, - isError: false, - data: null, - }); - const get = useCallback(async () => { - dispatch({ type: API_ACTIONS.INIT }); - try { - const result = await axios.get(url, { - timeout: TIMEOUT, - }); - dispatch({ type: API_ACTIONS.SUCCESS, payload: result.data }); - } catch (error) { - dispatch({ - type: API_ACTIONS.FAILURE, - payload: error.response.data, - status: error.response.status, - }); - } - }, [url]); - - return [state, get]; -} - -const APIPostReducer = (state, action) => { - switch (action.type) { - case API_ACTIONS.INIT: - return { - ...state, - isSending: true, - isError: false, - isSuccess: false, - }; - case API_ACTIONS.SUCCESS: - return { - ...state, - isSending: false, - isError: false, - isSuccess: true, - data: action.payload, - }; - case API_ACTIONS.FAILURE: - if (action.status === 403) window.location.assign(ForisURLs.login); - return { - ...state, - isSending: false, - isError: true, - isSuccess: false, - data: action.payload, - }; - default: - throw new Error(); - } -}; - -export function useAPIPost(url) { - const [state, dispatch] = useReducer(APIPostReducer, { - isSending: false, - isError: false, - isSuccess: false, - data: null, - }); - - const post = async (data) => { - dispatch({ type: API_ACTIONS.INIT }); - try { - const result = await axios.post(url, data, { - timeout: TIMEOUT, - headers: HEADERS, - }); - dispatch({ type: API_ACTIONS.SUCCESS, payload: result.data }); - } catch (error) { - dispatch({ - type: API_ACTIONS.FAILURE, - payload: error.response.data, - status: error.response.status, - }); - } - }; - return [state, post]; -} - -const APIDeleteReducer = (state, action) => { - switch (action.type) { - case API_ACTIONS.INIT: - return { - ...state, - isSending: true, - isError: false, - isSuccess: false, - }; - case API_ACTIONS.SUCCESS: - return { - ...state, - isSending: false, - isError: false, - isSuccess: true, - }; - case API_ACTIONS.FAILURE: - if (action.status === 403) { - window.location.assign(ForisURLs.login); - } - return { - ...state, - isSending: false, - isError: true, - isSuccess: false, - data: action.payload, - }; - default: - throw new Error(); - } -}; - -export function useAPIDelete(url) { - const [state, dispatch] = useReducer(APIDeleteReducer, { - isSending: false, - isError: false, - isSuccess: false, - data: null, - }); - - const requestDelete = useCallback(async () => { - dispatch({ type: API_ACTIONS.INIT }); - try { - await axios.delete(url, { - timeout: TIMEOUT, - headers: HEADERS, - }); - dispatch({ type: API_ACTIONS.SUCCESS }); - } catch (error) { - dispatch({ - type: API_ACTIONS.FAILURE, - payload: error.response.data, - status: error.response.status, - }); - } - }, [url]); - - return [state, requestDelete]; -} diff --git a/src/api/patch.js b/src/api/patch.js new file mode 100644 index 0000000..19c7fa4 --- /dev/null +++ b/src/api/patch.js @@ -0,0 +1,40 @@ +/* + * 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. + */ + +import { useReducer } from "react"; +import axios from "axios"; + +import { + API_ACTIONS, TIMEOUT, HEADERS, APIReducer, +} from "./utils"; + +export function useAPIPatch(url) { + const [state, dispatch] = useReducer(APIReducer, { + isSending: false, + isError: false, + isSuccess: false, + data: null, + }); + + const patch = async (data) => { + dispatch({ type: API_ACTIONS.INIT }); + try { + const result = await axios.patch(url, data, { + timeout: TIMEOUT, + headers: HEADERS, + }); + dispatch({ type: API_ACTIONS.SUCCESS, payload: result.data }); + } catch (error) { + dispatch({ + type: API_ACTIONS.FAILURE, + payload: error.response.data, + status: error.response.status, + }); + } + }; + return [state, patch]; +} diff --git a/src/api/post.js b/src/api/post.js new file mode 100644 index 0000000..b866f40 --- /dev/null +++ b/src/api/post.js @@ -0,0 +1,40 @@ +/* + * 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. + */ + +import { useReducer } from "react"; +import axios from "axios"; + +import { + API_ACTIONS, TIMEOUT, HEADERS, APIReducer, +} from "./utils"; + +export function useAPIPost(url) { + const [state, dispatch] = useReducer(APIReducer, { + isSending: false, + isError: false, + isSuccess: false, + data: null, + }); + + const post = async (data) => { + dispatch({ type: API_ACTIONS.INIT }); + try { + const result = await axios.post(url, data, { + timeout: TIMEOUT, + headers: HEADERS, + }); + dispatch({ type: API_ACTIONS.SUCCESS, payload: result.data }); + } catch (error) { + dispatch({ + type: API_ACTIONS.FAILURE, + payload: error.response.data, + status: error.response.status, + }); + } + }; + return [state, post]; +} diff --git a/src/api/utils.js b/src/api/utils.js new file mode 100644 index 0000000..20bc045 --- /dev/null +++ b/src/api/utils.js @@ -0,0 +1,69 @@ +/* + * 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. + */ + +import { ForisURLs } from "forisUrls"; + +function getCookie(name) { + let cookieValue = null; + if (document.cookie && document.cookie !== "") { + const cookies = document.cookie.split(";"); + for (let i = 0; i < cookies.length; i++) { + const cookie = cookies[i].trim(); + // Does this cookie string begin with the name we want? + if (cookie.substring(0, name.length + 1) === (`${name}=`)) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; +} + +export const HEADERS = { + Accept: "application/json", + "Content-Type": "application/json", + "X-CSRFToken": getCookie("_csrf_token"), +}; + +export const TIMEOUT = 5000; + +export const API_ACTIONS = { + INIT: 1, + SUCCESS: 2, + FAILURE: 3, +}; + +export function APIReducer(state, action) { + switch (action.type) { + case API_ACTIONS.INIT: + return { + ...state, + isSending: true, + isError: false, + isSuccess: false, + }; + case API_ACTIONS.SUCCESS: + return { + ...state, + isSending: false, + isError: false, + isSuccess: true, + data: action.payload, + }; + case API_ACTIONS.FAILURE: + if (action.status === 403) window.location.assign(ForisURLs.login); + return { + ...state, + isSending: false, + isError: true, + isSuccess: false, + data: action.payload, + }; + default: + throw new Error(); + } +} diff --git a/src/form/components/ForisForm.js b/src/form/components/ForisForm.js index c03badc..12e1854 100644 --- a/src/form/components/ForisForm.js +++ b/src/form/components/ForisForm.js @@ -9,7 +9,7 @@ import React, { useEffect, useState } from "react"; import PropTypes from "prop-types"; import { Spinner } from "bootstrap/Spinner"; -import { useAPIPost } from "api/hooks"; +import { useAPIPost } from "api/post"; import { Prompt } from "react-router"; import { useForisModule, useForm } from "../hooks"; diff --git a/src/form/hooks.js b/src/form/hooks.js index 2327c4f..8bbbd66 100644 --- a/src/form/hooks.js +++ b/src/form/hooks.js @@ -8,7 +8,7 @@ import { useCallback, useEffect, useReducer } from "react"; import update from "immutability-helper"; -import { useAPIGet } from "api/hooks"; +import { useAPIGet } from "api/get"; import { useWSForisModule } from "webSockets/hooks"; diff --git a/src/index.js b/src/index.js index d4bec52..647e85e 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,8 @@ // API -export { useAPIGet, useAPIPost, useAPIDelete } from "./api/hooks"; +export { useAPIGet } from "api/get"; +export { useAPIPost } from "api/post"; +export { useAPIDelete } from "api/delete"; +export { useAPIPatch } from "api/patch"; // Bootstrap export { Alert } from "bootstrap/Alert";