diff --git a/package-lock.json b/package-lock.json index 3676931..14c91e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,8 +20,10 @@ "next": "^12.1.4", "normalize.css": "^8.0.1", "react": "^17.0.2", - "react-beautiful-dnd": "^13.1.0", "react-csv": "^2.2.2", + "react-dnd": "15.0.2", + "react-dnd-html5-backend": "15.0.2", + "react-dnd-touch-backend": "15.0.2", "react-dom": "^17.0.2", "react-is": "^17.0.2", "react-markdown": "^8.0.2", @@ -39,7 +41,6 @@ "@types/js-cookie": "^3.0.1", "@types/node": "^16.11.36", "@types/react": "^17.0.19", - "@types/react-beautiful-dnd": "^13.1.2", "@types/react-csv": "^1.1.2", "@types/react-dom": "^17.0.9", "@types/shortid": "^0.0.29", @@ -2746,6 +2747,21 @@ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==" }, + "node_modules/@react-dnd/asap": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-4.0.1.tgz", + "integrity": "sha512-kLy0PJDDwvwwTXxqTFNAAllPHD73AycE9ypWeln/IguoGBEbvFcPDbCV03G52bEcC5E+YgupBE0VzHGdC8SIXg==" + }, + "node_modules/@react-dnd/invariant": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-2.0.0.tgz", + "integrity": "sha512-xL4RCQBCBDJ+GRwKTFhGUW8GXa4yoDfJrPbLblc3U09ciS+9ZJXJ3Qrcs/x2IODOdIE5kQxvMmE2UKyqUictUw==" + }, + "node_modules/@react-dnd/shallowequal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz", + "integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==" + }, "node_modules/@rjsf/core": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-4.2.0.tgz", @@ -3104,6 +3120,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "devOptional": true, "dependencies": { "@types/react": "*", "hoist-non-react-statics": "^3.3.0" @@ -3200,7 +3217,7 @@ "version": "16.11.36", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.36.tgz", "integrity": "sha512-FR5QJe+TaoZ2GsMHkjuwoNabr+UrJNRr2HNOo+r/7vhcuntM6Ee/pRPOnRhhL2XE9OOvX9VLEq+BcXl3VjNoWA==", - "dev": true + "devOptional": true }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -3240,15 +3257,6 @@ "csstype": "^3.0.2" } }, - "node_modules/@types/react-beautiful-dnd": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/@types/react-beautiful-dnd/-/react-beautiful-dnd-13.1.2.tgz", - "integrity": "sha512-+OvPkB8CdE/bGdXKyIhc/Lm2U7UAYCCJgsqmopFmh9gbAudmslkI8eOrPDjg4JhwSE6wytz4a3/wRjKtovHVJg==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/react-csv": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@types/react-csv/-/react-csv-1.1.2.tgz", @@ -3267,17 +3275,6 @@ "@types/react": "^17" } }, - "node_modules/@types/react-redux": { - "version": "7.1.24", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz", - "integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==", - "dependencies": { - "@types/hoist-non-react-statics": "^3.3.0", - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0", - "redux": "^4.0.0" - } - }, "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", @@ -4895,14 +4892,6 @@ "urix": "^0.1.0" } }, - "node_modules/css-box-model": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", - "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", - "dependencies": { - "tiny-invariant": "^1.0.6" - } - }, "node_modules/css-color-keywords": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", @@ -5307,6 +5296,16 @@ "node": ">=8" } }, + "node_modules/dnd-core": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-15.0.2.tgz", + "integrity": "sha512-38dMXvgyucWsp7cjdg+OtLqghLPZmr3H8Pf3I5OAqnpLWeT5aY3W5NCsJruoGn0pKFoL+Rh73WlT4aGSe5+rKg==", + "dependencies": { + "@react-dnd/asap": "^4.0.0", + "@react-dnd/invariant": "^2.0.0", + "redux": "^4.1.1" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -9099,11 +9098,6 @@ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" }, - "node_modules/memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" - }, "node_modules/memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -11049,11 +11043,6 @@ "node": ">=8" } }, - "node_modules/raf-schd": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", - "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==" - }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -11088,29 +11077,57 @@ "node": ">=0.10.0" } }, - "node_modules/react-beautiful-dnd": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.1.0.tgz", - "integrity": "sha512-aGvblPZTJowOWUNiwd6tNfEpgkX5OxmpqxHKNW/4VmvZTNTbeiq7bA3bn5T+QSF2uibXB0D1DmJsb1aC/+3cUA==", - "dependencies": { - "@babel/runtime": "^7.9.2", - "css-box-model": "^1.2.0", - "memoize-one": "^5.1.1", - "raf-schd": "^4.0.2", - "react-redux": "^7.2.0", - "redux": "^4.0.4", - "use-memo-one": "^1.1.1" - }, - "peerDependencies": { - "react": "^16.8.5 || ^17.0.0", - "react-dom": "^16.8.5 || ^17.0.0" - } - }, "node_modules/react-csv": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/react-csv/-/react-csv-2.2.2.tgz", "integrity": "sha512-RG5hOcZKZFigIGE8LxIEV/OgS1vigFQT4EkaHeKgyuCbUAu9Nbd/1RYq++bJcJJ9VOqO/n9TZRADsXNDR4VEpw==" }, + "node_modules/react-dnd": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-15.0.2.tgz", + "integrity": "sha512-TC2fLltThXNo8haTfZmwOwZ8+QIscxqfMLPPQQ0lB5+hYRHO5LMNfER39Ca5b6OKWe78o+ldPRRdsjPUxJ9hJg==", + "dependencies": { + "@react-dnd/invariant": "^2.0.0", + "@react-dnd/shallowequal": "^2.0.0", + "dnd-core": "15.0.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2" + }, + "peerDependencies": { + "@types/hoist-non-react-statics": ">= 3.3.1", + "@types/node": ">= 12", + "@types/react": ">= 16", + "react": ">= 16.14" + }, + "peerDependenciesMeta": { + "@types/hoist-non-react-statics": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-dnd-html5-backend": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-15.0.2.tgz", + "integrity": "sha512-PTXbWyv9Ij9BnOjDrH5wfIeBJNH9dD9Q4YAvDCBF7zOG7GLY8hvwNj9oT/7+EnkGe5qSFiqL+T7VPwAQdGEpFA==", + "dependencies": { + "dnd-core": "15.0.2" + } + }, + "node_modules/react-dnd-touch-backend": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/react-dnd-touch-backend/-/react-dnd-touch-backend-15.0.2.tgz", + "integrity": "sha512-hF/mxkOChur26dKNUIbb2rq4MdOqjFz9Y6FprKaYVKBHIaAc9nNBwgcH2j4/PI1diy8H0pYnU0BkfEFYpMJ75g==", + "dependencies": { + "@react-dnd/invariant": "^2.0.0", + "dnd-core": "15.0.2" + } + }, "node_modules/react-dom": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", @@ -11173,30 +11190,6 @@ "react-dom": "^17.0.0" } }, - "node_modules/react-redux": { - "version": "7.2.8", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.8.tgz", - "integrity": "sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw==", - "dependencies": { - "@babel/runtime": "^7.15.4", - "@types/react-redux": "^7.1.20", - "hoist-non-react-statics": "^3.3.2", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" - }, - "peerDependencies": { - "react": "^16.8.3 || ^17 || ^18" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } - } - }, "node_modules/react-toastify": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-8.2.0.tgz", @@ -13433,11 +13426,6 @@ "node": ">= 0.12" } }, - "node_modules/tiny-invariant": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", - "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" - }, "node_modules/tmp": { "version": "0.0.28", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz", @@ -13946,14 +13934,6 @@ "deprecated": "Please see https://github.com/lydell/urix#deprecated", "dev": true }, - "node_modules/use-memo-one": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.2.tgz", - "integrity": "sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0" - } - }, "node_modules/utf8-byte-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", @@ -16429,6 +16409,21 @@ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==" }, + "@react-dnd/asap": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-4.0.1.tgz", + "integrity": "sha512-kLy0PJDDwvwwTXxqTFNAAllPHD73AycE9ypWeln/IguoGBEbvFcPDbCV03G52bEcC5E+YgupBE0VzHGdC8SIXg==" + }, + "@react-dnd/invariant": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-2.0.0.tgz", + "integrity": "sha512-xL4RCQBCBDJ+GRwKTFhGUW8GXa4yoDfJrPbLblc3U09ciS+9ZJXJ3Qrcs/x2IODOdIE5kQxvMmE2UKyqUictUw==" + }, + "@react-dnd/shallowequal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz", + "integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==" + }, "@rjsf/core": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@rjsf/core/-/core-4.2.0.tgz", @@ -16723,6 +16718,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "devOptional": true, "requires": { "@types/react": "*", "hoist-non-react-statics": "^3.3.0" @@ -16819,7 +16815,7 @@ "version": "16.11.36", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.36.tgz", "integrity": "sha512-FR5QJe+TaoZ2GsMHkjuwoNabr+UrJNRr2HNOo+r/7vhcuntM6Ee/pRPOnRhhL2XE9OOvX9VLEq+BcXl3VjNoWA==", - "dev": true + "devOptional": true }, "@types/normalize-package-data": { "version": "2.4.1", @@ -16859,15 +16855,6 @@ "csstype": "^3.0.2" } }, - "@types/react-beautiful-dnd": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/@types/react-beautiful-dnd/-/react-beautiful-dnd-13.1.2.tgz", - "integrity": "sha512-+OvPkB8CdE/bGdXKyIhc/Lm2U7UAYCCJgsqmopFmh9gbAudmslkI8eOrPDjg4JhwSE6wytz4a3/wRjKtovHVJg==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, "@types/react-csv": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@types/react-csv/-/react-csv-1.1.2.tgz", @@ -16886,17 +16873,6 @@ "@types/react": "^17" } }, - "@types/react-redux": { - "version": "7.1.24", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz", - "integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==", - "requires": { - "@types/hoist-non-react-statics": "^3.3.0", - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0", - "redux": "^4.0.0" - } - }, "@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", @@ -18110,14 +18086,6 @@ } } }, - "css-box-model": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", - "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", - "requires": { - "tiny-invariant": "^1.0.6" - } - }, "css-color-keywords": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", @@ -18412,6 +18380,16 @@ "path-type": "^4.0.0" } }, + "dnd-core": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-15.0.2.tgz", + "integrity": "sha512-38dMXvgyucWsp7cjdg+OtLqghLPZmr3H8Pf3I5OAqnpLWeT5aY3W5NCsJruoGn0pKFoL+Rh73WlT4aGSe5+rKg==", + "requires": { + "@react-dnd/asap": "^4.0.0", + "@react-dnd/invariant": "^2.0.0", + "redux": "^4.1.1" + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -21326,11 +21304,6 @@ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" }, - "memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" - }, "memorystream": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", @@ -22648,11 +22621,6 @@ "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, - "raf-schd": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", - "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==" - }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -22680,25 +22648,40 @@ "object-assign": "^4.1.1" } }, - "react-beautiful-dnd": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.1.0.tgz", - "integrity": "sha512-aGvblPZTJowOWUNiwd6tNfEpgkX5OxmpqxHKNW/4VmvZTNTbeiq7bA3bn5T+QSF2uibXB0D1DmJsb1aC/+3cUA==", - "requires": { - "@babel/runtime": "^7.9.2", - "css-box-model": "^1.2.0", - "memoize-one": "^5.1.1", - "raf-schd": "^4.0.2", - "react-redux": "^7.2.0", - "redux": "^4.0.4", - "use-memo-one": "^1.1.1" - } - }, "react-csv": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/react-csv/-/react-csv-2.2.2.tgz", "integrity": "sha512-RG5hOcZKZFigIGE8LxIEV/OgS1vigFQT4EkaHeKgyuCbUAu9Nbd/1RYq++bJcJJ9VOqO/n9TZRADsXNDR4VEpw==" }, + "react-dnd": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-15.0.2.tgz", + "integrity": "sha512-TC2fLltThXNo8haTfZmwOwZ8+QIscxqfMLPPQQ0lB5+hYRHO5LMNfER39Ca5b6OKWe78o+ldPRRdsjPUxJ9hJg==", + "requires": { + "@react-dnd/invariant": "^2.0.0", + "@react-dnd/shallowequal": "^2.0.0", + "dnd-core": "15.0.2", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2" + } + }, + "react-dnd-html5-backend": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-15.0.2.tgz", + "integrity": "sha512-PTXbWyv9Ij9BnOjDrH5wfIeBJNH9dD9Q4YAvDCBF7zOG7GLY8hvwNj9oT/7+EnkGe5qSFiqL+T7VPwAQdGEpFA==", + "requires": { + "dnd-core": "15.0.2" + } + }, + "react-dnd-touch-backend": { + "version": "15.0.2", + "resolved": "https://registry.npmjs.org/react-dnd-touch-backend/-/react-dnd-touch-backend-15.0.2.tgz", + "integrity": "sha512-hF/mxkOChur26dKNUIbb2rq4MdOqjFz9Y6FprKaYVKBHIaAc9nNBwgcH2j4/PI1diy8H0pYnU0BkfEFYpMJ75g==", + "requires": { + "@react-dnd/invariant": "^2.0.0", + "dnd-core": "15.0.2" + } + }, "react-dom": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", @@ -22749,19 +22732,6 @@ "integrity": "sha512-CH/VK6d+tpVjJ8rTXfh1dDt6GWedTgCU0668p8toqhAc3vy0Lu872O2RKYDSpkUrlbHI08fjUPTl++nExp6gag==", "requires": {} }, - "react-redux": { - "version": "7.2.8", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.8.tgz", - "integrity": "sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw==", - "requires": { - "@babel/runtime": "^7.15.4", - "@types/react-redux": "^7.1.20", - "hoist-non-react-statics": "^3.3.2", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" - } - }, "react-toastify": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-8.2.0.tgz", @@ -24518,11 +24488,6 @@ "integrity": "sha512-FLHDDsIDducw7MBcRWlFtW2Tm50DoKOSFf0Nzx17qwXj8REXCte0eUkHrJl9QU3Bl9arG3XNYX0PcHpZ9xyuLw==", "dev": true }, - "tiny-invariant": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz", - "integrity": "sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg==" - }, "tmp": { "version": "0.0.28", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz", @@ -24884,12 +24849,6 @@ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", "dev": true }, - "use-memo-one": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.2.tgz", - "integrity": "sha512-u2qFKtxLsia/r8qG0ZKkbytbztzRb317XCkT7yP8wxL0tZ/CzK2G+WWie5vWvpyeP7+YoPIwbJoIHJ4Ba4k0oQ==", - "requires": {} - }, "utf8-byte-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", diff --git a/package.json b/package.json index 97124f4..2f95c40 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,6 @@ "@types/js-cookie": "^3.0.1", "@types/node": "^16.11.36", "@types/react": "^17.0.19", - "@types/react-beautiful-dnd": "^13.1.2", "@types/react-csv": "^1.1.2", "@types/react-dom": "^17.0.9", "@types/shortid": "^0.0.29", @@ -76,8 +75,10 @@ "next": "^12.1.4", "normalize.css": "^8.0.1", "react": "^17.0.2", - "react-beautiful-dnd": "^13.1.0", "react-csv": "^2.2.2", + "react-dnd": "15.0.2", + "react-dnd-html5-backend": "15.0.2", + "react-dnd-touch-backend": "15.0.2", "react-dom": "^17.0.2", "react-is": "^17.0.2", "react-markdown": "^8.0.2", diff --git a/src/components/Draggable.tsx b/src/components/Draggable.tsx new file mode 100644 index 0000000..a2a7c46 --- /dev/null +++ b/src/components/Draggable.tsx @@ -0,0 +1,61 @@ +import React, { useRef } from "react"; +import { useDrag, useDrop } from "react-dnd"; + +const type = "Draggable"; + +const Draggable = ({ + id, index, handleDrag, children, +}) => { + const ref = useRef(null); // Initialize the reference + + // useDrop hook is responsible for handling whether any item gets hovered or dropped on the element + const [, drop] = useDrop({ + // accept receives a definition of what must be the type of the dragged item to be droppable + accept: type, + // This method is called when we hover over an element while dragging + drop(item: { index: number }) { // item is the dragged element + if (!ref.current) { + return; + } + const dragIndex = item.index; + // current element where the dragged element is hovered on + const hoverIndex = index; + // If the dragged element is hovered in the same place, then do nothing + if (dragIndex === hoverIndex) { + return; + } + // If it is dragged around other elements, then move the image and set the state with position changes + handleDrag(dragIndex, hoverIndex); + /* + Update the index for dragged item directly to avoid flickering + when the image was half dragged into the next + */ + // eslint-disable-next-line no-param-reassign + item.index = hoverIndex; + }, + }); + + // useDrag will be responsible for making an element draggable. It also expose, isDragging method to add any styles while dragging + const [{ isDragging }, drag] = useDrag(() => ({ + // what type of item this to determine if a drop target accepts it + type, + // data of the item to be available to the drop methods + item: { id, index }, + // method to collect additional data for drop handling like whether is currently being dragged + collect: (monitor) => ({ + isDragging: monitor.isDragging(), + }), + })); + + /* + Initialize drag and drop into the element using its reference. + Here we initialize both drag and drop on the same element (i.e., Image component) + */ + drag(drop(ref)); + + return ( +
{children}
+ ); +}; + +export default Draggable; diff --git a/src/components/Widgets/SignupQuestionsWidget/QuestionList.tsx b/src/components/Widgets/SignupQuestionsWidget/QuestionList.tsx index 706f3b2..0fd0073 100644 --- a/src/components/Widgets/SignupQuestionsWidget/QuestionList.tsx +++ b/src/components/Widgets/SignupQuestionsWidget/QuestionList.tsx @@ -1,6 +1,6 @@ -import React, { ReactNode } from "react"; +import React from "react"; import styled from "styled-components"; -import { Draggable } from "react-beautiful-dnd"; +import Draggable from "@components/Draggable"; import colors from "@theme/colors"; import { SignupFormQuestion } from "@models/Signup"; import { Lang } from "../../../i18n"; @@ -18,14 +18,24 @@ const WidgetRow = styled.div` interface QuestionListProps { questions: SignupFormQuestion[]; - innerRef: React.Ref; - placeholder: ReactNode; onChange: (value: SignupFormQuestion[]) => void; } -class QuestionList extends React.Component { - handleNameInputChange = (questions: SignupFormQuestion[], index: number, lang: Lang): React.ChangeEventHandler => (event) => { - const { onChange } = this.props; +const QuestionList: React.FC = ({ questions, onChange }): JSX.Element => { + const handleDrag = (srcIndex, dstIndex) => { + const srcCopy = { ...questions[srcIndex] }; + questions.splice(srcIndex, 1); + questions.splice(dstIndex, 0, srcCopy); + onChange(questions); + }; + + const handleElementRemove = (index: number) => (): void => { + const newQuestions = [...questions]; + newQuestions.splice(index, 1); + onChange(newQuestions); + }; + + const handleNameInputChange = (index: number, lang: Lang): React.ChangeEventHandler => (event) => { const val = event.target.value; if (lang === "fi") { // eslint-disable-next-line no-param-reassign @@ -38,54 +48,39 @@ class QuestionList extends React.Component { onChange(questions); }; - handleElementRemove = (questions: SignupFormQuestion[], index: number) => (): void => { - const { onChange } = this.props; - const newQuestions = [...questions]; - newQuestions.splice(index, 1); - onChange(newQuestions); - }; - - renderQuestions(): JSX.Element[] { - const { questions, onChange } = this.props; - return questions.map((q, index) => { - const dataProps = { - value: q.options, type: q.type, questions, index, - }; - const optionsWidget = ; - const typeSelectWidget = ; - return ( - - {(provided) => ( - + return ( +
+ {questions.map((q, index) => { + const inputProps = { + value: q.options, + type: q.type, + questions, + index, + }; + const optionsWidget = ; + const typeSelectWidget = ; + return ( + + - - + + {typeSelectWidget} {optionsWidget} - )} - - ); - }); - } - - render(): JSX.Element { - const { placeholder, innerRef } = this.props; - - return ( -
- {this.renderQuestions()} - {placeholder} -
- ); - } -} + + ); + })} +
+ ); +}; export default QuestionList; diff --git a/src/components/Widgets/SignupQuestionsWidget/SignupQuestionsWidget.tsx b/src/components/Widgets/SignupQuestionsWidget/SignupQuestionsWidget.tsx index fc548cc..995ee3e 100644 --- a/src/components/Widgets/SignupQuestionsWidget/SignupQuestionsWidget.tsx +++ b/src/components/Widgets/SignupQuestionsWidget/SignupQuestionsWidget.tsx @@ -1,7 +1,6 @@ import React from "react"; import styled from "styled-components"; import shortid from "shortid"; -import { DragDropContext, Droppable } from "react-beautiful-dnd"; import colors from "@theme/colors"; import AddIcon from "@components/AddIcon"; import { SignupFormQuestion } from "@models/Signup"; @@ -34,12 +33,9 @@ const AddQuestionButton = styled.button` interface SignupQuestionsWidgetProps { value: string; onChange: (value: string) => void; - onFocus: () => void; - required: boolean; - disabled: boolean; } -const SignupQuestionsWidget: React.FC = ({ value, onFocus, onChange }) => { +const SignupQuestionsWidget: React.FC = ({ value, onChange }) => { const onValueChange = (questions: SignupFormQuestion[]) => { const newValue = JSON.stringify(questions); onChange(newValue); @@ -62,35 +58,14 @@ const SignupQuestionsWidget: React.FC = ({ value, on onValueChange(newQuestions); }; - const handleDragEnd = (questions: SignupFormQuestion[]) => (result) => { - const srcIndex = result.source.index; - const dstIndex = result.destination.index; - const srcCopy = { ...questions[srcIndex] }; - questions.splice(srcIndex, 1); - questions.splice(dstIndex, 0, srcCopy); - - onValueChange(questions); - }; const questions: SignupFormQuestion[] = JSON.parse(value); return ( - - - {(provided) => ( - - )} - - + New Question diff --git a/src/hooks/useIsTouchDevice.ts b/src/hooks/useIsTouchDevice.ts new file mode 100644 index 0000000..5879303 --- /dev/null +++ b/src/hooks/useIsTouchDevice.ts @@ -0,0 +1,14 @@ +import { useEffect, useState } from "react"; + +const useIsTouchDevice = () => { + const [isTouchDevice, setTouchDevice] = useState(false); + useEffect(() => { + // simple way to check whether the device support touch (it doesn't check all fallback, it supports only modern browsers) + if (window !== undefined && "ontouchstart" in window) { + setTouchDevice(true); + } + }, []); + return isTouchDevice; +}; + +export default useIsTouchDevice; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 2638a73..2ccafd8 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,4 +1,7 @@ import React from "react"; +import { DndProvider } from "react-dnd"; +import { HTML5Backend } from "react-dnd-html5-backend"; +import { TouchBackend } from "react-dnd-touch-backend"; import Head from "next/head"; import { AppProps } from "next/app"; import styled, { createGlobalStyle } from "styled-components"; @@ -10,6 +13,7 @@ import "react-mde/lib/styles/css/react-mde-all.css"; import "react-toastify/dist/ReactToastify.css"; import "normalize.css"; +import useIsTouchDevice from "@hooks/useIsTouchDevice"; import LocaleStore from "../i18n"; const fontFamily = "'Montserrat', sans-serif"; @@ -128,27 +132,35 @@ const AppContainer = styled.div` background-color: ${colors.white}; `; -const Web20App = ({ Component, pageProps }: AppProps): JSX.Element => ( - <> - - - - - Aalto-yliopiston Sähköinsinöörikilta ry - - - - - - - - - - - -); +const Web20App = ({ Component, pageProps }: AppProps): JSX.Element => { + const isTouchDevice = useIsTouchDevice(); + // Assigning backend based on touch support on the device + const backendForDND = isTouchDevice ? TouchBackend : HTML5Backend; + + return ( + <> + + + + + Aalto-yliopiston Sähköinsinöörikilta ry + + + + + + + + + + + + + + ); +}; export default Web20App; diff --git a/tests/testcafe/admin/create-signup.test.ts b/tests/testcafe/admin/create-signup.test.ts index afe5767..c933e70 100644 --- a/tests/testcafe/admin/create-signup.test.ts +++ b/tests/testcafe/admin/create-signup.test.ts @@ -9,7 +9,6 @@ fixture`Admin signup form`.page(`${getSiteRoot()}/admin/signups`) .requestHooks(LOGGER) .after(async (ctx) => { const token = await generateAccessToken(); - await deleteForm(ctx.formId, token); }); @@ -35,7 +34,8 @@ test("Logged in user can create signup", async (t) => { .click(visible); const newQuestionButton = Selector("[data-e2e=\"admin-signup-new-question\"]"); - const lastQuestion = () => Selector("[data-e2e=\"admin-signup-question\"]").child("div").child("div").nth(-1); + const lastQuestion = () => Selector("[data-e2e=\"admin-signup-question\"]").child("div").child("div").child("div") + .nth(-1); await t.click(newQuestionButton); let question = lastQuestion();