diff --git a/CHANGELOG.md b/CHANGELOG.md index d1abd9c9..375c5c1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * *Nothing* ### Changed +* [#616](https://github.com/shlinkio/shlink-web-client/pull/616) Updated to React 18. * [#594](https://github.com/shlinkio/shlink-web-client/pull/594) Updated to a new coding standard. * [#603](https://github.com/shlinkio/shlink-web-client/pull/603) Migrated to new and maintained dependencies to parse CSV<->JSON. diff --git a/jest.config.js b/jest.config.js index fa9ddbe4..9a46a4c3 100644 --- a/jest.config.js +++ b/jest.config.js @@ -25,7 +25,7 @@ module.exports = { }, transformIgnorePatterns: [ '/.stryker-tmp', - '[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$', + '/node_modules\\/(?!react-leaflet)\.(js|jsx|ts|tsx)$', '^.+\\.module\\.scss$', ], moduleNameMapper: { diff --git a/package-lock.json b/package-lock.json index 6f628ecd..7858c964 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,20 +26,20 @@ "leaflet": "^1.7.1", "qs": "^6.9.6", "ramda": "^0.27.2", - "react": "^17.0.2", + "react": "^18.0.0", "react-chartjs-2": "^3.3.0", "react-colorful": "^5.5.1", "react-copy-to-clipboard": "^5.0.4", "react-datepicker": "^4.7.0", - "react-dom": "^17.0.2", + "react-dom": "^18.0.0", "react-external-link": "^1.2.2", - "react-leaflet": "^3.2.5", - "react-redux": "^7.2.6", - "react-router-dom": "^6.2.2", + "react-leaflet": "^4.0.0", + "react-redux": "^8.0.0", + "react-router-dom": "^6.3.0", "react-swipeable": "^6.2.0", "react-tag-autocomplete": "^6.3.0", "reactstrap": "^9.0.1", - "redux": "^4.1.2", + "redux": "^4.2.0", "redux-localstorage-simple": "^2.4.1", "redux-thunk": "^2.4.1", "stream": "^0.0.2", @@ -62,13 +62,11 @@ "@types/leaflet": "^1.7.9", "@types/qs": "^6.9.7", "@types/ramda": "0.27.38", - "@types/react": "^17.0.39", + "@types/react": "^18.0.6", "@types/react-color": "^3.0.6", "@types/react-copy-to-clipboard": "^5.0.2", "@types/react-datepicker": "^4.3.4", - "@types/react-dom": "^17.0.13", - "@types/react-leaflet": "^2.8.2", - "@types/react-redux": "^7.1.23", + "@types/react-dom": "^18.0.2", "@types/react-tag-autocomplete": "^6.1.1", "@types/uuid": "^8.3.4", "@wojtekmaj/enzyme-adapter-react-17": "0.6.5", @@ -3384,13 +3382,13 @@ } }, "node_modules/@react-leaflet/core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-1.1.1.tgz", - "integrity": "sha512-7PGLWa9MZ5x/cWy8EH2VzI4T8q5WpuHbixzCDXqixP/WyqwIrg5NDUPgYuFnB4IEIZF+6nA265mYzswFo/h1Pw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.0.0.tgz", + "integrity": "sha512-SQQ5DCQIaLzvslN6wCXs5OWqtlvk1Ubv2n5d7zTM8SDl9hM5Rr2wVy7/nOCIY958D75/ovhq6ZoSvT7GLCX6sg==", "peerDependencies": { - "leaflet": "^1.7.1", - "react": "^17.0.1", - "react-dom": "^17.0.1" + "leaflet": "^1.8.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/@rollup/plugin-babel": { @@ -4837,9 +4835,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "17.0.39", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz", - "integrity": "sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==", + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.6.tgz", + "integrity": "sha512-bPqwzJRzKtfI0mVYr5R+1o9BOE8UEXefwc1LwcBtfnaAn6OoqMhLa/91VA8aeWfDPJt1kHvYKI8RHcQybZLHHA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -4877,36 +4875,43 @@ "react-popper": "^2.2.5" } }, + "node_modules/@types/react-datepicker/node_modules/react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "dev": true, + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@types/react-datepicker/node_modules/react-popper": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.5.tgz", + "integrity": "sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==", + "dev": true, + "dependencies": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + }, + "peerDependencies": { + "@popperjs/core": "^2.0.0", + "react": "^16.8.0 || ^17" + } + }, "node_modules/@types/react-dom": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.13.tgz", - "integrity": "sha512-wEP+B8hzvy6ORDv1QBhcQia4j6ea4SFIBttHYpXKPFZRviBvknq0FRh3VrIxeXUmsPkwuXVZrVGG7KUVONmXCQ==", - "dev": true, + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.2.tgz", + "integrity": "sha512-UxeS+Wtj5bvLRREz9tIgsK4ntCuLDo0EcAcACgw3E+9wE8ePDr9uQpq53MfcyxyIS55xJ+0B6mDS8c4qkkHLBg==", + "devOptional": true, "dependencies": { "@types/react": "*" } }, - "node_modules/@types/react-leaflet": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/@types/react-leaflet/-/react-leaflet-2.8.2.tgz", - "integrity": "sha512-Iel8Vd1bSCD38Yhiqcmm/+9hjPEdd39LFE3tBMbOytq3QAQsC3LDrbo6ifoh8JbpqPbCsQPo9Wx5OELHixEShg==", - "dev": true, - "dependencies": { - "@types/leaflet": "*", - "@types/react": "*" - } - }, - "node_modules/@types/react-redux": { - "version": "7.1.23", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.23.tgz", - "integrity": "sha512-D02o3FPfqQlfu2WeEYwh3x2otYd2Dk1o8wAfsA0B1C2AJEFxE663Ozu7JzuWbznGgW248NaOF6wsqCGNq9d3qw==", - "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/react-tag-autocomplete": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/@types/react-tag-autocomplete/-/react-tag-autocomplete-6.1.1.tgz", @@ -5018,6 +5023,11 @@ "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", "dev": true }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -5585,6 +5595,21 @@ "react-dom": "^17.0.0-0" } }, + "node_modules/@wojtekmaj/enzyme-adapter-react-17/node_modules/@wojtekmaj/enzyme-adapter-utils": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@wojtekmaj/enzyme-adapter-utils/-/enzyme-adapter-utils-0.1.4.tgz", + "integrity": "sha512-ARGIQSIIv3oBia1m5Ihn1VU0FGmft6KPe39SBKTb8p7LSXO23YI4kNtc4M/cKoIY7P+IYdrZcgMObvedyjoSQA==", + "dev": true, + "dependencies": { + "function.prototype.name": "^1.1.0", + "has": "^1.0.0", + "object.fromentries": "^2.0.0", + "prop-types": "^15.7.0" + }, + "peerDependencies": { + "react": "^17.0.0-0" + } + }, "node_modules/@wojtekmaj/enzyme-adapter-react-17/node_modules/enzyme-shallow-equal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.4.tgz", @@ -5619,19 +5644,17 @@ "react": "17.0.1" } }, - "node_modules/@wojtekmaj/enzyme-adapter-utils": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@wojtekmaj/enzyme-adapter-utils/-/enzyme-adapter-utils-0.1.4.tgz", - "integrity": "sha512-ARGIQSIIv3oBia1m5Ihn1VU0FGmft6KPe39SBKTb8p7LSXO23YI4kNtc4M/cKoIY7P+IYdrZcgMObvedyjoSQA==", + "node_modules/@wojtekmaj/enzyme-adapter-react-17/node_modules/react-test-renderer/node_modules/react-shallow-renderer": { + "version": "16.14.1", + "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz", + "integrity": "sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==", "dev": true, "dependencies": { - "function.prototype.name": "^1.1.0", - "has": "^1.0.0", - "object.fromentries": "^2.0.0", - "prop-types": "^15.7.0" + "object-assign": "^4.1.1", + "react-is": "^16.12.0 || ^17.0.0" }, "peerDependencies": { - "react": "^17.0.0-0" + "react": "^16.0.0 || ^17.0.0" } }, "node_modules/@xtuc/ieee754": { @@ -15837,9 +15860,9 @@ } }, "node_modules/leaflet": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz", - "integrity": "sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.8.0.tgz", + "integrity": "sha512-gwhMjFCQiYs3x/Sf+d49f10ERXaEFCPr+nVTryhAW8DWbMGqJqt9G4XuIaHmFW08zYvhgdzqXGr8AlW8v8dQkA==" }, "node_modules/leven": { "version": "3.1.0", @@ -18753,12 +18776,11 @@ } }, "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.0.0.tgz", + "integrity": "sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" @@ -18839,6 +18861,32 @@ "react-dom": "^16.9.0 || ^17" } }, + "node_modules/react-datepicker/node_modules/react-onclickoutside": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.12.1.tgz", + "integrity": "sha512-a5Q7CkWznBRUWPmocCvE8b6lEYw1s6+opp/60dCunhO+G6E4tDTO2Sd2jKE+leEnnrLAE2Wj5DlDHNqj5wPv1Q==", + "funding": { + "type": "individual", + "url": "https://github.com/Pomax/react-onclickoutside/blob/master/FUNDING.md" + }, + "peerDependencies": { + "react": "^15.5.x || ^16.x || ^17.x", + "react-dom": "^15.5.x || ^16.x || ^17.x" + } + }, + "node_modules/react-datepicker/node_modules/react-popper": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.5.tgz", + "integrity": "sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==", + "dependencies": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + }, + "peerDependencies": { + "@popperjs/core": "^2.0.0", + "react": "^16.8.0 || ^17" + } + }, "node_modules/react-dev-utils": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.0.tgz", @@ -19342,16 +19390,23 @@ } }, "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.0.0.tgz", + "integrity": "sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw==", "dependencies": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.21.0" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.0.0" + } + }, + "node_modules/react-dom/node_modules/scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "dependencies": { + "loose-envify": "^1.1.0" } }, "node_modules/react-error-overlay": { @@ -19380,72 +19435,60 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-leaflet": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-3.2.5.tgz", - "integrity": "sha512-Z3KZ+4SijsRbbrt2I1a3ZDY6+V6Pm91eYTdxTN18G6IOkFRsJo1BuSPLFnyFrlF3WDjQFPEcTPkEgD1VEeAoBg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.0.0.tgz", + "integrity": "sha512-qJJvoCNe12XHSWVUwhXYmMObPoSYy8h/hn0aDNvcBuq3O8zmVI5S2RdabhaDg/iWMCJ2jbCWZWtIU5VtztO9sg==", "dependencies": { - "@react-leaflet/core": "^1.1.1" + "@react-leaflet/core": "^2.0.0" }, "peerDependencies": { - "leaflet": "^1.7.1", - "react": "^17.0.1", - "react-dom": "^17.0.1" - } - }, - "node_modules/react-onclickoutside": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.12.1.tgz", - "integrity": "sha512-a5Q7CkWznBRUWPmocCvE8b6lEYw1s6+opp/60dCunhO+G6E4tDTO2Sd2jKE+leEnnrLAE2Wj5DlDHNqj5wPv1Q==", - "funding": { - "type": "individual", - "url": "https://github.com/Pomax/react-onclickoutside/blob/master/FUNDING.md" - }, - "peerDependencies": { - "react": "^15.5.x || ^16.x || ^17.x", - "react-dom": "^15.5.x || ^16.x || ^17.x" - } - }, - "node_modules/react-popper": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.5.tgz", - "integrity": "sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==", - "dependencies": { - "react-fast-compare": "^3.0.1", - "warning": "^4.0.2" - }, - "peerDependencies": { - "@popperjs/core": "^2.0.0", - "react": "^16.8.0 || ^17" + "leaflet": "^1.8.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" } }, "node_modules/react-redux": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz", - "integrity": "sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.1.tgz", + "integrity": "sha512-LMZMsPY4DYdZfLJgd7i79n5Kps5N9XVLCJJeWAaPYTV+Eah2zTuBjTxKtNEbjiyitbq80/eIkm55CYSLqAub3w==", "dependencies": { - "@babel/runtime": "^7.15.4", - "@types/react-redux": "^7.1.20", + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", "hoist-non-react-statics": "^3.3.2", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" }, "peerDependencies": { - "react": "^16.8.3 || ^17" + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4" }, "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, "react-dom": { "optional": true }, "react-native": { "optional": true + }, + "redux": { + "optional": true } } }, "node_modules/react-redux/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.0.0.tgz", + "integrity": "sha512-yUcBYdBBbo3QiPsgYDcfQcIkGZHfxOaoE6HLSnr1sPzMhdyxusbfKOSUbSd/ocGi32dxcj366PsTj+5oggeKKw==" }, "node_modules/react-refresh": { "version": "0.11.0", @@ -19457,9 +19500,9 @@ } }, "node_modules/react-router": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz", - "integrity": "sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz", + "integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==", "dependencies": { "history": "^5.2.0" }, @@ -19468,12 +19511,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.2.tgz", - "integrity": "sha512-AtYEsAST7bDD4dLSQHDnk/qxWLJdad5t1HFa1qJyUrCeGgEuCSw0VB/27ARbF9Fi/W5598ujvJOm3ujUCVzuYQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz", + "integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==", "dependencies": { "history": "^5.2.0", - "react-router": "6.2.2" + "react-router": "6.3.0" }, "peerDependencies": { "react": ">=16.8", @@ -21125,25 +21168,6 @@ "node": ">= 10.0.0" } }, - "node_modules/react-shallow-renderer": { - "version": "16.14.1", - "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz", - "integrity": "sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==", - "dev": true, - "dependencies": { - "object-assign": "^4.1.1", - "react-is": "^16.12.0 || ^17.0.0" - }, - "peerDependencies": { - "react": "^16.0.0 || ^17.0.0" - } - }, - "node_modules/react-shallow-renderer/node_modules/react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true - }, "node_modules/react-swipeable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/react-swipeable/-/react-swipeable-6.2.0.tgz", @@ -21197,6 +21221,19 @@ "react-dom": ">=16.8.0" } }, + "node_modules/reactstrap/node_modules/react-popper": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.5.tgz", + "integrity": "sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==", + "dependencies": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + }, + "peerDependencies": { + "@popperjs/core": "^2.0.0", + "react": "^16.8.0 || ^17" + } + }, "node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -21369,9 +21406,9 @@ } }, "node_modules/redux": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz", - "integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", + "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", "dependencies": { "@babel/runtime": "^7.9.2" } @@ -22202,6 +22239,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -25400,6 +25438,14 @@ "node": ">=0.10.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.0.0.tgz", + "integrity": "sha512-AFVsxg5GkFg8GDcxnl+Z0lMAz9rE8DGJCc28qnBuQF7lac57B5smLcT37aXpXIIPz75rW4g3eXHPjhHwdGskOw==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0-rc" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -29299,9 +29345,9 @@ "integrity": "sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==" }, "@react-leaflet/core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-1.1.1.tgz", - "integrity": "sha512-7PGLWa9MZ5x/cWy8EH2VzI4T8q5WpuHbixzCDXqixP/WyqwIrg5NDUPgYuFnB4IEIZF+6nA265mYzswFo/h1Pw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.0.0.tgz", + "integrity": "sha512-SQQ5DCQIaLzvslN6wCXs5OWqtlvk1Ubv2n5d7zTM8SDl9hM5Rr2wVy7/nOCIY958D75/ovhq6ZoSvT7GLCX6sg==", "requires": {} }, "@rollup/plugin-babel": { @@ -30413,9 +30459,9 @@ "dev": true }, "@types/react": { - "version": "17.0.39", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz", - "integrity": "sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==", + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.6.tgz", + "integrity": "sha512-bPqwzJRzKtfI0mVYr5R+1o9BOE8UEXefwc1LwcBtfnaAn6OoqMhLa/91VA8aeWfDPJt1kHvYKI8RHcQybZLHHA==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -30451,38 +30497,40 @@ "@types/react": "*", "date-fns": "^2.0.1", "react-popper": "^2.2.5" + }, + "dependencies": { + "react": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "dev": true, + "peer": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "react-popper": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.5.tgz", + "integrity": "sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==", + "dev": true, + "requires": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + } + } } }, "@types/react-dom": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.13.tgz", - "integrity": "sha512-wEP+B8hzvy6ORDv1QBhcQia4j6ea4SFIBttHYpXKPFZRviBvknq0FRh3VrIxeXUmsPkwuXVZrVGG7KUVONmXCQ==", - "dev": true, + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.2.tgz", + "integrity": "sha512-UxeS+Wtj5bvLRREz9tIgsK4ntCuLDo0EcAcACgw3E+9wE8ePDr9uQpq53MfcyxyIS55xJ+0B6mDS8c4qkkHLBg==", + "devOptional": true, "requires": { "@types/react": "*" } }, - "@types/react-leaflet": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/@types/react-leaflet/-/react-leaflet-2.8.2.tgz", - "integrity": "sha512-Iel8Vd1bSCD38Yhiqcmm/+9hjPEdd39LFE3tBMbOytq3QAQsC3LDrbo6ifoh8JbpqPbCsQPo9Wx5OELHixEShg==", - "dev": true, - "requires": { - "@types/leaflet": "*", - "@types/react": "*" - } - }, - "@types/react-redux": { - "version": "7.1.23", - "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.23.tgz", - "integrity": "sha512-D02o3FPfqQlfu2WeEYwh3x2otYd2Dk1o8wAfsA0B1C2AJEFxE663Ozu7JzuWbznGgW248NaOF6wsqCGNq9d3qw==", - "requires": { - "@types/hoist-non-react-statics": "^3.3.0", - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0", - "redux": "^4.0.0" - } - }, "@types/react-tag-autocomplete": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/@types/react-tag-autocomplete/-/react-tag-autocomplete-6.1.1.tgz", @@ -30594,6 +30642,11 @@ "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", "dev": true }, + "@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "@types/uuid": { "version": "8.3.4", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz", @@ -31024,6 +31077,18 @@ "react-test-renderer": "^17.0.0" }, "dependencies": { + "@wojtekmaj/enzyme-adapter-utils": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@wojtekmaj/enzyme-adapter-utils/-/enzyme-adapter-utils-0.1.4.tgz", + "integrity": "sha512-ARGIQSIIv3oBia1m5Ihn1VU0FGmft6KPe39SBKTb8p7LSXO23YI4kNtc4M/cKoIY7P+IYdrZcgMObvedyjoSQA==", + "dev": true, + "requires": { + "function.prototype.name": "^1.1.0", + "has": "^1.0.0", + "object.fromentries": "^2.0.0", + "prop-types": "^15.7.0" + } + }, "enzyme-shallow-equal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.4.tgz", @@ -31050,22 +31115,22 @@ "react-is": "^17.0.1", "react-shallow-renderer": "^16.13.1", "scheduler": "^0.20.1" + }, + "dependencies": { + "react-shallow-renderer": { + "version": "16.14.1", + "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz", + "integrity": "sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "react-is": "^16.12.0 || ^17.0.0" + } + } } } } }, - "@wojtekmaj/enzyme-adapter-utils": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@wojtekmaj/enzyme-adapter-utils/-/enzyme-adapter-utils-0.1.4.tgz", - "integrity": "sha512-ARGIQSIIv3oBia1m5Ihn1VU0FGmft6KPe39SBKTb8p7LSXO23YI4kNtc4M/cKoIY7P+IYdrZcgMObvedyjoSQA==", - "dev": true, - "requires": { - "function.prototype.name": "^1.1.0", - "has": "^1.0.0", - "object.fromentries": "^2.0.0", - "prop-types": "^15.7.0" - } - }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -38766,9 +38831,9 @@ } }, "leaflet": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.7.1.tgz", - "integrity": "sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.8.0.tgz", + "integrity": "sha512-gwhMjFCQiYs3x/Sf+d49f10ERXaEFCPr+nVTryhAW8DWbMGqJqt9G4XuIaHmFW08zYvhgdzqXGr8AlW8v8dQkA==" }, "leven": { "version": "3.1.0", @@ -40988,12 +41053,11 @@ } }, "react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.0.0.tgz", + "integrity": "sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A==", "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "react-app-polyfill": { @@ -41050,6 +41114,23 @@ "prop-types": "^15.7.2", "react-onclickoutside": "^6.12.0", "react-popper": "^2.2.5" + }, + "dependencies": { + "react-onclickoutside": { + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.12.1.tgz", + "integrity": "sha512-a5Q7CkWznBRUWPmocCvE8b6lEYw1s6+opp/60dCunhO+G6E4tDTO2Sd2jKE+leEnnrLAE2Wj5DlDHNqj5wPv1Q==", + "requires": {} + }, + "react-popper": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.5.tgz", + "integrity": "sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==", + "requires": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + } + } } }, "react-dev-utils": { @@ -41394,13 +41475,22 @@ } }, "react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.0.0.tgz", + "integrity": "sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw==", "requires": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.21.0" + }, + "dependencies": { + "scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "requires": { + "loose-envify": "^1.1.0" + } + } } }, "react-error-overlay": { @@ -41426,45 +41516,30 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-leaflet": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-3.2.5.tgz", - "integrity": "sha512-Z3KZ+4SijsRbbrt2I1a3ZDY6+V6Pm91eYTdxTN18G6IOkFRsJo1BuSPLFnyFrlF3WDjQFPEcTPkEgD1VEeAoBg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-4.0.0.tgz", + "integrity": "sha512-qJJvoCNe12XHSWVUwhXYmMObPoSYy8h/hn0aDNvcBuq3O8zmVI5S2RdabhaDg/iWMCJ2jbCWZWtIU5VtztO9sg==", "requires": { - "@react-leaflet/core": "^1.1.1" - } - }, - "react-onclickoutside": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.12.1.tgz", - "integrity": "sha512-a5Q7CkWznBRUWPmocCvE8b6lEYw1s6+opp/60dCunhO+G6E4tDTO2Sd2jKE+leEnnrLAE2Wj5DlDHNqj5wPv1Q==", - "requires": {} - }, - "react-popper": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.5.tgz", - "integrity": "sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==", - "requires": { - "react-fast-compare": "^3.0.1", - "warning": "^4.0.2" + "@react-leaflet/core": "^2.0.0" } }, "react-redux": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.6.tgz", - "integrity": "sha512-10RPdsz0UUrRL1NZE0ejTkucnclYSgXp5q+tB5SWx2qeG2ZJQJyymgAhwKy73yiL/13btfB6fPr+rgbMAaZIAQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.1.tgz", + "integrity": "sha512-LMZMsPY4DYdZfLJgd7i79n5Kps5N9XVLCJJeWAaPYTV+Eah2zTuBjTxKtNEbjiyitbq80/eIkm55CYSLqAub3w==", "requires": { - "@babel/runtime": "^7.15.4", - "@types/react-redux": "^7.1.20", + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", "hoist-non-react-statics": "^3.3.2", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" }, "dependencies": { "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.0.0.tgz", + "integrity": "sha512-yUcBYdBBbo3QiPsgYDcfQcIkGZHfxOaoE6HLSnr1sPzMhdyxusbfKOSUbSd/ocGi32dxcj366PsTj+5oggeKKw==" } } }, @@ -41475,20 +41550,20 @@ "dev": true }, "react-router": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz", - "integrity": "sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz", + "integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==", "requires": { "history": "^5.2.0" } }, "react-router-dom": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.2.tgz", - "integrity": "sha512-AtYEsAST7bDD4dLSQHDnk/qxWLJdad5t1HFa1qJyUrCeGgEuCSw0VB/27ARbF9Fi/W5598ujvJOm3ujUCVzuYQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz", + "integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==", "requires": { "history": "^5.2.0", - "react-router": "6.2.2" + "react-router": "6.3.0" } }, "react-scripts": { @@ -42540,24 +42615,6 @@ } } }, - "react-shallow-renderer": { - "version": "16.14.1", - "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz", - "integrity": "sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "react-is": "^16.12.0 || ^17.0.0" - }, - "dependencies": { - "react-is": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", - "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", - "dev": true - } - } - }, "react-swipeable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/react-swipeable/-/react-swipeable-6.2.0.tgz", @@ -42592,6 +42649,17 @@ "prop-types": "^15.5.8", "react-popper": "^2.2.4", "react-transition-group": "^4.4.2" + }, + "dependencies": { + "react-popper": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-2.2.5.tgz", + "integrity": "sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==", + "requires": { + "react-fast-compare": "^3.0.1", + "warning": "^4.0.2" + } + } } }, "read-pkg": { @@ -42736,9 +42804,9 @@ } }, "redux": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.1.2.tgz", - "integrity": "sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", + "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", "requires": { "@babel/runtime": "^7.9.2" } @@ -43373,6 +43441,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", + "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -45840,6 +45909,12 @@ "integrity": "sha1-1QyMrHmhn7wg8pEfVuuXP04QBw8=", "dev": true }, + "use-sync-external-store": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.0.0.tgz", + "integrity": "sha512-AFVsxg5GkFg8GDcxnl+Z0lMAz9rE8DGJCc28qnBuQF7lac57B5smLcT37aXpXIIPz75rW4g3eXHPjhHwdGskOw==", + "requires": {} + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index e7ce6866..fd9dd228 100644 --- a/package.json +++ b/package.json @@ -42,20 +42,20 @@ "leaflet": "^1.7.1", "qs": "^6.9.6", "ramda": "^0.27.2", - "react": "^17.0.2", + "react": "^18.0.0", "react-chartjs-2": "^3.3.0", "react-colorful": "^5.5.1", "react-copy-to-clipboard": "^5.0.4", "react-datepicker": "^4.7.0", - "react-dom": "^17.0.2", + "react-dom": "^18.0.0", "react-external-link": "^1.2.2", - "react-leaflet": "^3.2.5", - "react-redux": "^7.2.6", - "react-router-dom": "^6.2.2", + "react-leaflet": "^4.0.0", + "react-redux": "^8.0.0", + "react-router-dom": "^6.3.0", "react-swipeable": "^6.2.0", "react-tag-autocomplete": "^6.3.0", "reactstrap": "^9.0.1", - "redux": "^4.1.2", + "redux": "^4.2.0", "redux-localstorage-simple": "^2.4.1", "redux-thunk": "^2.4.1", "stream": "^0.0.2", @@ -78,13 +78,11 @@ "@types/leaflet": "^1.7.9", "@types/qs": "^6.9.7", "@types/ramda": "0.27.38", - "@types/react": "^17.0.39", + "@types/react": "^18.0.6", "@types/react-color": "^3.0.6", "@types/react-copy-to-clipboard": "^5.0.2", "@types/react-datepicker": "^4.3.4", - "@types/react-dom": "^17.0.13", - "@types/react-leaflet": "^2.8.2", - "@types/react-redux": "^7.1.23", + "@types/react-dom": "^18.0.2", "@types/react-tag-autocomplete": "^6.1.1", "@types/uuid": "^8.3.4", "@wojtekmaj/enzyme-adapter-react-17": "0.6.5", diff --git a/src/common/NoMenuLayout.tsx b/src/common/NoMenuLayout.tsx index ea3862f2..9e44c15b 100644 --- a/src/common/NoMenuLayout.tsx +++ b/src/common/NoMenuLayout.tsx @@ -1,4 +1,6 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import './NoMenuLayout.scss'; -export const NoMenuLayout: FC = ({ children }) =>
{children}
; +export const NoMenuLayout: FC> = ({ children }) => ( +
{children}
+); diff --git a/src/common/NotFound.tsx b/src/common/NotFound.tsx index 5770fda3..750c8c9d 100644 --- a/src/common/NotFound.tsx +++ b/src/common/NotFound.tsx @@ -1,10 +1,8 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import { Link } from 'react-router-dom'; import { SimpleCard } from '../utils/SimpleCard'; -interface NotFoundProps { - to?: string; -} +type NotFoundProps = PropsWithChildren<{ to?: string }>; const NotFound: FC = ({ to = '/', children = 'Home' }) => (
diff --git a/src/common/ScrollToTop.tsx b/src/common/ScrollToTop.tsx index aae4a7f5..85fe9766 100644 --- a/src/common/ScrollToTop.tsx +++ b/src/common/ScrollToTop.tsx @@ -1,7 +1,7 @@ -import { FC, useEffect } from 'react'; +import { FC, PropsWithChildren, useEffect } from 'react'; import { useLocation } from 'react-router-dom'; -const ScrollToTop = (): FC => ({ children }) => { +const ScrollToTop = (): FC> => ({ children }) => { const location = useLocation(); useEffect(() => { diff --git a/src/index.tsx b/src/index.tsx index 99ff2820..5f0cd85e 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,4 +1,4 @@ -import { render } from 'react-dom'; +import { createRoot } from 'react-dom/client'; import { Provider } from 'react-redux'; import { BrowserRouter } from 'react-router-dom'; import pack from '../package.json'; @@ -15,7 +15,7 @@ fixLeafletIcons(); const { App, ScrollToTop, ErrorHandler, appUpdateAvailable } = container; -render( +createRoot(document.getElementById('root')!).render( // eslint-disable-line @typescript-eslint/no-non-null-assertion @@ -25,7 +25,6 @@ render( , - document.getElementById('root'), ); // Learn more about service workers: https://cra.link/PWA diff --git a/src/servers/DeleteServerButton.tsx b/src/servers/DeleteServerButton.tsx index 21d40fc4..a40e6ecc 100644 --- a/src/servers/DeleteServerButton.tsx +++ b/src/servers/DeleteServerButton.tsx @@ -1,15 +1,15 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import { faMinusCircle as deleteIcon } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { useToggle } from '../utils/helpers/hooks'; import { DeleteServerModalProps } from './DeleteServerModal'; import { ServerWithId } from './data'; -export interface DeleteServerButtonProps { +export type DeleteServerButtonProps = PropsWithChildren<{ server: ServerWithId; className?: string; textClassName?: string; -} +}>; const DeleteServerButton = (DeleteServerModal: FC): FC => ( { server, className, children, textClassName }, diff --git a/src/servers/Overview.tsx b/src/servers/Overview.tsx index fc29a675..9127b1ab 100644 --- a/src/servers/Overview.tsx +++ b/src/servers/Overview.tsx @@ -8,12 +8,12 @@ import { ShortUrlsTableProps } from '../short-urls/ShortUrlsTable'; import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub'; import { CreateShortUrlProps } from '../short-urls/CreateShortUrl'; import { VisitsOverview } from '../visits/reducers/visitsOverview'; -import { Versions } from '../utils/helpers/version'; import { Topics } from '../mercure/helpers/Topics'; import { ShlinkShortUrlsListParams } from '../api/types'; import { supportsNonOrphanVisits, supportsOrphanVisits } from '../utils/helpers/features'; import { getServerId, SelectedServer } from './data'; import { HighlightCard } from './helpers/HighlightCard'; +import { ForServerVersionProps } from './helpers/ForServerVersion'; interface OverviewConnectProps { shortUrlsList: ShortUrlsListState; @@ -28,7 +28,7 @@ interface OverviewConnectProps { export const Overview = ( ShortUrlsTable: FC, CreateShortUrl: FC, - ForServerVersion: FC, + ForServerVersion: FC, ) => boundToMercureHub(({ shortUrlsList, listShortUrls, diff --git a/src/servers/ServersListGroup.tsx b/src/servers/ServersListGroup.tsx index ed545b27..a88787a7 100644 --- a/src/servers/ServersListGroup.tsx +++ b/src/servers/ServersListGroup.tsx @@ -1,4 +1,4 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import { ListGroup, ListGroupItem } from 'reactstrap'; import { Link } from 'react-router-dom'; import classNames from 'classnames'; @@ -7,10 +7,10 @@ import { faChevronRight as chevronIcon } from '@fortawesome/free-solid-svg-icons import { ServerWithId } from './data'; import './ServersListGroup.scss'; -interface ServersListGroupProps { +type ServersListGroupProps = PropsWithChildren<{ servers: ServerWithId[]; embedded?: boolean; -} +}>; const ServerListItem = ({ id, name }: { id: string; name: string }) => ( diff --git a/src/servers/helpers/ForServerVersion.tsx b/src/servers/helpers/ForServerVersion.tsx index 1f871a8e..abda57f2 100644 --- a/src/servers/helpers/ForServerVersion.tsx +++ b/src/servers/helpers/ForServerVersion.tsx @@ -1,12 +1,14 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import { versionMatch, Versions } from '../../utils/helpers/version'; import { isReachableServer, SelectedServer } from '../data'; -interface ForServerVersionProps extends Versions { +export type ForServerVersionProps = PropsWithChildren; + +interface ForServerVersionConnectProps extends ForServerVersionProps { selectedServer: SelectedServer; } -const ForServerVersion: FC = ({ minVersion, maxVersion, selectedServer, children }) => { +const ForServerVersion: FC = ({ minVersion, maxVersion, selectedServer, children }) => { if (!isReachableServer(selectedServer)) { return null; } diff --git a/src/servers/helpers/HighlightCard.tsx b/src/servers/helpers/HighlightCard.tsx index 5f13edeb..d5a6f1ef 100644 --- a/src/servers/helpers/HighlightCard.tsx +++ b/src/servers/helpers/HighlightCard.tsx @@ -1,14 +1,14 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import { Card, CardText, CardTitle } from 'reactstrap'; import { Link } from 'react-router-dom'; import { faArrowAltCircleRight as linkIcon } from '@fortawesome/free-regular-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import './HighlightCard.scss'; -export interface HighlightCardProps { +export type HighlightCardProps = PropsWithChildren<{ title: string; link?: string | false; -} +}>; const buildExtraProps = (link?: string | false) => (!link ? {} : { tag: Link, to: link }); diff --git a/src/servers/helpers/ImportServersBtn.tsx b/src/servers/helpers/ImportServersBtn.tsx index abc5be8c..e01500c6 100644 --- a/src/servers/helpers/ImportServersBtn.tsx +++ b/src/servers/helpers/ImportServersBtn.tsx @@ -1,4 +1,4 @@ -import { useRef, RefObject, ChangeEvent, MutableRefObject, useState, useEffect, FC } from 'react'; +import { useRef, RefObject, ChangeEvent, MutableRefObject, useState, useEffect, FC, PropsWithChildren } from 'react'; import { Button, UncontrolledTooltip } from 'reactstrap'; import { complement, pipe } from 'ramda'; import { faFileUpload as importIcon } from '@fortawesome/free-solid-svg-icons'; @@ -11,12 +11,12 @@ import './ImportServersBtn.scss'; type Ref = RefObject | MutableRefObject; -export interface ImportServersBtnProps { +export type ImportServersBtnProps = PropsWithChildren<{ onImport?: () => void; onImportError?: (error: Error) => void; tooltipPlacement?: 'top' | 'bottom'; className?: string; -} +}>; interface ImportServersBtnConnectProps extends ImportServersBtnProps { createServers: (servers: ServerData[]) => void; diff --git a/src/servers/helpers/ServerForm.tsx b/src/servers/helpers/ServerForm.tsx index 2e708e8e..f13b5b4a 100644 --- a/src/servers/helpers/ServerForm.tsx +++ b/src/servers/helpers/ServerForm.tsx @@ -1,14 +1,14 @@ -import { FC, ReactNode, useEffect, useState } from 'react'; +import { FC, PropsWithChildren, ReactNode, useEffect, useState } from 'react'; import { InputFormGroup } from '../../utils/forms/InputFormGroup'; import { handleEventPreventingDefault } from '../../utils/utils'; import { ServerData } from '../data'; import { SimpleCard } from '../../utils/SimpleCard'; -interface ServerFormProps { +type ServerFormProps = PropsWithChildren<{ onSubmit: (server: ServerData) => void; initialValues?: ServerData; title?: ReactNode; -} +}>; export const ServerForm: FC = ({ onSubmit, initialValues, children, title }) => { const [name, setName] = useState(''); diff --git a/src/short-urls/helpers/QrCodeModal.tsx b/src/short-urls/helpers/QrCodeModal.tsx index d0a7b996..081925e1 100644 --- a/src/short-urls/helpers/QrCodeModal.tsx +++ b/src/short-urls/helpers/QrCodeModal.tsx @@ -13,16 +13,16 @@ import { supportsQrErrorCorrection, } from '../../utils/helpers/features'; import { ImageDownloader } from '../../common/services/ImageDownloader'; -import { Versions } from '../../utils/helpers/version'; +import { ForServerVersionProps } from '../../servers/helpers/ForServerVersion'; import { QrFormatDropdown } from './qr-codes/QrFormatDropdown'; -import './QrCodeModal.scss'; import { QrErrorCorrectionDropdown } from './qr-codes/QrErrorCorrectionDropdown'; +import './QrCodeModal.scss'; interface QrCodeModalConnectProps extends ShortUrlModalProps { selectedServer: SelectedServer; } -const QrCodeModal = (imageDownloader: ImageDownloader, ForServerVersion: FC) => ( +const QrCodeModal = (imageDownloader: ImageDownloader, ForServerVersion: FC) => ( { shortUrl: { shortUrl, shortCode }, toggle, isOpen, selectedServer }: QrCodeModalConnectProps, ) => { const [size, setSize] = useState(300); diff --git a/src/short-urls/helpers/ShortUrlFormCheckboxGroup.tsx b/src/short-urls/helpers/ShortUrlFormCheckboxGroup.tsx index 3798f512..85654d24 100644 --- a/src/short-urls/helpers/ShortUrlFormCheckboxGroup.tsx +++ b/src/short-urls/helpers/ShortUrlFormCheckboxGroup.tsx @@ -1,12 +1,12 @@ -import { ChangeEvent, FC } from 'react'; +import { ChangeEvent, FC, PropsWithChildren } from 'react'; import Checkbox from '../../utils/Checkbox'; import { InfoTooltip } from '../../utils/InfoTooltip'; -interface ShortUrlFormCheckboxGroupProps { +type ShortUrlFormCheckboxGroupProps = PropsWithChildren<{ checked?: boolean; onChange?: (checked: boolean, e: ChangeEvent) => void; infoTooltip?: string; -} +}>; export const ShortUrlFormCheckboxGroup: FC = ( { children, infoTooltip, checked, onChange }, diff --git a/src/tags/helpers/Tag.tsx b/src/tags/helpers/Tag.tsx index 72dd31cd..1bfa2daf 100644 --- a/src/tags/helpers/Tag.tsx +++ b/src/tags/helpers/Tag.tsx @@ -1,16 +1,16 @@ -import { FC, MouseEventHandler } from 'react'; +import { FC, MouseEventHandler, PropsWithChildren } from 'react'; import classNames from 'classnames'; import ColorGenerator from '../../utils/services/ColorGenerator'; import './Tag.scss'; -interface TagProps { +type TagProps = PropsWithChildren<{ colorGenerator: ColorGenerator; text: string; className?: string; clearable?: boolean; onClick?: MouseEventHandler; onClose?: MouseEventHandler; -} +}>; const Tag: FC = ({ text, children, clearable, className = '', colorGenerator, onClick, onClose }) => ( ) => void; className?: string; inline?: boolean; -} +}>; interface BooleanControlWithTypeProps extends BooleanControlProps { type: 'switch' | 'checkbox'; @@ -17,7 +17,7 @@ interface BooleanControlWithTypeProps extends BooleanControlProps { const BooleanControl: FC = ( { checked = false, onChange = identity, className, children, type, inline = false }, ) => { - const { current: id } = useRef(uuid()); + const id = useDomId(); const onChecked = (e: ChangeEvent) => onChange(e.target.checked, e); const typeClasses = { 'form-switch': type === 'switch', diff --git a/src/utils/DropdownBtn.tsx b/src/utils/DropdownBtn.tsx index bbed5ba5..6bfe82cd 100644 --- a/src/utils/DropdownBtn.tsx +++ b/src/utils/DropdownBtn.tsx @@ -1,16 +1,16 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import { Dropdown, DropdownMenu, DropdownToggle } from 'reactstrap'; import { useToggle } from './helpers/hooks'; import './DropdownBtn.scss'; -export interface DropdownBtnProps { +export type DropdownBtnProps = PropsWithChildren<{ text: string; disabled?: boolean; className?: string; dropdownClassName?: string; right?: boolean; minWidth?: number; -} +}>; export const DropdownBtn: FC = ( { text, disabled = false, className = '', children, dropdownClassName, right = false, minWidth }, diff --git a/src/utils/DropdownBtnMenu.tsx b/src/utils/DropdownBtnMenu.tsx index 26d4565e..694ccb89 100644 --- a/src/utils/DropdownBtnMenu.tsx +++ b/src/utils/DropdownBtnMenu.tsx @@ -1,14 +1,14 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import { ButtonDropdown, DropdownMenu, DropdownToggle } from 'reactstrap'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faEllipsisV as menuIcon } from '@fortawesome/free-solid-svg-icons'; import './DropdownBtnMenu.scss'; -export interface DropdownBtnMenuProps { +export type DropdownBtnMenuProps = PropsWithChildren<{ isOpen: boolean; toggle: () => void; right?: boolean; -} +}>; export const DropdownBtnMenu: FC = ({ isOpen, toggle, children, right = true }) => ( diff --git a/src/utils/InfoTooltip.tsx b/src/utils/InfoTooltip.tsx index fead3f4b..34cc7239 100644 --- a/src/utils/InfoTooltip.tsx +++ b/src/utils/InfoTooltip.tsx @@ -1,13 +1,13 @@ -import { FC, useRef } from 'react'; +import { FC, PropsWithChildren, useRef } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faInfoCircle as infoIcon } from '@fortawesome/free-solid-svg-icons'; import { UncontrolledTooltip } from 'reactstrap'; import { Placement } from '@popperjs/core'; -interface InfoTooltipProps { +type InfoTooltipProps = PropsWithChildren<{ className?: string; placement: Placement; -} +}>; export const InfoTooltip: FC = ({ className = '', placement, children }) => { const ref = useRef(); diff --git a/src/utils/Message.tsx b/src/utils/Message.tsx index bd1f740b..7d267ca4 100644 --- a/src/utils/Message.tsx +++ b/src/utils/Message.tsx @@ -1,4 +1,4 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import { Card, Row } from 'reactstrap'; import classNames from 'classnames'; import { faCircleNotch as preloader } from '@fortawesome/free-solid-svg-icons'; @@ -23,12 +23,12 @@ const getTextClassForType = (type: MessageType) => { return map[type]; }; -export interface MessageProps { +export type MessageProps = PropsWithChildren<{ className?: string; loading?: boolean; fullWidth?: boolean; type?: MessageType; -} +}>; const Message: FC = ({ className, children, loading = false, type = 'default', fullWidth = false }) => { const classes = classNames({ diff --git a/src/utils/NavPills.tsx b/src/utils/NavPills.tsx index f1e9ba67..4eaf3f17 100644 --- a/src/utils/NavPills.tsx +++ b/src/utils/NavPills.tsx @@ -1,17 +1,17 @@ -import { FC, Children, isValidElement } from 'react'; +import { FC, Children, isValidElement, PropsWithChildren } from 'react'; import { Card, Nav, NavLink } from 'reactstrap'; import { NavLink as RouterNavLink } from 'react-router-dom'; import './NavPills.scss'; -interface NavPillsProps { +type NavPillsProps = PropsWithChildren<{ fill?: boolean; className?: string; -} +}>; -interface NavPillProps { +type NavPillProps = PropsWithChildren<{ to: string; replace?: boolean; -} +}>; export const NavPillItem: FC = ({ children, ...rest }) => ( diff --git a/src/utils/Result.tsx b/src/utils/Result.tsx index 5f49e703..eacf40f0 100644 --- a/src/utils/Result.tsx +++ b/src/utils/Result.tsx @@ -1,15 +1,15 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import { Row } from 'reactstrap'; import classNames from 'classnames'; import { SimpleCard } from './SimpleCard'; export type ResultType = 'success' | 'error' | 'warning'; -export interface ResultProps { +export type ResultProps = PropsWithChildren<{ type: ResultType; className?: string; small?: boolean; -} +}>; export const Result: FC = ({ children, type, className, small = false }) => ( diff --git a/src/utils/TooltipToggleSwitch.tsx b/src/utils/TooltipToggleSwitch.tsx index 1fb28f61..35d2889b 100644 --- a/src/utils/TooltipToggleSwitch.tsx +++ b/src/utils/TooltipToggleSwitch.tsx @@ -1,9 +1,11 @@ -import { FC, useRef } from 'react'; +import { FC, PropsWithChildren, useRef } from 'react'; import { UncontrolledTooltip, UncontrolledTooltipProps } from 'reactstrap'; import { BooleanControlProps } from './BooleanControl'; import ToggleSwitch from './ToggleSwitch'; -export type TooltipToggleSwitchProps = BooleanControlProps & { tooltip?: Omit }; +export type TooltipToggleSwitchProps = BooleanControlProps & PropsWithChildren<{ + tooltip?: Omit; +}>; export const TooltipToggleSwitch: FC = ({ children, tooltip = {}, ...rest }) => { const ref = useRef(); diff --git a/src/utils/forms/FormText.tsx b/src/utils/forms/FormText.tsx index ffe4044b..c3e1a685 100644 --- a/src/utils/forms/FormText.tsx +++ b/src/utils/forms/FormText.tsx @@ -1,3 +1,5 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; -export const FormText: FC = ({ children }) => {children}; +export const FormText: FC> = ({ children }) => ( + {children} +); diff --git a/src/utils/forms/InputFormGroup.tsx b/src/utils/forms/InputFormGroup.tsx index 016671ad..9e047d3a 100644 --- a/src/utils/forms/InputFormGroup.tsx +++ b/src/utils/forms/InputFormGroup.tsx @@ -1,8 +1,8 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import { InputType } from 'reactstrap/types/lib/Input'; import { LabeledFormGroup } from './LabeledFormGroup'; -export interface InputFormGroupProps { +export type InputFormGroupProps = PropsWithChildren<{ value: string; onChange: (newValue: string) => void; type?: InputType; @@ -10,7 +10,7 @@ export interface InputFormGroupProps { placeholder?: string; className?: string; labelClassName?: string; -} +}>; export const InputFormGroup: FC = ( { children, value, onChange, type, required, placeholder, className, labelClassName }, diff --git a/src/utils/forms/LabeledFormGroup.tsx b/src/utils/forms/LabeledFormGroup.tsx index cb7fd726..ea11c1ee 100644 --- a/src/utils/forms/LabeledFormGroup.tsx +++ b/src/utils/forms/LabeledFormGroup.tsx @@ -1,11 +1,11 @@ -import { FC, ReactNode } from 'react'; +import { FC, PropsWithChildren, ReactNode } from 'react'; -interface LabeledFormGroupProps { +type LabeledFormGroupProps = PropsWithChildren<{ label: ReactNode; noMargin?: boolean; className?: string; labelClassName?: string; -} +}>; /* eslint-disable jsx-a11y/label-has-associated-control */ export const LabeledFormGroup: FC = ( diff --git a/src/utils/helpers/hooks.ts b/src/utils/helpers/hooks.ts index 7b816373..90c232d2 100644 --- a/src/utils/helpers/hooks.ts +++ b/src/utils/helpers/hooks.ts @@ -1,6 +1,7 @@ import { useState, useRef, EffectCallback, DependencyList, useEffect } from 'react'; import { useSwipeable as useReactSwipeable } from 'react-swipeable'; import { useNavigate } from 'react-router-dom'; +import { v4 as uuid } from 'uuid'; import { parseQuery, stringifyQuery } from './query'; const DEFAULT_DELAY = 2000; @@ -82,3 +83,8 @@ export const useGoBack = () => { return () => navigate(-1); }; + +export const useDomId = (): string => { + const { current: id } = useRef(`dom-${uuid()}`); + return id; +}; diff --git a/src/visits/VisitsHeader.tsx b/src/visits/VisitsHeader.tsx index 7cd36a77..85398a6b 100644 --- a/src/visits/VisitsHeader.tsx +++ b/src/visits/VisitsHeader.tsx @@ -1,17 +1,17 @@ import { Button, Card } from 'reactstrap'; -import { FC, ReactNode } from 'react'; +import { FC, PropsWithChildren, ReactNode } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faArrowLeft } from '@fortawesome/free-solid-svg-icons'; import ShortUrlVisitsCount from '../short-urls/helpers/ShortUrlVisitsCount'; import { ShortUrl } from '../short-urls/data'; import { Visit } from './types'; -interface VisitsHeaderProps { +type VisitsHeaderProps = PropsWithChildren<{ visits: Visit[]; goBack: () => void; title: ReactNode; shortUrl?: ShortUrl; -} +}>; const VisitsHeader: FC = ({ visits, goBack, shortUrl, children, title }) => (
diff --git a/src/visits/VisitsStats.tsx b/src/visits/VisitsStats.tsx index 90e7fbe7..f0e35b89 100644 --- a/src/visits/VisitsStats.tsx +++ b/src/visits/VisitsStats.tsx @@ -1,5 +1,5 @@ import { isEmpty, propEq, values } from 'ramda'; -import { useState, useEffect, useMemo, FC, useRef } from 'react'; +import { useState, useEffect, useMemo, FC, useRef, PropsWithChildren } from 'react'; import { Button, Progress, Row } from 'reactstrap'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faCalendarAlt, faMapMarkedAlt, faList, faChartPie } from '@fortawesome/free-solid-svg-icons'; @@ -27,7 +27,7 @@ import { HighlightableProps, highlightedVisitsToStats } from './types/helpers'; import { DoughnutChartCard } from './charts/DoughnutChartCard'; import { SortableBarChartCard } from './charts/SortableBarChartCard'; -export interface VisitsStatsProps { +export type VisitsStatsProps = PropsWithChildren<{ getVisits: (params: VisitsParams, doIntervalFallback?: boolean) => void; visitsInfo: VisitsInfo; settings: Settings; @@ -36,7 +36,7 @@ export interface VisitsStatsProps { domain?: string; exportCsv: (visits: NormalizedVisit[]) => void; isOrphanVisits?: boolean; -} +}>; interface VisitsNavLinkProps { title: string; diff --git a/src/visits/charts/ChartCard.tsx b/src/visits/charts/ChartCard.tsx index 9c25acc8..c68da31a 100644 --- a/src/visits/charts/ChartCard.tsx +++ b/src/visits/charts/ChartCard.tsx @@ -1,11 +1,11 @@ import { Card, CardHeader, CardBody, CardFooter } from 'reactstrap'; -import { FC, ReactNode } from 'react'; +import { FC, PropsWithChildren, ReactNode } from 'react'; import './ChartCard.scss'; -interface ChartCardProps { +type ChartCardProps = PropsWithChildren<{ title: Function | string; footer?: ReactNode; -} +}>; export const ChartCard: FC = ({ title, footer, children }) => ( diff --git a/src/visits/helpers/OpenMapModalBtn.tsx b/src/visits/helpers/OpenMapModalBtn.tsx index d4a5f88a..1afc8583 100644 --- a/src/visits/helpers/OpenMapModalBtn.tsx +++ b/src/visits/helpers/OpenMapModalBtn.tsx @@ -1,8 +1,8 @@ -import { useRef, useState } from 'react'; +import { useState } from 'react'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faMapMarkedAlt as mapIcon } from '@fortawesome/free-solid-svg-icons'; import { Button, Dropdown, DropdownItem, DropdownMenu, UncontrolledTooltip } from 'reactstrap'; -import { useToggle } from '../../utils/helpers/hooks'; +import { useDomId, useToggle } from '../../utils/helpers/hooks'; import { CityStats } from '../types'; import MapModal from './MapModal'; import './OpenMapModalBtn.scss'; @@ -17,7 +17,7 @@ const OpenMapModalBtn = ({ modalTitle, activeCities, locations = [] }: OpenMapMo const [mapIsOpened, , openMap, closeMap] = useToggle(); const [dropdownIsOpened, toggleDropdown, openDropdown] = useToggle(); const [locationsToShow, setLocationsToShow] = useState([]); - const buttonRef = useRef(); + const id = useDomId(); const filterLocations = (cities: CityStats[]) => cities.filter(({ cityName }) => activeCities.includes(cityName)); const onClick = () => { @@ -37,10 +37,10 @@ const OpenMapModalBtn = ({ modalTitle, activeCities, locations = [] }: OpenMapMo return ( <> - - buttonRef.current) as any}>Show in map + Show in map Show all locations diff --git a/test/servers/Overview.test.tsx b/test/servers/Overview.test.tsx index b678a7a5..1dbc7bcf 100644 --- a/test/servers/Overview.test.tsx +++ b/test/servers/Overview.test.tsx @@ -1,4 +1,4 @@ -import { FC } from 'react'; +import { FC, PropsWithChildren } from 'react'; import { mount, ReactWrapper } from 'enzyme'; import { Mock } from 'ts-mockery'; import { Link, MemoryRouter } from 'react-router-dom'; @@ -15,7 +15,7 @@ describe('', () => { let wrapper: ReactWrapper; const ShortUrlsTable = () => null; const CreateShortUrl = () => null; - const ForServerVersion: FC = ({ children }) => <>{children}; + const ForServerVersion: FC> = ({ children }) => <>{children}; const listShortUrls = jest.fn(); const listTags = jest.fn(); const loadVisitsOverview = jest.fn(); diff --git a/tsconfig.json b/tsconfig.json index 655fb804..a822a90e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,7 +5,7 @@ "jsx": "preserve", "lib": [ "dom", - "es2019" + "es2021" ], "module": "esnext", "moduleResolution": "node", @@ -17,7 +17,7 @@ "skipLibCheck": true, "sourceMap": true, "strict": true, - "target": "es2019", + "target": "es2021", "forceConsistentCasingInFileNames": true, "esModuleInterop": true, "resolveJsonModule": true,