diff --git a/Makefile b/Makefile index 5decf79..a2fc9f0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,18 @@ -.PHONY: all create-messages update-messages clean +.PHONY: all install-js watch-js build-js publish-beta lint-js test-js create-messages update-messages clean all: + @echo "make install-js" + @echo " Install dependencies" + @echo "make watch-js" + @echo " Compile JS in watch mode." + @echo "make build-js" + @echo " Compile JS." + @echo "make publish-beta" + @echo " Publish package with 'beta' tag" + @echo "make lint-js" + @echo " Run linter" + @echo "make test-js" + @echo " Run tests" @echo "make create-messages" @echo " Create locale messages (.pot)." @echo "make update-messages" @@ -8,6 +20,23 @@ all: @echo "make clean" @echo " Remove python artifacts and virtualenv." +install-js: package.json + npm install --save-dev + +watch-js: + npm run watch +build-js: + npm run build + +publish-beta: + npm publish --tag beta + +lint-js: + npm run lint + +test-js: + npm test + create-messages: pybabel extract -F babel.cfg -o ./translations/forisjs.pot . update-messages: diff --git a/package-lock.json b/package-lock.json index 654d2c1..f0719ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "foris", - "version": "0.0.5", + "version": "0.1.0-beta", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -123,6 +123,20 @@ "@babel/types": "^7.4.4" } }, + "@babel/helper-create-class-features-plugin": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz", + "integrity": "sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-member-expression-to-functions": "^7.5.5", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.5.5", + "@babel/helper-split-export-declaration": "^7.4.4" + } + }, "@babel/helper-define-map": { "version": "7.5.5", "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz", @@ -324,6 +338,16 @@ "@babel/plugin-syntax-async-generators": "^7.2.0" } }, + "@babel/plugin-proposal-class-properties": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz", + "integrity": "sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.5.5", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, "@babel/plugin-proposal-dynamic-import": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz", @@ -3336,47 +3360,48 @@ } }, "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", + "integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", + "ajv": "^6.10.0", "chalk": "^2.1.0", "cross-spawn": "^6.0.5", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.2", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.1", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", + "glob-parent": "^5.0.0", "globals": "^11.7.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", - "lodash": "^4.17.11", + "lodash": "^4.17.14", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", "progress": "^2.0.0", "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", "table": "^5.2.3", - "text-table": "^0.2.0" + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "dependencies": { "debug": { @@ -3389,20 +3414,44 @@ } }, "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } } } }, @@ -3745,14 +3794,22 @@ "dev": true }, "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", + "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", "dev": true, "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "acorn": "^7.0.0", + "acorn-jsx": "^5.0.2", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "acorn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", + "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "dev": true + } } }, "esprima": { @@ -9871,9 +9928,9 @@ "dev": true }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", "dev": true }, "supports-color": { @@ -10598,6 +10655,12 @@ "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", "dev": true }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", diff --git a/package.json b/package.json index dd0d4ae..6ab94c2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "foris", - "version": "0.0.7", + "version": "0.1.0-beta", "description": "Set of components and utils for Foris and its plugins.", "author": "CZ.NIC, z.s.p.o.", "repository": { @@ -15,7 +15,7 @@ "main": "./dist/index.js", "dependencies": { "axios": "^0.19.0", - "immutability-helper": "^3.0.1", + "immutability-helper": "^3.0.0", "prop-types": "^15.7.2", "react-datetime": "^2.16.3", "react-router": "^5.0.1", @@ -28,25 +28,26 @@ "react-dom": "^16.9.0" }, "devDependencies": { - "@babel/cli": "^7.5.5", - "@babel/core": "^7.5.5", - "@babel/plugin-syntax-export-default-from": "^7.2.0", + "@babel/cli": "^7.4.4", + "@babel/core": "^7.4.5", + "@babel/plugin-proposal-class-properties": "^7.4.4", "@babel/plugin-transform-runtime": "^7.4.4", + "@babel/plugin-syntax-export-default-from": "^7.2.0", "@babel/preset-env": "^7.4.5", "@babel/preset-react": "^7.0.0", - "@testing-library/react": "^8.0.1", + "@testing-library/react": "^8.0.9", "babel-eslint": "^9.0.0", "babel-jest": "^24.8.0", "babel-loader": "^8.0.6", "babel-plugin-module-resolver": "^3.2.0", "babel-plugin-react-transform": "^3.0.0", "babel-polyfill": "^6.26.0", - "eslint": "^5.16.0", + "eslint": "^6.1.0", "eslint-config-airbnb": "^18.0.1", - "eslint-plugin-import": "^2.17.3", - "eslint-plugin-jsx-a11y": "^6.2.1", - "eslint-plugin-react": "^7.13.0", - "eslint-plugin-react-hooks": "^1.6.0", + "eslint-plugin-import": "^2.18.2", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-react": "^7.14.3", + "eslint-plugin-react-hooks": "^1.7.0", "jest": "^24.8.0", "jest-mock-axios": "^3.0.0", "moment": "^2.24.0", @@ -57,12 +58,14 @@ "snapshot-diff": "^0.5.1" }, "scripts": { + "watch": "babel src --verbose --watch --out-dir dist --ignore '**/__tests__' --source-maps inline", "build": "rm -rf dist; babel src --out-dir dist --ignore '**/__tests__' --source-maps inline", "prepare": "rm -rf ./dist && npm run build", "lint": "eslint src", "test": "jest", "test:watch": "jest --watch", - "test:coverage": "jest --coverage --colors" + "test:coverage": "jest --coverage --colors", + "test:update-snapshots": "jest -u" }, "files": [ "dist/**", diff --git a/src/api/hooks.js b/src/api/hooks.js index cd62851..4f47bdd 100644 --- a/src/api/hooks.js +++ b/src/api/hooks.js @@ -11,7 +11,7 @@ import { useCallback, useReducer } from "react"; import { ForisURLs } from "forisUrls"; -const POST_HEADERS = { +const HEADERS = { Accept: "application/json", "Content-Type": "application/json", "X-CSRFToken": getCookie("_csrf_token"), @@ -138,7 +138,7 @@ export function useAPIPost(url) { try { const result = await axios.post(url, data, { timeout: TIMEOUT, - headers: POST_HEADERS, + headers: HEADERS, }); dispatch({ type: API_ACTIONS.SUCCESS, payload: result.data }); } catch (error) { @@ -151,3 +151,63 @@ export function useAPIPost(url) { }; 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/index.js b/src/index.js index 8b0f17b..df5480f 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,5 @@ // API -export { useAPIGet, useAPIPost } from "./api/hooks"; +export { useAPIGet, useAPIPost, useAPIDelete } from "./api/hooks"; // Bootstrap export { Alert } from "bootstrap/Alert";