mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 01:20:24 +03:00
Updated source code to react-router 6
This commit is contained in:
parent
071eaddfd1
commit
c6e500ba71
31 changed files with 310 additions and 718 deletions
527
package-lock.json
generated
527
package-lock.json
generated
|
@ -35,7 +35,7 @@
|
||||||
"react-external-link": "^1.2.0",
|
"react-external-link": "^1.2.0",
|
||||||
"react-leaflet": "^3.1.0",
|
"react-leaflet": "^3.1.0",
|
||||||
"react-redux": "^7.2.2",
|
"react-redux": "^7.2.2",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^6.2.1",
|
||||||
"react-swipeable": "^6.0.1",
|
"react-swipeable": "^6.0.1",
|
||||||
"react-tag-autocomplete": "^6.1.0",
|
"react-tag-autocomplete": "^6.1.0",
|
||||||
"reactstrap": "^8.9.0",
|
"reactstrap": "^8.9.0",
|
||||||
|
@ -71,7 +71,6 @@
|
||||||
"@types/react-dom": "^17.0.1",
|
"@types/react-dom": "^17.0.1",
|
||||||
"@types/react-leaflet": "^2.5.2",
|
"@types/react-leaflet": "^2.5.2",
|
||||||
"@types/react-redux": "^7.1.16",
|
"@types/react-redux": "^7.1.16",
|
||||||
"@types/react-router-dom": "^5.1.7",
|
|
||||||
"@types/react-tag-autocomplete": "^6.1.0",
|
"@types/react-tag-autocomplete": "^6.1.0",
|
||||||
"@types/uuid": "^8.3.0",
|
"@types/uuid": "^8.3.0",
|
||||||
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
|
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
|
||||||
|
@ -2194,11 +2193,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.2.0",
|
"version": "7.17.0",
|
||||||
"resolved": "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.0.tgz",
|
||||||
"integrity": "sha1-sD5C7t31iY4AZG5MhA+ge6jcrX8=",
|
"integrity": "sha512-etcO/ohMNaNA2UBdaXBBSX/3aEzFMRrVfaPv8Ptc0k+cWpWW0QFiGZ2XnVqQZI1Cf734LbPGmqBKWESfW4x/dQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"regenerator-runtime": "^0.12.0"
|
"regenerator-runtime": "^0.13.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime-corejs3": {
|
"node_modules/@babel/runtime-corejs3": {
|
||||||
|
@ -2211,12 +2213,6 @@
|
||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/runtime-corejs3/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@babel/template": {
|
"node_modules/@babel/template": {
|
||||||
"version": "7.16.0",
|
"version": "7.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz",
|
||||||
|
@ -4408,12 +4404,6 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/history": {
|
|
||||||
"version": "4.7.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz",
|
|
||||||
"integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/@types/hoist-non-react-statics": {
|
"node_modules/@types/hoist-non-react-statics": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
||||||
|
@ -4619,27 +4609,6 @@
|
||||||
"redux": "^4.0.0"
|
"redux": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/react-router": {
|
|
||||||
"version": "5.1.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.11.tgz",
|
|
||||||
"integrity": "sha512-ofHbZMlp0Y2baOHgsWBQ4K3AttxY61bDMkwTiBOkPg7U6C/3UwwB5WaIx28JmSVi/eX3uFEMRo61BV22fDQIvg==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@types/history": "*",
|
|
||||||
"@types/react": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/react-router-dom": {
|
|
||||||
"version": "5.1.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.7.tgz",
|
|
||||||
"integrity": "sha512-D5mHD6TbdV/DNHYsnwBTv+y73ei+mMjrkGrla86HthE4/PVvL1J94Bu3qABU+COXzpL23T1EZapVVpwHuBXiUg==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@types/history": "*",
|
|
||||||
"@types/react": "*",
|
|
||||||
"@types/react-router": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/react-tag-autocomplete": {
|
"node_modules/@types/react-tag-autocomplete": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-tag-autocomplete/-/react-tag-autocomplete-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-tag-autocomplete/-/react-tag-autocomplete-6.1.0.tgz",
|
||||||
|
@ -5639,21 +5608,6 @@
|
||||||
"node": ">=6.0"
|
"node": ">=6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/aria-query/node_modules/@babel/runtime": {
|
|
||||||
"version": "7.13.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.9.tgz",
|
|
||||||
"integrity": "sha512-aY2kU+xgJ3dJ1eU6FMB9EH8dIe8dmusF1xEku52joLvw6eAFN0AI+WxCLDnpev2LEejWBAy2sBvBOBAjI3zmvA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/aria-query/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/arr-diff": {
|
"node_modules/arr-diff": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz",
|
"resolved": "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz",
|
||||||
|
@ -6757,15 +6711,6 @@
|
||||||
"resolve": "^1.12.0"
|
"resolve": "^1.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/babel-plugin-macros/node_modules/@babel/runtime": {
|
|
||||||
"version": "7.12.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
|
|
||||||
"integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/babel-plugin-macros/node_modules/cosmiconfig": {
|
"node_modules/babel-plugin-macros/node_modules/cosmiconfig": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
|
||||||
|
@ -6822,12 +6767,6 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/babel-plugin-macros/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/babel-plugin-macros/node_modules/resolve-from": {
|
"node_modules/babel-plugin-macros/node_modules/resolve-from": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||||
|
@ -7895,12 +7834,6 @@
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/babel-preset-react-app/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/babel-preset-react-app/node_modules/regenerator-transform": {
|
"node_modules/babel-preset-react-app/node_modules/regenerator-transform": {
|
||||||
"version": "0.14.5",
|
"version": "0.14.5",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
|
||||||
|
@ -12429,27 +12362,12 @@
|
||||||
"eslint": "^3 || ^4 || ^5 || ^6 || ^7"
|
"eslint": "^3 || ^4 || ^5 || ^6 || ^7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-jsx-a11y/node_modules/@babel/runtime": {
|
|
||||||
"version": "7.13.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.9.tgz",
|
|
||||||
"integrity": "sha512-aY2kU+xgJ3dJ1eU6FMB9EH8dIe8dmusF1xEku52joLvw6eAFN0AI+WxCLDnpev2LEejWBAy2sBvBOBAjI3zmvA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": {
|
"node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": {
|
||||||
"version": "9.2.2",
|
"version": "9.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
||||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-jsx-a11y/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/eslint-plugin-node": {
|
"node_modules/eslint-plugin-node": {
|
||||||
"version": "11.1.0",
|
"version": "11.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz",
|
||||||
|
@ -15454,16 +15372,11 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/history": {
|
"node_modules/history": {
|
||||||
"version": "4.10.1",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/history/-/history-5.2.0.tgz",
|
||||||
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
|
"integrity": "sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.1.2",
|
"@babel/runtime": "^7.7.6"
|
||||||
"loose-envify": "^1.2.0",
|
|
||||||
"resolve-pathname": "^3.0.0",
|
|
||||||
"tiny-invariant": "^1.0.2",
|
|
||||||
"tiny-warning": "^1.0.0",
|
|
||||||
"value-equal": "^1.0.1"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/hmac-drbg": {
|
"node_modules/hmac-drbg": {
|
||||||
|
@ -19379,32 +19292,6 @@
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mini-create-react-context": {
|
|
||||||
"version": "0.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz",
|
|
||||||
"integrity": "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": "^7.5.5",
|
|
||||||
"tiny-warning": "^1.0.3"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"prop-types": "^15.0.0",
|
|
||||||
"react": "^0.14.0 || ^15.0.0 || ^16.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mini-create-react-context/node_modules/@babel/runtime": {
|
|
||||||
"version": "7.11.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz",
|
|
||||||
"integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==",
|
|
||||||
"dependencies": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mini-create-react-context/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
|
|
||||||
},
|
|
||||||
"node_modules/mini-css-extract-plugin": {
|
"node_modules/mini-css-extract-plugin": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.1.tgz",
|
||||||
|
@ -21113,6 +21000,7 @@
|
||||||
"version": "1.7.0",
|
"version": "1.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
|
||||||
"integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
|
"integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"isarray": "0.0.1"
|
"isarray": "0.0.1"
|
||||||
}
|
}
|
||||||
|
@ -21120,7 +21008,8 @@
|
||||||
"node_modules/path-to-regexp/node_modules/isarray": {
|
"node_modules/path-to-regexp/node_modules/isarray": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz",
|
"resolved": "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz",
|
||||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/path-type": {
|
"node_modules/path-type": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
|
@ -26602,12 +26491,6 @@
|
||||||
"asap": "~2.0.6"
|
"asap": "~2.0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-app-polyfill/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/react-chartjs-2": {
|
"node_modules/react-chartjs-2": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-3.0.4.tgz",
|
||||||
|
@ -27022,59 +26905,33 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-redux/node_modules/@babel/runtime": {
|
|
||||||
"version": "7.12.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
|
|
||||||
"integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
|
|
||||||
"dependencies": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-redux/node_modules/react-is": {
|
"node_modules/react-redux/node_modules/react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
},
|
},
|
||||||
"node_modules/react-redux/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
|
|
||||||
},
|
|
||||||
"node_modules/react-router": {
|
"node_modules/react-router": {
|
||||||
"version": "5.2.0",
|
"version": "6.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz",
|
||||||
"integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==",
|
"integrity": "sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.1.2",
|
"history": "^5.2.0"
|
||||||
"history": "^4.9.0",
|
|
||||||
"hoist-non-react-statics": "^3.1.0",
|
|
||||||
"loose-envify": "^1.3.1",
|
|
||||||
"mini-create-react-context": "^0.4.0",
|
|
||||||
"path-to-regexp": "^1.7.0",
|
|
||||||
"prop-types": "^15.6.2",
|
|
||||||
"react-is": "^16.6.0",
|
|
||||||
"tiny-invariant": "^1.0.2",
|
|
||||||
"tiny-warning": "^1.0.0"
|
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=15"
|
"react": ">=16.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-router-dom": {
|
"node_modules/react-router-dom": {
|
||||||
"version": "5.2.0",
|
"version": "6.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz",
|
||||||
"integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
|
"integrity": "sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.1.2",
|
"history": "^5.2.0",
|
||||||
"history": "^4.9.0",
|
"react-router": "6.2.1"
|
||||||
"loose-envify": "^1.3.1",
|
|
||||||
"prop-types": "^15.6.2",
|
|
||||||
"react-router": "5.2.0",
|
|
||||||
"tiny-invariant": "^1.0.2",
|
|
||||||
"tiny-warning": "^1.0.0"
|
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=15"
|
"react": ">=16.8",
|
||||||
|
"react-dom": ">=16.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-shallow-renderer": {
|
"node_modules/react-shallow-renderer": {
|
||||||
|
@ -27156,19 +27013,6 @@
|
||||||
"react-dom": ">=16.3.0"
|
"react-dom": ">=16.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/reactstrap/node_modules/@babel/runtime": {
|
|
||||||
"version": "7.13.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.8.tgz",
|
|
||||||
"integrity": "sha512-CwQljpw6qSayc0fRG1soxHAKs1CnQMOChm4mlQP6My0kf9upVGizj/KhlTTgyUnETmHpcUXjaluNAkteRFuafg==",
|
|
||||||
"dependencies": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/reactstrap/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
|
|
||||||
},
|
|
||||||
"node_modules/read-pkg": {
|
"node_modules/read-pkg": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
|
||||||
|
@ -27381,9 +27225,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/regenerator-runtime": {
|
"node_modules/regenerator-runtime": {
|
||||||
"version": "0.12.1",
|
"version": "0.13.9",
|
||||||
"resolved": "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
||||||
"integrity": "sha1-+hpxVEdkwDb4xJsToIsllMn4oN4="
|
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
|
||||||
},
|
},
|
||||||
"node_modules/regenerator-transform": {
|
"node_modules/regenerator-transform": {
|
||||||
"version": "0.14.5",
|
"version": "0.14.5",
|
||||||
|
@ -27394,21 +27238,6 @@
|
||||||
"@babel/runtime": "^7.8.4"
|
"@babel/runtime": "^7.8.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/regenerator-transform/node_modules/@babel/runtime": {
|
|
||||||
"version": "7.13.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.8.tgz",
|
|
||||||
"integrity": "sha512-CwQljpw6qSayc0fRG1soxHAKs1CnQMOChm4mlQP6My0kf9upVGizj/KhlTTgyUnETmHpcUXjaluNAkteRFuafg==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/regenerator-transform/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/regex-not": {
|
"node_modules/regex-not": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz",
|
"resolved": "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz",
|
||||||
|
@ -27880,11 +27709,6 @@
|
||||||
"node": ">=4"
|
"node": ">=4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/resolve-pathname": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
|
|
||||||
},
|
|
||||||
"node_modules/resolve-url": {
|
"node_modules/resolve-url": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
|
||||||
|
@ -31802,16 +31626,6 @@
|
||||||
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
|
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/tiny-invariant": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw=="
|
|
||||||
},
|
|
||||||
"node_modules/tiny-warning": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
|
|
||||||
},
|
|
||||||
"node_modules/tinycolor2": {
|
"node_modules/tinycolor2": {
|
||||||
"version": "1.4.2",
|
"version": "1.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz",
|
||||||
|
@ -33068,11 +32882,6 @@
|
||||||
"spdx-expression-parse": "^3.0.0"
|
"spdx-expression-parse": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/value-equal": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
|
|
||||||
},
|
|
||||||
"node_modules/vary": {
|
"node_modules/vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
@ -34384,15 +34193,6 @@
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/workbox-build/node_modules/@babel/runtime": {
|
|
||||||
"version": "7.14.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz",
|
|
||||||
"integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/workbox-build/node_modules/fast-json-stable-stringify": {
|
"node_modules/workbox-build/node_modules/fast-json-stable-stringify": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||||
|
@ -34411,12 +34211,6 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/workbox-build/node_modules/regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"node_modules/workbox-build/node_modules/source-map": {
|
"node_modules/workbox-build/node_modules/source-map": {
|
||||||
"version": "0.8.0-beta.0",
|
"version": "0.8.0-beta.0",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
|
||||||
|
@ -36554,11 +36348,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/runtime": {
|
"@babel/runtime": {
|
||||||
"version": "7.2.0",
|
"version": "7.17.0",
|
||||||
"resolved": "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.0.tgz",
|
||||||
"integrity": "sha1-sD5C7t31iY4AZG5MhA+ge6jcrX8=",
|
"integrity": "sha512-etcO/ohMNaNA2UBdaXBBSX/3aEzFMRrVfaPv8Ptc0k+cWpWW0QFiGZ2XnVqQZI1Cf734LbPGmqBKWESfW4x/dQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"regenerator-runtime": "^0.12.0"
|
"regenerator-runtime": "^0.13.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/runtime-corejs3": {
|
"@babel/runtime-corejs3": {
|
||||||
|
@ -36569,14 +36363,6 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"core-js-pure": "^3.0.0",
|
"core-js-pure": "^3.0.0",
|
||||||
"regenerator-runtime": "^0.13.4"
|
"regenerator-runtime": "^0.13.4"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/template": {
|
"@babel/template": {
|
||||||
|
@ -38204,12 +37990,6 @@
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/history": {
|
|
||||||
"version": "4.7.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz",
|
|
||||||
"integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/hoist-non-react-statics": {
|
"@types/hoist-non-react-statics": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
|
||||||
|
@ -38415,27 +38195,6 @@
|
||||||
"redux": "^4.0.0"
|
"redux": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/react-router": {
|
|
||||||
"version": "5.1.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.11.tgz",
|
|
||||||
"integrity": "sha512-ofHbZMlp0Y2baOHgsWBQ4K3AttxY61bDMkwTiBOkPg7U6C/3UwwB5WaIx28JmSVi/eX3uFEMRo61BV22fDQIvg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/history": "*",
|
|
||||||
"@types/react": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@types/react-router-dom": {
|
|
||||||
"version": "5.1.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.7.tgz",
|
|
||||||
"integrity": "sha512-D5mHD6TbdV/DNHYsnwBTv+y73ei+mMjrkGrla86HthE4/PVvL1J94Bu3qABU+COXzpL23T1EZapVVpwHuBXiUg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@types/history": "*",
|
|
||||||
"@types/react": "*",
|
|
||||||
"@types/react-router": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@types/react-tag-autocomplete": {
|
"@types/react-tag-autocomplete": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-tag-autocomplete/-/react-tag-autocomplete-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-tag-autocomplete/-/react-tag-autocomplete-6.1.0.tgz",
|
||||||
|
@ -39224,23 +38983,6 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.10.2",
|
"@babel/runtime": "^7.10.2",
|
||||||
"@babel/runtime-corejs3": "^7.10.2"
|
"@babel/runtime-corejs3": "^7.10.2"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": {
|
|
||||||
"version": "7.13.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.9.tgz",
|
|
||||||
"integrity": "sha512-aY2kU+xgJ3dJ1eU6FMB9EH8dIe8dmusF1xEku52joLvw6eAFN0AI+WxCLDnpev2LEejWBAy2sBvBOBAjI3zmvA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"arr-diff": {
|
"arr-diff": {
|
||||||
|
@ -40062,15 +39804,6 @@
|
||||||
"resolve": "^1.12.0"
|
"resolve": "^1.12.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": {
|
|
||||||
"version": "7.12.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
|
|
||||||
"integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"cosmiconfig": {
|
"cosmiconfig": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
|
||||||
|
@ -40112,12 +39845,6 @@
|
||||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"resolve-from": {
|
"resolve-from": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
|
||||||
|
@ -40980,12 +40707,6 @@
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"regenerator-transform": {
|
"regenerator-transform": {
|
||||||
"version": "0.14.5",
|
"version": "0.14.5",
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
|
||||||
|
@ -44728,26 +44449,11 @@
|
||||||
"language-tags": "^1.0.5"
|
"language-tags": "^1.0.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": {
|
|
||||||
"version": "7.13.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.9.tgz",
|
|
||||||
"integrity": "sha512-aY2kU+xgJ3dJ1eU6FMB9EH8dIe8dmusF1xEku52joLvw6eAFN0AI+WxCLDnpev2LEejWBAy2sBvBOBAjI3zmvA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"emoji-regex": {
|
"emoji-regex": {
|
||||||
"version": "9.2.2",
|
"version": "9.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
||||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -46919,16 +46625,11 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"history": {
|
"history": {
|
||||||
"version": "4.10.1",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/history/-/history-5.2.0.tgz",
|
||||||
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
|
"integrity": "sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.1.2",
|
"@babel/runtime": "^7.7.6"
|
||||||
"loose-envify": "^1.2.0",
|
|
||||||
"resolve-pathname": "^3.0.0",
|
|
||||||
"tiny-invariant": "^1.0.2",
|
|
||||||
"tiny-warning": "^1.0.0",
|
|
||||||
"value-equal": "^1.0.1"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"hmac-drbg": {
|
"hmac-drbg": {
|
||||||
|
@ -49941,30 +49642,6 @@
|
||||||
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
|
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"mini-create-react-context": {
|
|
||||||
"version": "0.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz",
|
|
||||||
"integrity": "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==",
|
|
||||||
"requires": {
|
|
||||||
"@babel/runtime": "^7.5.5",
|
|
||||||
"tiny-warning": "^1.0.3"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": {
|
|
||||||
"version": "7.11.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz",
|
|
||||||
"integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==",
|
|
||||||
"requires": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mini-css-extract-plugin": {
|
"mini-css-extract-plugin": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.1.tgz",
|
||||||
|
@ -51298,6 +50975,7 @@
|
||||||
"version": "1.7.0",
|
"version": "1.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
|
||||||
"integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
|
"integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"isarray": "0.0.1"
|
"isarray": "0.0.1"
|
||||||
},
|
},
|
||||||
|
@ -51305,7 +50983,8 @@
|
||||||
"isarray": {
|
"isarray": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz",
|
"resolved": "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz",
|
||||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
|
||||||
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -55656,12 +55335,6 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"asap": "~2.0.6"
|
"asap": "~2.0.6"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -55972,55 +55645,28 @@
|
||||||
"react-is": "^16.13.1"
|
"react-is": "^16.13.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": {
|
|
||||||
"version": "7.12.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
|
|
||||||
"integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
|
|
||||||
"requires": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"react-is": {
|
"react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
},
|
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-router": {
|
"react-router": {
|
||||||
"version": "5.2.0",
|
"version": "6.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz",
|
||||||
"integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==",
|
"integrity": "sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.1.2",
|
"history": "^5.2.0"
|
||||||
"history": "^4.9.0",
|
|
||||||
"hoist-non-react-statics": "^3.1.0",
|
|
||||||
"loose-envify": "^1.3.1",
|
|
||||||
"mini-create-react-context": "^0.4.0",
|
|
||||||
"path-to-regexp": "^1.7.0",
|
|
||||||
"prop-types": "^15.6.2",
|
|
||||||
"react-is": "^16.6.0",
|
|
||||||
"tiny-invariant": "^1.0.2",
|
|
||||||
"tiny-warning": "^1.0.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-router-dom": {
|
"react-router-dom": {
|
||||||
"version": "5.2.0",
|
"version": "6.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz",
|
||||||
"integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
|
"integrity": "sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.1.2",
|
"history": "^5.2.0",
|
||||||
"history": "^4.9.0",
|
"react-router": "6.2.1"
|
||||||
"loose-envify": "^1.3.1",
|
|
||||||
"prop-types": "^15.6.2",
|
|
||||||
"react-router": "5.2.0",
|
|
||||||
"tiny-invariant": "^1.0.2",
|
|
||||||
"tiny-warning": "^1.0.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-shallow-renderer": {
|
"react-shallow-renderer": {
|
||||||
|
@ -56082,21 +55728,6 @@
|
||||||
"prop-types": "^15.5.8",
|
"prop-types": "^15.5.8",
|
||||||
"react-popper": "^1.3.6",
|
"react-popper": "^1.3.6",
|
||||||
"react-transition-group": "^2.3.1"
|
"react-transition-group": "^2.3.1"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": {
|
|
||||||
"version": "7.13.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.8.tgz",
|
|
||||||
"integrity": "sha512-CwQljpw6qSayc0fRG1soxHAKs1CnQMOChm4mlQP6My0kf9upVGizj/KhlTTgyUnETmHpcUXjaluNAkteRFuafg==",
|
|
||||||
"requires": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"read-pkg": {
|
"read-pkg": {
|
||||||
|
@ -56278,9 +55909,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"regenerator-runtime": {
|
"regenerator-runtime": {
|
||||||
"version": "0.12.1",
|
"version": "0.13.9",
|
||||||
"resolved": "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz",
|
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz",
|
||||||
"integrity": "sha1-+hpxVEdkwDb4xJsToIsllMn4oN4="
|
"integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
|
||||||
},
|
},
|
||||||
"regenerator-transform": {
|
"regenerator-transform": {
|
||||||
"version": "0.14.5",
|
"version": "0.14.5",
|
||||||
|
@ -56289,23 +55920,6 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.8.4"
|
"@babel/runtime": "^7.8.4"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": {
|
|
||||||
"version": "7.13.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.8.tgz",
|
|
||||||
"integrity": "sha512-CwQljpw6qSayc0fRG1soxHAKs1CnQMOChm4mlQP6My0kf9upVGizj/KhlTTgyUnETmHpcUXjaluNAkteRFuafg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"regex-not": {
|
"regex-not": {
|
||||||
|
@ -56672,11 +56286,6 @@
|
||||||
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
|
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"resolve-pathname": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
|
|
||||||
},
|
|
||||||
"resolve-url": {
|
"resolve-url": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
|
||||||
|
@ -59698,16 +59307,6 @@
|
||||||
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
|
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"tiny-invariant": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw=="
|
|
||||||
},
|
|
||||||
"tiny-warning": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
|
|
||||||
},
|
|
||||||
"tinycolor2": {
|
"tinycolor2": {
|
||||||
"version": "1.4.2",
|
"version": "1.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz",
|
||||||
|
@ -60660,11 +60259,6 @@
|
||||||
"spdx-expression-parse": "^3.0.0"
|
"spdx-expression-parse": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"value-equal": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
|
|
||||||
},
|
|
||||||
"vary": {
|
"vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
@ -61689,15 +61283,6 @@
|
||||||
"workbox-window": "^6.1.5"
|
"workbox-window": "^6.1.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": {
|
|
||||||
"version": "7.14.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz",
|
|
||||||
"integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"regenerator-runtime": "^0.13.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fast-json-stable-stringify": {
|
"fast-json-stable-stringify": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||||
|
@ -61710,12 +61295,6 @@
|
||||||
"integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
|
"integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"regenerator-runtime": {
|
|
||||||
"version": "0.13.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
|
||||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"source-map": {
|
"source-map": {
|
||||||
"version": "0.8.0-beta.0",
|
"version": "0.8.0-beta.0",
|
||||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz",
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
"react-external-link": "^1.2.0",
|
"react-external-link": "^1.2.0",
|
||||||
"react-leaflet": "^3.1.0",
|
"react-leaflet": "^3.1.0",
|
||||||
"react-redux": "^7.2.2",
|
"react-redux": "^7.2.2",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^6.2.1",
|
||||||
"react-swipeable": "^6.0.1",
|
"react-swipeable": "^6.0.1",
|
||||||
"react-tag-autocomplete": "^6.1.0",
|
"react-tag-autocomplete": "^6.1.0",
|
||||||
"reactstrap": "^8.9.0",
|
"reactstrap": "^8.9.0",
|
||||||
|
@ -86,7 +86,6 @@
|
||||||
"@types/react-dom": "^17.0.1",
|
"@types/react-dom": "^17.0.1",
|
||||||
"@types/react-leaflet": "^2.5.2",
|
"@types/react-leaflet": "^2.5.2",
|
||||||
"@types/react-redux": "^7.1.16",
|
"@types/react-redux": "^7.1.16",
|
||||||
"@types/react-router-dom": "^5.1.7",
|
|
||||||
"@types/react-tag-autocomplete": "^6.1.0",
|
"@types/react-tag-autocomplete": "^6.1.0",
|
||||||
"@types/uuid": "^8.3.0",
|
"@types/uuid": "^8.3.0",
|
||||||
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
|
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useEffect, FC } from 'react';
|
import { useEffect, FC } from 'react';
|
||||||
import { Route, RouteChildrenProps, Switch } from 'react-router-dom';
|
import { Route, Routes, useLocation } from 'react-router-dom';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import NotFound from '../common/NotFound';
|
import NotFound from '../common/NotFound';
|
||||||
import { ServersMap } from '../servers/data';
|
import { ServersMap } from '../servers/data';
|
||||||
|
@ -9,7 +9,7 @@ import { AppUpdateBanner } from '../common/AppUpdateBanner';
|
||||||
import { forceUpdate } from '../utils/helpers/sw';
|
import { forceUpdate } from '../utils/helpers/sw';
|
||||||
import './App.scss';
|
import './App.scss';
|
||||||
|
|
||||||
interface AppProps extends RouteChildrenProps {
|
interface AppProps {
|
||||||
fetchServers: () => void;
|
fetchServers: () => void;
|
||||||
servers: ServersMap;
|
servers: ServersMap;
|
||||||
settings: Settings;
|
settings: Settings;
|
||||||
|
@ -26,7 +26,8 @@ const App = (
|
||||||
Settings: FC,
|
Settings: FC,
|
||||||
ManageServers: FC,
|
ManageServers: FC,
|
||||||
ShlinkVersionsContainer: FC,
|
ShlinkVersionsContainer: FC,
|
||||||
) => ({ fetchServers, servers, settings, appUpdated, resetAppUpdate, location }: AppProps) => {
|
) => ({ fetchServers, servers, settings, appUpdated, resetAppUpdate }: AppProps) => {
|
||||||
|
const location = useLocation();
|
||||||
const isHome = location.pathname === '/';
|
const isHome = location.pathname === '/';
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -44,15 +45,15 @@ const App = (
|
||||||
|
|
||||||
<div className="app">
|
<div className="app">
|
||||||
<div className={classNames('shlink-wrapper', { 'd-flex d-md-block align-items-center': isHome })}>
|
<div className={classNames('shlink-wrapper', { 'd-flex d-md-block align-items-center': isHome })}>
|
||||||
<Switch>
|
<Routes>
|
||||||
<Route exact path="/" component={Home} />
|
<Route index element={<Home />} />
|
||||||
<Route exact path="/settings" component={Settings} />
|
<Route path="/settings" element={<Settings />} />
|
||||||
<Route exact path="/manage-servers" component={ManageServers} />
|
<Route path="/manage-servers" element={<ManageServers />} />
|
||||||
<Route exact path="/server/create" component={CreateServer} />
|
<Route path="/server/create" element={<CreateServer />} />
|
||||||
<Route exact path="/server/:serverId/edit" component={EditServer} />
|
<Route path="/server/:serverId/edit" element={<EditServer />} />
|
||||||
<Route path="/server/:serverId" component={MenuLayout} />
|
<Route path="/server/:serverId/*" element={<MenuLayout />} />
|
||||||
<Route component={NotFound} />
|
<Route path="*" element={<NotFound />} />
|
||||||
</Switch>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="shlink-footer">
|
<div className="shlink-footer">
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import Bottle, { Decorator } from 'bottlejs';
|
import Bottle from 'bottlejs';
|
||||||
import { appUpdateAvailable, resetAppUpdate } from '../reducers/appUpdates';
|
import { appUpdateAvailable, resetAppUpdate } from '../reducers/appUpdates';
|
||||||
import App from '../App';
|
import App from '../App';
|
||||||
import { ConnectDecorator } from '../../container/types';
|
import { ConnectDecorator } from '../../container/types';
|
||||||
|
|
||||||
const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter: Decorator) => {
|
const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
||||||
// Components
|
// Components
|
||||||
bottle.serviceFactory(
|
bottle.serviceFactory(
|
||||||
'App',
|
'App',
|
||||||
|
@ -18,7 +18,6 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter:
|
||||||
'ShlinkVersionsContainer',
|
'ShlinkVersionsContainer',
|
||||||
);
|
);
|
||||||
bottle.decorator('App', connect([ 'servers', 'settings', 'appUpdated' ], [ 'fetchServers', 'resetAppUpdate' ]));
|
bottle.decorator('App', connect([ 'servers', 'settings', 'appUpdated' ], [ 'fetchServers', 'resetAppUpdate' ]));
|
||||||
bottle.decorator('App', withRouter);
|
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
bottle.serviceFactory('appUpdateAvailable', () => appUpdateAvailable);
|
bottle.serviceFactory('appUpdateAvailable', () => appUpdateAvailable);
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { NavLink, NavLinkProps } from 'react-router-dom';
|
import { NavLink, NavLinkProps } from 'react-router-dom';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Location } from 'history';
|
|
||||||
import { DeleteServerButtonProps } from '../servers/DeleteServerButton';
|
import { DeleteServerButtonProps } from '../servers/DeleteServerButton';
|
||||||
import { isServerWithId, SelectedServer } from '../servers/data';
|
import { isServerWithId, SelectedServer } from '../servers/data';
|
||||||
import { supportsDomainRedirects } from '../utils/helpers/features';
|
import { supportsDomainRedirects } from '../utils/helpers/features';
|
||||||
|
@ -28,8 +27,7 @@ interface AsideMenuItemProps extends NavLinkProps {
|
||||||
|
|
||||||
const AsideMenuItem: FC<AsideMenuItemProps> = ({ children, to, className, ...rest }) => (
|
const AsideMenuItem: FC<AsideMenuItemProps> = ({ children, to, className, ...rest }) => (
|
||||||
<NavLink
|
<NavLink
|
||||||
className={classNames('aside-menu__item', className)}
|
className={({ isActive }) => classNames('aside-menu__item', className, { 'aside-menu__item--selected': isActive })}
|
||||||
activeClassName="aside-menu__item--selected"
|
|
||||||
to={to}
|
to={to}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
|
@ -46,7 +44,8 @@ const AsideMenu = (DeleteServerButton: FC<DeleteServerButtonProps>) => (
|
||||||
const asideClass = classNames('aside-menu', {
|
const asideClass = classNames('aside-menu', {
|
||||||
'aside-menu--hidden': !showOnMobile,
|
'aside-menu--hidden': !showOnMobile,
|
||||||
});
|
});
|
||||||
const shortUrlsIsActive = (_: null, location: Location) => location.pathname.match('/list-short-urls') !== null;
|
// TODO
|
||||||
|
// const shortUrlsIsActive = (_: null, location: Location) => location.pathname.match('/list-short-urls') !== null;
|
||||||
const buildPath = (suffix: string) => `/server/${serverId}${suffix}`;
|
const buildPath = (suffix: string) => `/server/${serverId}${suffix}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -56,7 +55,7 @@ const AsideMenu = (DeleteServerButton: FC<DeleteServerButtonProps>) => (
|
||||||
<FontAwesomeIcon fixedWidth icon={overviewIcon} />
|
<FontAwesomeIcon fixedWidth icon={overviewIcon} />
|
||||||
<span className="aside-menu__item-text">Overview</span>
|
<span className="aside-menu__item-text">Overview</span>
|
||||||
</AsideMenuItem>
|
</AsideMenuItem>
|
||||||
<AsideMenuItem to={buildPath('/list-short-urls/1')} isActive={shortUrlsIsActive}>
|
<AsideMenuItem to={buildPath('/list-short-urls/1')}>
|
||||||
<FontAwesomeIcon fixedWidth icon={listIcon} />
|
<FontAwesomeIcon fixedWidth icon={listIcon} />
|
||||||
<span className="aside-menu__item-text">List short URLs</span>
|
<span className="aside-menu__item-text">List short URLs</span>
|
||||||
</AsideMenuItem>
|
</AsideMenuItem>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { isEmpty, values } from 'ramda';
|
import { isEmpty, values } from 'ramda';
|
||||||
import { Link, RouteChildrenProps } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
import { Card, Row } from 'reactstrap';
|
import { Card, Row } from 'reactstrap';
|
||||||
import { ExternalLink } from 'react-external-link';
|
import { ExternalLink } from 'react-external-link';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
@ -10,11 +10,12 @@ import { ServersMap } from '../servers/data';
|
||||||
import { ShlinkLogo } from './img/ShlinkLogo';
|
import { ShlinkLogo } from './img/ShlinkLogo';
|
||||||
import './Home.scss';
|
import './Home.scss';
|
||||||
|
|
||||||
export interface HomeProps extends RouteChildrenProps {
|
export interface HomeProps {
|
||||||
servers: ServersMap;
|
servers: ServersMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Home = ({ servers, history }: HomeProps) => {
|
const Home = ({ servers }: HomeProps) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
const serversList = values(servers);
|
const serversList = values(servers);
|
||||||
const hasServers = !isEmpty(serversList);
|
const hasServers = !isEmpty(serversList);
|
||||||
|
|
||||||
|
@ -22,7 +23,7 @@ const Home = ({ servers, history }: HomeProps) => {
|
||||||
// Try to redirect to the first server marked as auto-connect
|
// Try to redirect to the first server marked as auto-connect
|
||||||
const autoConnectServer = serversList.find(({ autoConnect }) => autoConnect);
|
const autoConnectServer = serversList.find(({ autoConnect }) => autoConnect);
|
||||||
|
|
||||||
autoConnectServer && history.push(`/server/${autoConnectServer.id}`);
|
autoConnectServer && navigate(`/server/${autoConnectServer.id}`);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import { faChevronDown as arrowIcon, faCogs as cogsIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faChevronDown as arrowIcon, faCogs as cogsIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { FC, useEffect } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link, useLocation } from 'react-router-dom';
|
||||||
import { Collapse, Nav, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } from 'reactstrap';
|
import { Collapse, Nav, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } from 'reactstrap';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { RouteComponentProps } from 'react-router';
|
|
||||||
import { useToggle } from '../utils/helpers/hooks';
|
import { useToggle } from '../utils/helpers/hooks';
|
||||||
import { ShlinkLogo } from './img/ShlinkLogo';
|
import { ShlinkLogo } from './img/ShlinkLogo';
|
||||||
import './MainHeader.scss';
|
import './MainHeader.scss';
|
||||||
|
|
||||||
const MainHeader = (ServersDropdown: FC) => ({ location }: RouteComponentProps) => {
|
const MainHeader = (ServersDropdown: FC) => () => {
|
||||||
const [ isOpen, toggleOpen, , close ] = useToggle();
|
const [ isOpen, toggleOpen, , close ] = useToggle();
|
||||||
|
const location = useLocation();
|
||||||
const { pathname } = location;
|
const { pathname } = location;
|
||||||
|
|
||||||
useEffect(close, [ location ]);
|
useEffect(close, [ location ]);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { FC, useEffect } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
import { Redirect, Route, Switch } from 'react-router-dom';
|
import { Navigate, Route, Routes, useLocation } from 'react-router-dom';
|
||||||
import { faBars as burgerIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faBars as burgerIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
@ -24,7 +24,8 @@ const MenuLayout = (
|
||||||
Overview: FC,
|
Overview: FC,
|
||||||
EditShortUrl: FC,
|
EditShortUrl: FC,
|
||||||
ManageDomains: FC,
|
ManageDomains: FC,
|
||||||
) => withSelectedServer(({ location, selectedServer }) => {
|
) => withSelectedServer(({ selectedServer }) => {
|
||||||
|
const location = useLocation();
|
||||||
const [ sidebarVisible, toggleSidebar, showSidebar, hideSidebar ] = useToggle();
|
const [ sidebarVisible, toggleSidebar, showSidebar, hideSidebar ] = useToggle();
|
||||||
|
|
||||||
useEffect(() => hideSidebar(), [ location ]);
|
useEffect(() => hideSidebar(), [ location ]);
|
||||||
|
@ -48,22 +49,23 @@ const MenuLayout = (
|
||||||
<AsideMenu selectedServer={selectedServer} showOnMobile={sidebarVisible} />
|
<AsideMenu selectedServer={selectedServer} showOnMobile={sidebarVisible} />
|
||||||
<div className="menu-layout__container" onClick={() => hideSidebar()}>
|
<div className="menu-layout__container" onClick={() => hideSidebar()}>
|
||||||
<div className="container-xl">
|
<div className="container-xl">
|
||||||
<Switch>
|
<Routes>
|
||||||
<Redirect exact from="/server/:serverId" to="/server/:serverId/overview" />
|
<Route index element={<Navigate replace to="overview" />} />
|
||||||
<Route exact path="/server/:serverId/overview" component={Overview} />
|
<Route path="/overview" element={<Overview />} />
|
||||||
<Route exact path="/server/:serverId/list-short-urls/:page" component={ShortUrlsList} />
|
<Route path="/list-short-urls/:page" element={<ShortUrlsList />} />
|
||||||
<Route exact path="/server/:serverId/create-short-url" component={CreateShortUrl} />
|
<Route path="/create-short-url" element={<CreateShortUrl />} />
|
||||||
<Route path="/server/:serverId/short-code/:shortCode/visits" component={ShortUrlVisits} />
|
<Route path="/short-code/:shortCode/visits/*" element={<ShortUrlVisits />} />
|
||||||
<Route path="/server/:serverId/short-code/:shortCode/edit" component={EditShortUrl} />
|
<Route path="/short-code/:shortCode/edit" element={<EditShortUrl />} />
|
||||||
<Route path="/server/:serverId/tag/:tag/visits" component={TagVisits} />
|
<Route path="/tag/:tag/visits/*" element={<TagVisits />} />
|
||||||
{addOrphanVisitsRoute && <Route path="/server/:serverId/orphan-visits" component={OrphanVisits} />}
|
{addOrphanVisitsRoute && <Route path="/orphan-visits/*" element={<OrphanVisits />} />}
|
||||||
{addNonOrphanVisitsRoute && <Route path="/server/:serverId/non-orphan-visits" component={NonOrphanVisits} />}
|
{addNonOrphanVisitsRoute && <Route path="/non-orphan-visits/*" element={<NonOrphanVisits />} />}
|
||||||
<Route exact path="/server/:serverId/manage-tags" component={TagsList} />
|
<Route path="/manage-tags" element={<TagsList />} />
|
||||||
{addManageDomainsRoute && <Route exact path="/server/:serverId/manage-domains" component={ManageDomains} />}
|
{addManageDomainsRoute && <Route path="/manage-domains" element={<ManageDomains />} />}
|
||||||
<Route
|
<Route
|
||||||
render={() => <NotFound to={`/server/${selectedServer.id}/list-short-urls/1`}>List short URLs</NotFound>}
|
path="*"
|
||||||
|
element={<NotFound to={`/server/${selectedServer.id}/list-short-urls/1`}>List short URLs</NotFound>}
|
||||||
/>
|
/>
|
||||||
</Switch>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { PropsWithChildren, useEffect } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
import { RouteComponentProps } from 'react-router';
|
import { useLocation } from 'react-router-dom';
|
||||||
|
|
||||||
|
const ScrollToTop = (): FC => ({ children }) => {
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
const ScrollToTop = () => ({ location, children }: PropsWithChildren<RouteComponentProps>) => {
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
scrollTo(0, 0);
|
scrollTo(0, 0);
|
||||||
}, [ location ]);
|
}, [ location ]);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import Bottle, { Decorator } from 'bottlejs';
|
import Bottle from 'bottlejs';
|
||||||
import ScrollToTop from '../ScrollToTop';
|
import ScrollToTop from '../ScrollToTop';
|
||||||
import MainHeader from '../MainHeader';
|
import MainHeader from '../MainHeader';
|
||||||
import Home from '../Home';
|
import Home from '../Home';
|
||||||
|
@ -11,7 +11,7 @@ import { ConnectDecorator } from '../../container/types';
|
||||||
import { withoutSelectedServer } from '../../servers/helpers/withoutSelectedServer';
|
import { withoutSelectedServer } from '../../servers/helpers/withoutSelectedServer';
|
||||||
import { ImageDownloader } from './ImageDownloader';
|
import { ImageDownloader } from './ImageDownloader';
|
||||||
|
|
||||||
const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter: Decorator) => {
|
const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
||||||
// Services
|
// Services
|
||||||
bottle.constant('window', (global as any).window);
|
bottle.constant('window', (global as any).window);
|
||||||
bottle.constant('console', global.console);
|
bottle.constant('console', global.console);
|
||||||
|
@ -21,14 +21,11 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter:
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
bottle.serviceFactory('ScrollToTop', ScrollToTop);
|
bottle.serviceFactory('ScrollToTop', ScrollToTop);
|
||||||
bottle.decorator('ScrollToTop', withRouter);
|
|
||||||
|
|
||||||
bottle.serviceFactory('MainHeader', MainHeader, 'ServersDropdown');
|
bottle.serviceFactory('MainHeader', MainHeader, 'ServersDropdown');
|
||||||
bottle.decorator('MainHeader', withRouter);
|
|
||||||
|
|
||||||
bottle.serviceFactory('Home', () => Home);
|
bottle.serviceFactory('Home', () => Home);
|
||||||
bottle.decorator('Home', withoutSelectedServer);
|
bottle.decorator('Home', withoutSelectedServer);
|
||||||
bottle.decorator('Home', withRouter);
|
|
||||||
bottle.decorator('Home', connect([ 'servers' ], [ 'resetSelectedServer' ]));
|
bottle.decorator('Home', connect([ 'servers' ], [ 'resetSelectedServer' ]));
|
||||||
|
|
||||||
bottle.serviceFactory(
|
bottle.serviceFactory(
|
||||||
|
@ -48,7 +45,6 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter:
|
||||||
'ManageDomains',
|
'ManageDomains',
|
||||||
);
|
);
|
||||||
bottle.decorator('MenuLayout', connect([ 'selectedServer' ], [ 'selectServer' ]));
|
bottle.decorator('MenuLayout', connect([ 'selectedServer' ], [ 'selectServer' ]));
|
||||||
bottle.decorator('MenuLayout', withRouter);
|
|
||||||
|
|
||||||
bottle.serviceFactory('AsideMenu', AsideMenu, 'DeleteServerButton');
|
bottle.serviceFactory('AsideMenu', AsideMenu, 'DeleteServerButton');
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import Bottle, { IContainer } from 'bottlejs';
|
import Bottle, { IContainer } from 'bottlejs';
|
||||||
import { withRouter } from 'react-router-dom';
|
|
||||||
import { connect as reduxConnect } from 'react-redux';
|
import { connect as reduxConnect } from 'react-redux';
|
||||||
import { pick } from 'ramda';
|
import { pick } from 'ramda';
|
||||||
import provideApiServices from '../api/services/provideServices';
|
import provideApiServices from '../api/services/provideServices';
|
||||||
|
@ -34,11 +33,11 @@ const connect: ConnectDecorator = (propsFromState: string[] | null, actionServic
|
||||||
actionServiceNames.reduce(mapActionService, {}),
|
actionServiceNames.reduce(mapActionService, {}),
|
||||||
);
|
);
|
||||||
|
|
||||||
provideAppServices(bottle, connect, withRouter);
|
provideAppServices(bottle, connect);
|
||||||
provideCommonServices(bottle, connect, withRouter);
|
provideCommonServices(bottle, connect);
|
||||||
provideApiServices(bottle);
|
provideApiServices(bottle);
|
||||||
provideShortUrlsServices(bottle, connect, withRouter);
|
provideShortUrlsServices(bottle, connect);
|
||||||
provideServersServices(bottle, connect, withRouter);
|
provideServersServices(bottle, connect);
|
||||||
provideTagsServices(bottle, connect);
|
provideTagsServices(bottle, connect);
|
||||||
provideVisitsServices(bottle, connect);
|
provideVisitsServices(bottle, connect);
|
||||||
provideUtilsServices(bottle);
|
provideUtilsServices(bottle);
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { pipe } from 'ramda';
|
||||||
import { CreateVisit } from '../../visits/types';
|
import { CreateVisit } from '../../visits/types';
|
||||||
import { MercureInfo } from '../reducers/mercureInfo';
|
import { MercureInfo } from '../reducers/mercureInfo';
|
||||||
import { bindToMercureTopic } from './index';
|
import { bindToMercureTopic } from './index';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
|
|
||||||
export interface MercureBoundProps {
|
export interface MercureBoundProps {
|
||||||
createNewVisits: (createdVisits: CreateVisit[]) => void;
|
createNewVisits: (createdVisits: CreateVisit[]) => void;
|
||||||
|
@ -12,17 +13,19 @@ export interface MercureBoundProps {
|
||||||
|
|
||||||
export function boundToMercureHub<T = {}>(
|
export function boundToMercureHub<T = {}>(
|
||||||
WrappedComponent: FC<MercureBoundProps & T>,
|
WrappedComponent: FC<MercureBoundProps & T>,
|
||||||
getTopicsForProps: (props: T) => string[],
|
getTopicsForProps: (props: T, routeParams: any) => string[],
|
||||||
) {
|
) {
|
||||||
const pendingUpdates = new Set<CreateVisit>();
|
const pendingUpdates = new Set<CreateVisit>();
|
||||||
|
|
||||||
return (props: MercureBoundProps & T) => {
|
return (props: MercureBoundProps & T) => {
|
||||||
const { createNewVisits, loadMercureInfo, mercureInfo } = props;
|
const { createNewVisits, loadMercureInfo, mercureInfo } = props;
|
||||||
const { interval } = mercureInfo;
|
const { interval } = mercureInfo;
|
||||||
|
const params = useParams();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const onMessage = (visit: CreateVisit) => interval ? pendingUpdates.add(visit) : createNewVisits([ visit ]);
|
const onMessage = (visit: CreateVisit) => interval ? pendingUpdates.add(visit) : createNewVisits([ visit ]);
|
||||||
const closeEventSource = bindToMercureTopic(mercureInfo, getTopicsForProps(props), onMessage, loadMercureInfo);
|
const topics = getTopicsForProps(props, params);
|
||||||
|
const closeEventSource = bindToMercureTopic(mercureInfo, topics, onMessage, loadMercureInfo);
|
||||||
|
|
||||||
if (!interval) {
|
if (!interval) {
|
||||||
return closeEventSource;
|
return closeEventSource;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { RouterProps } from 'react-router';
|
|
||||||
import { Button } from 'reactstrap';
|
import { Button } from 'reactstrap';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Result } from '../utils/Result';
|
import { Result } from '../utils/Result';
|
||||||
import { NoMenuLayout } from '../common/NoMenuLayout';
|
import { NoMenuLayout } from '../common/NoMenuLayout';
|
||||||
import { StateFlagTimeout, useToggle } from '../utils/helpers/hooks';
|
import { StateFlagTimeout, useGoBack, useToggle } from '../utils/helpers/hooks';
|
||||||
import { ServerForm } from './helpers/ServerForm';
|
import { ServerForm } from './helpers/ServerForm';
|
||||||
import { ImportServersBtnProps } from './helpers/ImportServersBtn';
|
import { ImportServersBtnProps } from './helpers/ImportServersBtn';
|
||||||
import { ServerData, ServersMap, ServerWithId } from './data';
|
import { ServerData, ServersMap, ServerWithId } from './data';
|
||||||
|
@ -12,7 +12,7 @@ import { DuplicatedServersModal } from './helpers/DuplicatedServersModal';
|
||||||
|
|
||||||
const SHOW_IMPORT_MSG_TIME = 4000;
|
const SHOW_IMPORT_MSG_TIME = 4000;
|
||||||
|
|
||||||
interface CreateServerProps extends RouterProps {
|
interface CreateServerProps {
|
||||||
createServer: (server: ServerWithId) => void;
|
createServer: (server: ServerWithId) => void;
|
||||||
servers: ServersMap;
|
servers: ServersMap;
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,10 @@ const ImportResult = ({ type }: { type: 'error' | 'success' }) => (
|
||||||
);
|
);
|
||||||
|
|
||||||
const CreateServer = (ImportServersBtn: FC<ImportServersBtnProps>, useStateFlagTimeout: StateFlagTimeout) => (
|
const CreateServer = (ImportServersBtn: FC<ImportServersBtnProps>, useStateFlagTimeout: StateFlagTimeout) => (
|
||||||
{ servers, createServer, history: { push, goBack } }: CreateServerProps,
|
{ servers, createServer }: CreateServerProps,
|
||||||
) => {
|
) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const goBack = useGoBack();
|
||||||
const hasServers = !!Object.keys(servers).length;
|
const hasServers = !!Object.keys(servers).length;
|
||||||
const [ serversImported, setServersImported ] = useStateFlagTimeout(false, SHOW_IMPORT_MSG_TIME);
|
const [ serversImported, setServersImported ] = useStateFlagTimeout(false, SHOW_IMPORT_MSG_TIME);
|
||||||
const [ errorImporting, setErrorImporting ] = useStateFlagTimeout(false, SHOW_IMPORT_MSG_TIME);
|
const [ errorImporting, setErrorImporting ] = useStateFlagTimeout(false, SHOW_IMPORT_MSG_TIME);
|
||||||
|
@ -42,7 +44,7 @@ const CreateServer = (ImportServersBtn: FC<ImportServersBtnProps>, useStateFlagT
|
||||||
const id = uuid();
|
const id = uuid();
|
||||||
|
|
||||||
createServer({ ...serverData, id });
|
createServer({ ...serverData, id });
|
||||||
push(`/server/${id}`);
|
navigate(`/server/${id}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
||||||
import { RouterProps } from 'react-router';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { ServerWithId } from './data';
|
import { ServerWithId } from './data';
|
||||||
|
|
||||||
export interface DeleteServerModalProps {
|
export interface DeleteServerModalProps {
|
||||||
|
@ -10,17 +10,18 @@ export interface DeleteServerModalProps {
|
||||||
redirectHome?: boolean;
|
redirectHome?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DeleteServerModalConnectProps extends DeleteServerModalProps, RouterProps {
|
interface DeleteServerModalConnectProps extends DeleteServerModalProps {
|
||||||
deleteServer: (server: ServerWithId) => void;
|
deleteServer: (server: ServerWithId) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DeleteServerModal: FC<DeleteServerModalConnectProps> = (
|
const DeleteServerModal: FC<DeleteServerModalConnectProps> = (
|
||||||
{ server, toggle, isOpen, deleteServer, history, redirectHome = true },
|
{ server, toggle, isOpen, deleteServer, redirectHome = true },
|
||||||
) => {
|
) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
const closeModal = () => {
|
const closeModal = () => {
|
||||||
deleteServer(server);
|
deleteServer(server);
|
||||||
toggle();
|
toggle();
|
||||||
redirectHome && history.push('/');
|
redirectHome && navigate('/');
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { Button } from 'reactstrap';
|
import { Button } from 'reactstrap';
|
||||||
import { NoMenuLayout } from '../common/NoMenuLayout';
|
import { NoMenuLayout } from '../common/NoMenuLayout';
|
||||||
|
import { useGoBack } from '../utils/helpers/hooks';
|
||||||
import { ServerForm } from './helpers/ServerForm';
|
import { ServerForm } from './helpers/ServerForm';
|
||||||
import { withSelectedServer } from './helpers/withSelectedServer';
|
import { withSelectedServer } from './helpers/withSelectedServer';
|
||||||
import { isServerWithId, ServerData } from './data';
|
import { isServerWithId, ServerData } from './data';
|
||||||
|
@ -9,9 +10,9 @@ interface EditServerProps {
|
||||||
editServer: (serverId: string, serverData: ServerData) => void;
|
editServer: (serverId: string, serverData: ServerData) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EditServer = (ServerError: FC) => withSelectedServer<EditServerProps>((
|
export const EditServer = (ServerError: FC) => withSelectedServer<EditServerProps>(({ editServer, selectedServer }) => {
|
||||||
{ editServer, selectedServer, history: { goBack } },
|
const goBack = useGoBack();
|
||||||
) => {
|
|
||||||
if (!isServerWithId(selectedServer)) {
|
if (!isServerWithId(selectedServer)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { FC, useEffect } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
import { Card, CardBody, CardHeader, Row } from 'reactstrap';
|
import { Card, CardBody, CardHeader, Row } from 'reactstrap';
|
||||||
import { Link, useHistory } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
import { ITEMS_IN_OVERVIEW_PAGE, ShortUrlsList as ShortUrlsListState } from '../short-urls/reducers/shortUrlsList';
|
import { ITEMS_IN_OVERVIEW_PAGE, ShortUrlsList as ShortUrlsListState } from '../short-urls/reducers/shortUrlsList';
|
||||||
import { prettify } from '../utils/helpers/numbers';
|
import { prettify } from '../utils/helpers/numbers';
|
||||||
import { TagsList } from '../tags/reducers/tagsList';
|
import { TagsList } from '../tags/reducers/tagsList';
|
||||||
|
@ -44,7 +44,7 @@ export const Overview = (
|
||||||
const serverId = getServerId(selectedServer);
|
const serverId = getServerId(selectedServer);
|
||||||
const linkToOrphanVisits = supportsOrphanVisits(selectedServer);
|
const linkToOrphanVisits = supportsOrphanVisits(selectedServer);
|
||||||
const linkToNonOrphanVisits = supportsNonOrphanVisits(selectedServer);
|
const linkToNonOrphanVisits = supportsNonOrphanVisits(selectedServer);
|
||||||
const history = useHistory();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
listShortUrls({ itemsPerPage: ITEMS_IN_OVERVIEW_PAGE, orderBy: { field: 'dateCreated', dir: 'DESC' } });
|
listShortUrls({ itemsPerPage: ITEMS_IN_OVERVIEW_PAGE, orderBy: { field: 'dateCreated', dir: 'DESC' } });
|
||||||
|
@ -103,7 +103,7 @@ export const Overview = (
|
||||||
shortUrlsList={shortUrlsList}
|
shortUrlsList={shortUrlsList}
|
||||||
selectedServer={selectedServer}
|
selectedServer={selectedServer}
|
||||||
className="mb-0"
|
className="mb-0"
|
||||||
onTagClick={(tag) => history.push(`/server/${serverId}/list-short-urls/1?tags=${encodeURIComponent(tag)}`)}
|
onTagClick={(tag) => navigate(`/server/${serverId}/list-short-urls/1?tags=${encodeURIComponent(tag)}`)}
|
||||||
/>
|
/>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
@ -1,21 +1,22 @@
|
||||||
import { FC, useEffect } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
import { RouteComponentProps } from 'react-router';
|
import { useParams } from 'react-router-dom';
|
||||||
import Message from '../../utils/Message';
|
import Message from '../../utils/Message';
|
||||||
import { isNotFoundServer, SelectedServer } from '../data';
|
import { isNotFoundServer, SelectedServer } from '../data';
|
||||||
import { NoMenuLayout } from '../../common/NoMenuLayout';
|
import { NoMenuLayout } from '../../common/NoMenuLayout';
|
||||||
|
|
||||||
interface WithSelectedServerProps extends RouteComponentProps<{ serverId: string }> {
|
interface WithSelectedServerProps {
|
||||||
selectServer: (serverId: string) => void;
|
selectServer: (serverId: string) => void;
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function withSelectedServer<T = {}>(WrappedComponent: FC<WithSelectedServerProps & T>, ServerError: FC) {
|
export function withSelectedServer<T = {}>(WrappedComponent: FC<WithSelectedServerProps & T>, ServerError: FC) {
|
||||||
return (props: WithSelectedServerProps & T) => {
|
return (props: WithSelectedServerProps & T) => {
|
||||||
const { selectServer, selectedServer, match } = props;
|
const params = useParams<{ serverId: string }>();
|
||||||
|
const { selectServer, selectedServer } = props;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
selectServer(match.params.serverId);
|
params.serverId && selectServer(params.serverId);
|
||||||
}, [ match.params.serverId ]);
|
}, [ params.serverId ]);
|
||||||
|
|
||||||
if (!selectedServer) {
|
if (!selectedServer) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import csvjson from 'csvjson';
|
import csvjson from 'csvjson';
|
||||||
import Bottle, { Decorator } from 'bottlejs';
|
import Bottle from 'bottlejs';
|
||||||
import CreateServer from '../CreateServer';
|
import CreateServer from '../CreateServer';
|
||||||
import ServersDropdown from '../ServersDropdown';
|
import ServersDropdown from '../ServersDropdown';
|
||||||
import DeleteServerModal from '../DeleteServerModal';
|
import DeleteServerModal from '../DeleteServerModal';
|
||||||
|
@ -20,7 +20,7 @@ import { ManageServersRowDropdown } from '../ManageServersRowDropdown';
|
||||||
import { ServersImporter } from './ServersImporter';
|
import { ServersImporter } from './ServersImporter';
|
||||||
import ServersExporter from './ServersExporter';
|
import ServersExporter from './ServersExporter';
|
||||||
|
|
||||||
const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter: Decorator) => {
|
const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
||||||
// Components
|
// Components
|
||||||
bottle.serviceFactory(
|
bottle.serviceFactory(
|
||||||
'ManageServers',
|
'ManageServers',
|
||||||
|
@ -48,7 +48,6 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter:
|
||||||
bottle.decorator('ServersDropdown', connect([ 'servers', 'selectedServer' ]));
|
bottle.decorator('ServersDropdown', connect([ 'servers', 'selectedServer' ]));
|
||||||
|
|
||||||
bottle.serviceFactory('DeleteServerModal', () => DeleteServerModal);
|
bottle.serviceFactory('DeleteServerModal', () => DeleteServerModal);
|
||||||
bottle.decorator('DeleteServerModal', withRouter);
|
|
||||||
bottle.decorator('DeleteServerModal', connect(null, [ 'deleteServer' ]));
|
bottle.decorator('DeleteServerModal', connect(null, [ 'deleteServer' ]));
|
||||||
|
|
||||||
bottle.serviceFactory('DeleteServerButton', DeleteServerButton, 'DeleteServerModal');
|
bottle.serviceFactory('DeleteServerButton', DeleteServerButton, 'DeleteServerModal');
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { FC, useEffect, useMemo } from 'react';
|
import { FC, useEffect, useMemo } from 'react';
|
||||||
import { RouteComponentProps } from 'react-router';
|
|
||||||
import { Button, Card } from 'reactstrap';
|
import { Button, Card } from 'reactstrap';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faArrowLeft } from '@fortawesome/free-solid-svg-icons';
|
import { faArrowLeft } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { ExternalLink } from 'react-external-link';
|
import { ExternalLink } from 'react-external-link';
|
||||||
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
import { SelectedServer } from '../servers/data';
|
import { SelectedServer } from '../servers/data';
|
||||||
import { Settings, ShortUrlCreationSettings } from '../settings/reducers/settings';
|
import { Settings, ShortUrlCreationSettings } from '../settings/reducers/settings';
|
||||||
import { OptionalString } from '../utils/utils';
|
import { OptionalString } from '../utils/utils';
|
||||||
|
@ -11,13 +11,13 @@ import { parseQuery } from '../utils/helpers/query';
|
||||||
import Message from '../utils/Message';
|
import Message from '../utils/Message';
|
||||||
import { Result } from '../utils/Result';
|
import { Result } from '../utils/Result';
|
||||||
import { ShlinkApiError } from '../api/ShlinkApiError';
|
import { ShlinkApiError } from '../api/ShlinkApiError';
|
||||||
import { useToggle } from '../utils/helpers/hooks';
|
import { useGoBack, useToggle } from '../utils/helpers/hooks';
|
||||||
import { ShortUrlFormProps } from './ShortUrlForm';
|
import { ShortUrlFormProps } from './ShortUrlForm';
|
||||||
import { ShortUrlDetail } from './reducers/shortUrlDetail';
|
import { ShortUrlDetail } from './reducers/shortUrlDetail';
|
||||||
import { EditShortUrlData, ShortUrl, ShortUrlData } from './data';
|
import { EditShortUrlData, ShortUrl, ShortUrlData } from './data';
|
||||||
import { ShortUrlEdition } from './reducers/shortUrlEdition';
|
import { ShortUrlEdition } from './reducers/shortUrlEdition';
|
||||||
|
|
||||||
interface EditShortUrlConnectProps extends RouteComponentProps<{ shortCode: string }> {
|
interface EditShortUrlConnectProps {
|
||||||
settings: Settings;
|
settings: Settings;
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
shortUrlDetail: ShortUrlDetail;
|
shortUrlDetail: ShortUrlDetail;
|
||||||
|
@ -48,9 +48,6 @@ const getInitialState = (shortUrl?: ShortUrl, settings?: ShortUrlCreationSetting
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EditShortUrl = (ShortUrlForm: FC<ShortUrlFormProps>) => ({
|
export const EditShortUrl = (ShortUrlForm: FC<ShortUrlFormProps>) => ({
|
||||||
history: { goBack },
|
|
||||||
match: { params },
|
|
||||||
location: { search },
|
|
||||||
settings: { shortUrlCreation: shortUrlCreationSettings },
|
settings: { shortUrlCreation: shortUrlCreationSettings },
|
||||||
selectedServer,
|
selectedServer,
|
||||||
shortUrlDetail,
|
shortUrlDetail,
|
||||||
|
@ -58,6 +55,9 @@ export const EditShortUrl = (ShortUrlForm: FC<ShortUrlFormProps>) => ({
|
||||||
shortUrlEdition,
|
shortUrlEdition,
|
||||||
editShortUrl,
|
editShortUrl,
|
||||||
}: EditShortUrlConnectProps) => {
|
}: EditShortUrlConnectProps) => {
|
||||||
|
const { search } = useLocation();
|
||||||
|
const params = useParams<{ shortCode: string }>();
|
||||||
|
const goBack = useGoBack();
|
||||||
const { loading, error, errorData, shortUrl } = shortUrlDetail;
|
const { loading, error, errorData, shortUrl } = shortUrlDetail;
|
||||||
const { saving, error: savingError, errorData: savingErrorData } = shortUrlEdition;
|
const { saving, error: savingError, errorData: savingErrorData } = shortUrlEdition;
|
||||||
const { domain } = parseQuery<{ domain?: string }>(search);
|
const { domain } = parseQuery<{ domain?: string }>(search);
|
||||||
|
@ -68,7 +68,7 @@ export const EditShortUrl = (ShortUrlForm: FC<ShortUrlFormProps>) => ({
|
||||||
const [ savingSucceeded,, isSuccessful, isNotSuccessful ] = useToggle();
|
const [ savingSucceeded,, isSuccessful, isNotSuccessful ] = useToggle();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getShortUrlDetail(params.shortCode, domain);
|
params.shortCode && getShortUrlDetail(params.shortCode, domain);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
|
|
|
@ -2,22 +2,19 @@ import { faTags as tagsIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { isEmpty, pipe } from 'ramda';
|
import { isEmpty, pipe } from 'ramda';
|
||||||
import { parseISO } from 'date-fns';
|
import { parseISO } from 'date-fns';
|
||||||
import { RouteChildrenProps } from 'react-router-dom';
|
|
||||||
import SearchField from '../utils/SearchField';
|
import SearchField from '../utils/SearchField';
|
||||||
import Tag from '../tags/helpers/Tag';
|
import Tag from '../tags/helpers/Tag';
|
||||||
import { DateRangeSelector } from '../utils/dates/DateRangeSelector';
|
import { DateRangeSelector } from '../utils/dates/DateRangeSelector';
|
||||||
import { formatIsoDate } from '../utils/helpers/date';
|
import { formatIsoDate } from '../utils/helpers/date';
|
||||||
import ColorGenerator from '../utils/services/ColorGenerator';
|
import ColorGenerator from '../utils/services/ColorGenerator';
|
||||||
import { DateRange } from '../utils/dates/types';
|
import { DateRange } from '../utils/dates/types';
|
||||||
import { ShortUrlListRouteParams, useShortUrlsQuery } from './helpers/hooks';
|
import { useShortUrlsQuery } from './helpers/hooks';
|
||||||
import './ShortUrlsFilteringBar.scss';
|
import './ShortUrlsFilteringBar.scss';
|
||||||
|
|
||||||
export type ShortUrlsFilteringProps = RouteChildrenProps<ShortUrlListRouteParams>;
|
|
||||||
|
|
||||||
const dateOrNull = (date?: string) => date ? parseISO(date) : null;
|
const dateOrNull = (date?: string) => date ? parseISO(date) : null;
|
||||||
|
|
||||||
const ShortUrlsFilteringBar = (colorGenerator: ColorGenerator) => (props: ShortUrlsFilteringProps) => {
|
const ShortUrlsFilteringBar = (colorGenerator: ColorGenerator) => () => {
|
||||||
const [{ search, tags, startDate, endDate }, toFirstPage ] = useShortUrlsQuery(props);
|
const [{ search, tags, startDate, endDate }, toFirstPage ] = useShortUrlsQuery();
|
||||||
const selectedTags = tags?.split(',') ?? [];
|
const selectedTags = tags?.split(',') ?? [];
|
||||||
const setDates = pipe(
|
const setDates = pipe(
|
||||||
({ startDate, endDate }: DateRange) => ({
|
({ startDate, endDate }: DateRange) => ({
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { pipe } from 'ramda';
|
import { pipe } from 'ramda';
|
||||||
import { FC, useEffect, useMemo, useState } from 'react';
|
import { FC, useEffect, useMemo, useState } from 'react';
|
||||||
import { RouteComponentProps } from 'react-router';
|
|
||||||
import { Card } from 'reactstrap';
|
import { Card } from 'reactstrap';
|
||||||
|
import { useParams } from 'react-router-dom';
|
||||||
import { OrderingDropdown } from '../utils/OrderingDropdown';
|
import { OrderingDropdown } from '../utils/OrderingDropdown';
|
||||||
import { determineOrderDir, OrderDir } from '../utils/helpers/ordering';
|
import { determineOrderDir, OrderDir } from '../utils/helpers/ordering';
|
||||||
import { getServerId, SelectedServer } from '../servers/data';
|
import { getServerId, SelectedServer } from '../servers/data';
|
||||||
|
@ -13,10 +13,10 @@ import { DEFAULT_SHORT_URLS_ORDERING, Settings } from '../settings/reducers/sett
|
||||||
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
|
import { ShortUrlsList as ShortUrlsListState } from './reducers/shortUrlsList';
|
||||||
import { ShortUrlsTableProps } from './ShortUrlsTable';
|
import { ShortUrlsTableProps } from './ShortUrlsTable';
|
||||||
import Paginator from './Paginator';
|
import Paginator from './Paginator';
|
||||||
import { ShortUrlListRouteParams, useShortUrlsQuery } from './helpers/hooks';
|
import { useShortUrlsQuery } from './helpers/hooks';
|
||||||
import { ShortUrlsOrderableFields, SHORT_URLS_ORDERABLE_FIELDS } from './data';
|
import { ShortUrlsOrderableFields, SHORT_URLS_ORDERABLE_FIELDS } from './data';
|
||||||
|
|
||||||
interface ShortUrlsListProps extends RouteComponentProps<ShortUrlListRouteParams> {
|
interface ShortUrlsListProps {
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
shortUrlsList: ShortUrlsListState;
|
shortUrlsList: ShortUrlsListState;
|
||||||
listShortUrls: (params: ShlinkShortUrlsListParams) => void;
|
listShortUrls: (params: ShlinkShortUrlsListParams) => void;
|
||||||
|
@ -25,15 +25,13 @@ interface ShortUrlsListProps extends RouteComponentProps<ShortUrlListRouteParams
|
||||||
|
|
||||||
const ShortUrlsList = (ShortUrlsTable: FC<ShortUrlsTableProps>, ShortUrlsFilteringBar: FC) => boundToMercureHub(({
|
const ShortUrlsList = (ShortUrlsTable: FC<ShortUrlsTableProps>, ShortUrlsFilteringBar: FC) => boundToMercureHub(({
|
||||||
listShortUrls,
|
listShortUrls,
|
||||||
match,
|
|
||||||
location,
|
|
||||||
history,
|
|
||||||
shortUrlsList,
|
shortUrlsList,
|
||||||
selectedServer,
|
selectedServer,
|
||||||
settings,
|
settings,
|
||||||
}: ShortUrlsListProps) => {
|
}: ShortUrlsListProps) => {
|
||||||
const serverId = getServerId(selectedServer);
|
const serverId = getServerId(selectedServer);
|
||||||
const [{ tags, search, startDate, endDate, orderBy }, toFirstPage ] = useShortUrlsQuery({ history, match, location });
|
const { page } = useParams();
|
||||||
|
const [{ tags, search, startDate, endDate, orderBy }, toFirstPage ] = useShortUrlsQuery();
|
||||||
const [ actualOrderBy, setActualOrderBy ] = useState(
|
const [ actualOrderBy, setActualOrderBy ] = useState(
|
||||||
// This separated state handling is needed to be able to fall back to settings value, but only once when loaded
|
// This separated state handling is needed to be able to fall back to settings value, but only once when loaded
|
||||||
orderBy ?? settings.shortUrlsList?.defaultOrdering ?? DEFAULT_SHORT_URLS_ORDERING,
|
orderBy ?? settings.shortUrlsList?.defaultOrdering ?? DEFAULT_SHORT_URLS_ORDERING,
|
||||||
|
@ -55,14 +53,14 @@ const ShortUrlsList = (ShortUrlsTable: FC<ShortUrlsTableProps>, ShortUrlsFilteri
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
listShortUrls({
|
listShortUrls({
|
||||||
page: match.params.page,
|
page,
|
||||||
searchTerm: search,
|
searchTerm: search,
|
||||||
tags: selectedTags,
|
tags: selectedTags,
|
||||||
startDate,
|
startDate,
|
||||||
endDate,
|
endDate,
|
||||||
orderBy: actualOrderBy,
|
orderBy: actualOrderBy,
|
||||||
});
|
});
|
||||||
}, [ match.params.page, search, selectedTags, startDate, endDate, actualOrderBy ]);
|
}, [ page, search, selectedTags, startDate, endDate, actualOrderBy ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import { RouteChildrenProps } from 'react-router-dom';
|
import { useParams, useLocation, useNavigate } from 'react-router-dom';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { isEmpty, pipe } from 'ramda';
|
import { isEmpty, pipe } from 'ramda';
|
||||||
import { parseQuery, stringifyQuery } from '../../utils/helpers/query';
|
import { parseQuery, stringifyQuery } from '../../utils/helpers/query';
|
||||||
import { ShortUrlsOrder, ShortUrlsOrderableFields } from '../data';
|
import { ShortUrlsOrder, ShortUrlsOrderableFields } from '../data';
|
||||||
import { orderToString, stringToOrder } from '../../utils/helpers/ordering';
|
import { orderToString, stringToOrder } from '../../utils/helpers/ordering';
|
||||||
|
|
||||||
type ServerIdRouteProps = RouteChildrenProps<{ serverId: string }>;
|
|
||||||
type ToFirstPage = (extra: Partial<ShortUrlsFiltering>) => void;
|
type ToFirstPage = (extra: Partial<ShortUrlsFiltering>) => void;
|
||||||
|
|
||||||
export interface ShortUrlListRouteParams {
|
export interface ShortUrlListRouteParams {
|
||||||
|
@ -28,9 +27,11 @@ interface ShortUrlsFiltering extends ShortUrlsQueryCommon {
|
||||||
orderBy?: ShortUrlsOrder;
|
orderBy?: ShortUrlsOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useShortUrlsQuery = (
|
export const useShortUrlsQuery = (): [ShortUrlsFiltering, ToFirstPage] => {
|
||||||
{ history, location, match }: ServerIdRouteProps,
|
const navigate = useNavigate();
|
||||||
): [ShortUrlsFiltering, ToFirstPage] => {
|
const location = useLocation();
|
||||||
|
const params = useParams<{ serverId: string }>();
|
||||||
|
|
||||||
const query = useMemo(
|
const query = useMemo(
|
||||||
pipe(
|
pipe(
|
||||||
() => parseQuery<ShortUrlsQuery>(location.search),
|
() => parseQuery<ShortUrlsQuery>(location.search),
|
||||||
|
@ -47,7 +48,7 @@ export const useShortUrlsQuery = (
|
||||||
const evolvedQuery = stringifyQuery(normalizedQuery);
|
const evolvedQuery = stringifyQuery(normalizedQuery);
|
||||||
const queryString = isEmpty(evolvedQuery) ? '' : `?${evolvedQuery}`;
|
const queryString = isEmpty(evolvedQuery) ? '' : `?${evolvedQuery}`;
|
||||||
|
|
||||||
history.push(`/server/${match?.params.serverId}/list-short-urls/1${queryString}`);
|
navigate(`/server/${params.serverId}/list-short-urls/1${queryString}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
return [ query, toFirstPageWithExtra ];
|
return [ query, toFirstPageWithExtra ];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Bottle, { Decorator } from 'bottlejs';
|
import Bottle from 'bottlejs';
|
||||||
import ShortUrlsFilteringBar from '../ShortUrlsFilteringBar';
|
import ShortUrlsFilteringBar from '../ShortUrlsFilteringBar';
|
||||||
import ShortUrlsList from '../ShortUrlsList';
|
import ShortUrlsList from '../ShortUrlsList';
|
||||||
import ShortUrlsRow from '../helpers/ShortUrlsRow';
|
import ShortUrlsRow from '../helpers/ShortUrlsRow';
|
||||||
|
@ -17,7 +17,7 @@ import { ShortUrlForm } from '../ShortUrlForm';
|
||||||
import { EditShortUrl } from '../EditShortUrl';
|
import { EditShortUrl } from '../EditShortUrl';
|
||||||
import { getShortUrlDetail } from '../reducers/shortUrlDetail';
|
import { getShortUrlDetail } from '../reducers/shortUrlDetail';
|
||||||
|
|
||||||
const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter: Decorator) => {
|
const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
||||||
// Components
|
// Components
|
||||||
bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsTable', 'ShortUrlsFilteringBar');
|
bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsTable', 'ShortUrlsFilteringBar');
|
||||||
bottle.decorator('ShortUrlsList', connect(
|
bottle.decorator('ShortUrlsList', connect(
|
||||||
|
@ -49,9 +49,7 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator, withRouter:
|
||||||
bottle.serviceFactory('QrCodeModal', QrCodeModal, 'ImageDownloader', 'ForServerVersion');
|
bottle.serviceFactory('QrCodeModal', QrCodeModal, 'ImageDownloader', 'ForServerVersion');
|
||||||
bottle.decorator('QrCodeModal', connect([ 'selectedServer' ]));
|
bottle.decorator('QrCodeModal', connect([ 'selectedServer' ]));
|
||||||
|
|
||||||
// Services
|
|
||||||
bottle.serviceFactory('ShortUrlsFilteringBar', ShortUrlsFilteringBar, 'ColorGenerator');
|
bottle.serviceFactory('ShortUrlsFilteringBar', ShortUrlsFilteringBar, 'ColorGenerator');
|
||||||
bottle.decorator('ShortUrlsFilteringBar', withRouter);
|
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
bottle.serviceFactory('listShortUrls', listShortUrls, 'buildShlinkApiClient');
|
bottle.serviceFactory('listShortUrls', listShortUrls, 'buildShlinkApiClient');
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { FC, useEffect, useRef } from 'react';
|
import { FC, useEffect, useRef } from 'react';
|
||||||
import { splitEvery } from 'ramda';
|
import { splitEvery } from 'ramda';
|
||||||
import { RouteChildrenProps } from 'react-router';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { SimpleCard } from '../utils/SimpleCard';
|
import { SimpleCard } from '../utils/SimpleCard';
|
||||||
import SimplePaginator from '../common/SimplePaginator';
|
import SimplePaginator from '../common/SimplePaginator';
|
||||||
import { useQueryState } from '../utils/helpers/hooks';
|
import { useQueryState } from '../utils/helpers/hooks';
|
||||||
|
@ -18,10 +18,11 @@ export interface TagsTableProps extends TagsListChildrenProps {
|
||||||
const TAGS_PER_PAGE = 20; // TODO Allow customizing this value in settings
|
const TAGS_PER_PAGE = 20; // TODO Allow customizing this value in settings
|
||||||
|
|
||||||
export const TagsTable = (TagsTableRow: FC<TagsTableRowProps>) => (
|
export const TagsTable = (TagsTableRow: FC<TagsTableRowProps>) => (
|
||||||
{ sortedTags, selectedServer, location, orderByColumn, currentOrder }: TagsTableProps & RouteChildrenProps,
|
{ sortedTags, selectedServer, orderByColumn, currentOrder }: TagsTableProps,
|
||||||
) => {
|
) => {
|
||||||
const isFirstLoad = useRef(true);
|
const isFirstLoad = useRef(true);
|
||||||
const { page: pageFromQuery = 1 } = parseQuery<{ page?: number | string }>(location.search);
|
const { search } = useLocation();
|
||||||
|
const { page: pageFromQuery = 1 } = parseQuery<{ page?: number | string }>(search);
|
||||||
const [ page, setPage ] = useQueryState<number>('page', Number(pageFromQuery));
|
const [ page, setPage ] = useQueryState<number>('page', Number(pageFromQuery));
|
||||||
const pages = splitEvery(TAGS_PER_PAGE, sortedTags);
|
const pages = splitEvery(TAGS_PER_PAGE, sortedTags);
|
||||||
const showPaginator = pages.length > 1;
|
const showPaginator = pages.length > 1;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import Bottle, { IContainer } from 'bottlejs';
|
import Bottle, { IContainer } from 'bottlejs';
|
||||||
import { withRouter } from 'react-router-dom';
|
|
||||||
import TagsSelector from '../helpers/TagsSelector';
|
import TagsSelector from '../helpers/TagsSelector';
|
||||||
import TagCard from '../TagCard';
|
import TagCard from '../TagCard';
|
||||||
import DeleteTagConfirmModal from '../helpers/DeleteTagConfirmModal';
|
import DeleteTagConfirmModal from '../helpers/DeleteTagConfirmModal';
|
||||||
|
@ -30,7 +29,6 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
||||||
bottle.serviceFactory('TagsTableRow', TagsTableRow, 'DeleteTagConfirmModal', 'EditTagModal', 'ColorGenerator');
|
bottle.serviceFactory('TagsTableRow', TagsTableRow, 'DeleteTagConfirmModal', 'EditTagModal', 'ColorGenerator');
|
||||||
|
|
||||||
bottle.serviceFactory('TagsTable', TagsTable, 'TagsTableRow');
|
bottle.serviceFactory('TagsTable', TagsTable, 'TagsTableRow');
|
||||||
bottle.decorator('TagsTable', withRouter);
|
|
||||||
|
|
||||||
bottle.serviceFactory('TagsList', TagsList, 'TagsCards', 'TagsTable');
|
bottle.serviceFactory('TagsList', TagsList, 'TagsCards', 'TagsTable');
|
||||||
bottle.decorator('TagsList', connect(
|
bottle.decorator('TagsList', connect(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useState, useRef, EffectCallback, DependencyList, useEffect } from 'react';
|
import { useState, useRef, EffectCallback, DependencyList, useEffect } from 'react';
|
||||||
import { useSwipeable as useReactSwipeable } from 'react-swipeable';
|
import { useSwipeable as useReactSwipeable } from 'react-swipeable';
|
||||||
import { parseQuery, stringifyQuery } from './query';
|
import { parseQuery, stringifyQuery } from './query';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
const DEFAULT_DELAY = 2000;
|
const DEFAULT_DELAY = 2000;
|
||||||
|
|
||||||
|
@ -75,3 +76,9 @@ export const useEffectExceptFirstTime = (callback: EffectCallback, deps: Depende
|
||||||
isFirstLoad.current = false;
|
isFirstLoad.current = false;
|
||||||
}, deps);
|
}, deps);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useGoBack = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
return () => navigate(-1);
|
||||||
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { RouteComponentProps } from 'react-router';
|
|
||||||
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
||||||
import { ShlinkVisitsParams } from '../api/types';
|
import { ShlinkVisitsParams } from '../api/types';
|
||||||
import { Topics } from '../mercure/helpers/Topics';
|
import { Topics } from '../mercure/helpers/Topics';
|
||||||
|
import { useGoBack } from '../utils/helpers/hooks';
|
||||||
import VisitsStats from './VisitsStats';
|
import VisitsStats from './VisitsStats';
|
||||||
import { NormalizedVisit, VisitsInfo, VisitsParams } from './types';
|
import { NormalizedVisit, VisitsInfo, VisitsParams } from './types';
|
||||||
import { VisitsExporter } from './services/VisitsExporter';
|
import { VisitsExporter } from './services/VisitsExporter';
|
||||||
|
@ -9,21 +9,20 @@ import { CommonVisitsProps } from './types/CommonVisitsProps';
|
||||||
import { toApiParams } from './types/helpers';
|
import { toApiParams } from './types/helpers';
|
||||||
import { NonOrphanVisitsHeader } from './NonOrphanVisitsHeader';
|
import { NonOrphanVisitsHeader } from './NonOrphanVisitsHeader';
|
||||||
|
|
||||||
export interface NonOrphanVisitsProps extends CommonVisitsProps, RouteComponentProps {
|
export interface NonOrphanVisitsProps extends CommonVisitsProps {
|
||||||
getNonOrphanVisits: (params?: ShlinkVisitsParams, doIntervalFallback?: boolean) => void;
|
getNonOrphanVisits: (params?: ShlinkVisitsParams, doIntervalFallback?: boolean) => void;
|
||||||
nonOrphanVisits: VisitsInfo;
|
nonOrphanVisits: VisitsInfo;
|
||||||
cancelGetNonOrphanVisits: () => void;
|
cancelGetNonOrphanVisits: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const NonOrphanVisits = ({ exportVisits }: VisitsExporter) => boundToMercureHub(({
|
export const NonOrphanVisits = ({ exportVisits }: VisitsExporter) => boundToMercureHub(({
|
||||||
history: { goBack },
|
|
||||||
match: { url },
|
|
||||||
getNonOrphanVisits,
|
getNonOrphanVisits,
|
||||||
nonOrphanVisits,
|
nonOrphanVisits,
|
||||||
cancelGetNonOrphanVisits,
|
cancelGetNonOrphanVisits,
|
||||||
settings,
|
settings,
|
||||||
selectedServer,
|
selectedServer,
|
||||||
}: NonOrphanVisitsProps) => {
|
}: NonOrphanVisitsProps) => {
|
||||||
|
const goBack = useGoBack();
|
||||||
const exportCsv = (visits: NormalizedVisit[]) => exportVisits('non_orphan_visits.csv', visits);
|
const exportCsv = (visits: NormalizedVisit[]) => exportVisits('non_orphan_visits.csv', visits);
|
||||||
const loadVisits = (params: VisitsParams, doIntervalFallback?: boolean) =>
|
const loadVisits = (params: VisitsParams, doIntervalFallback?: boolean) =>
|
||||||
getNonOrphanVisits(toApiParams(params), doIntervalFallback);
|
getNonOrphanVisits(toApiParams(params), doIntervalFallback);
|
||||||
|
@ -33,7 +32,6 @@ export const NonOrphanVisits = ({ exportVisits }: VisitsExporter) => boundToMerc
|
||||||
getVisits={loadVisits}
|
getVisits={loadVisits}
|
||||||
cancelGetVisits={cancelGetNonOrphanVisits}
|
cancelGetVisits={cancelGetNonOrphanVisits}
|
||||||
visitsInfo={nonOrphanVisits}
|
visitsInfo={nonOrphanVisits}
|
||||||
baseUrl={url}
|
|
||||||
settings={settings}
|
settings={settings}
|
||||||
exportCsv={exportCsv}
|
exportCsv={exportCsv}
|
||||||
selectedServer={selectedServer}
|
selectedServer={selectedServer}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { RouteComponentProps } from 'react-router';
|
|
||||||
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
||||||
import { ShlinkVisitsParams } from '../api/types';
|
import { ShlinkVisitsParams } from '../api/types';
|
||||||
import { Topics } from '../mercure/helpers/Topics';
|
import { Topics } from '../mercure/helpers/Topics';
|
||||||
|
import { useGoBack } from '../utils/helpers/hooks';
|
||||||
import VisitsStats from './VisitsStats';
|
import VisitsStats from './VisitsStats';
|
||||||
import { OrphanVisitsHeader } from './OrphanVisitsHeader';
|
import { OrphanVisitsHeader } from './OrphanVisitsHeader';
|
||||||
import { NormalizedVisit, OrphanVisitType, VisitsInfo, VisitsParams } from './types';
|
import { NormalizedVisit, OrphanVisitType, VisitsInfo, VisitsParams } from './types';
|
||||||
|
@ -9,7 +9,7 @@ import { VisitsExporter } from './services/VisitsExporter';
|
||||||
import { CommonVisitsProps } from './types/CommonVisitsProps';
|
import { CommonVisitsProps } from './types/CommonVisitsProps';
|
||||||
import { toApiParams } from './types/helpers';
|
import { toApiParams } from './types/helpers';
|
||||||
|
|
||||||
export interface OrphanVisitsProps extends CommonVisitsProps, RouteComponentProps {
|
export interface OrphanVisitsProps extends CommonVisitsProps {
|
||||||
getOrphanVisits: (
|
getOrphanVisits: (
|
||||||
params?: ShlinkVisitsParams,
|
params?: ShlinkVisitsParams,
|
||||||
orphanVisitsType?: OrphanVisitType,
|
orphanVisitsType?: OrphanVisitType,
|
||||||
|
@ -20,14 +20,13 @@ export interface OrphanVisitsProps extends CommonVisitsProps, RouteComponentProp
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OrphanVisits = ({ exportVisits }: VisitsExporter) => boundToMercureHub(({
|
export const OrphanVisits = ({ exportVisits }: VisitsExporter) => boundToMercureHub(({
|
||||||
history: { goBack },
|
|
||||||
match: { url },
|
|
||||||
getOrphanVisits,
|
getOrphanVisits,
|
||||||
orphanVisits,
|
orphanVisits,
|
||||||
cancelGetOrphanVisits,
|
cancelGetOrphanVisits,
|
||||||
settings,
|
settings,
|
||||||
selectedServer,
|
selectedServer,
|
||||||
}: OrphanVisitsProps) => {
|
}: OrphanVisitsProps) => {
|
||||||
|
const goBack = useGoBack();
|
||||||
const exportCsv = (visits: NormalizedVisit[]) => exportVisits('orphan_visits.csv', visits);
|
const exportCsv = (visits: NormalizedVisit[]) => exportVisits('orphan_visits.csv', visits);
|
||||||
const loadVisits = (params: VisitsParams, doIntervalFallback?: boolean) =>
|
const loadVisits = (params: VisitsParams, doIntervalFallback?: boolean) =>
|
||||||
getOrphanVisits(toApiParams(params), params.filter?.orphanVisitsType, doIntervalFallback);
|
getOrphanVisits(toApiParams(params), params.filter?.orphanVisitsType, doIntervalFallback);
|
||||||
|
@ -37,7 +36,6 @@ export const OrphanVisits = ({ exportVisits }: VisitsExporter) => boundToMercure
|
||||||
getVisits={loadVisits}
|
getVisits={loadVisits}
|
||||||
cancelGetVisits={cancelGetOrphanVisits}
|
cancelGetVisits={cancelGetOrphanVisits}
|
||||||
visitsInfo={orphanVisits}
|
visitsInfo={orphanVisits}
|
||||||
baseUrl={url}
|
|
||||||
settings={settings}
|
settings={settings}
|
||||||
exportCsv={exportCsv}
|
exportCsv={exportCsv}
|
||||||
selectedServer={selectedServer}
|
selectedServer={selectedServer}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { RouteComponentProps } from 'react-router';
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
||||||
import { ShlinkVisitsParams } from '../api/types';
|
import { ShlinkVisitsParams } from '../api/types';
|
||||||
import { parseQuery } from '../utils/helpers/query';
|
import { parseQuery } from '../utils/helpers/query';
|
||||||
import { Topics } from '../mercure/helpers/Topics';
|
import { Topics } from '../mercure/helpers/Topics';
|
||||||
import { ShortUrlDetail } from '../short-urls/reducers/shortUrlDetail';
|
import { ShortUrlDetail } from '../short-urls/reducers/shortUrlDetail';
|
||||||
|
import { useGoBack } from '../utils/helpers/hooks';
|
||||||
import { ShortUrlVisits as ShortUrlVisitsState } from './reducers/shortUrlVisits';
|
import { ShortUrlVisits as ShortUrlVisitsState } from './reducers/shortUrlVisits';
|
||||||
import ShortUrlVisitsHeader from './ShortUrlVisitsHeader';
|
import ShortUrlVisitsHeader from './ShortUrlVisitsHeader';
|
||||||
import VisitsStats from './VisitsStats';
|
import VisitsStats from './VisitsStats';
|
||||||
|
@ -13,7 +14,7 @@ import { NormalizedVisit, VisitsParams } from './types';
|
||||||
import { CommonVisitsProps } from './types/CommonVisitsProps';
|
import { CommonVisitsProps } from './types/CommonVisitsProps';
|
||||||
import { toApiParams } from './types/helpers';
|
import { toApiParams } from './types/helpers';
|
||||||
|
|
||||||
export interface ShortUrlVisitsProps extends CommonVisitsProps, RouteComponentProps<{ shortCode: string }> {
|
export interface ShortUrlVisitsProps extends CommonVisitsProps {
|
||||||
getShortUrlVisits: (shortCode: string, query?: ShlinkVisitsParams, doIntervalFallback?: boolean) => void;
|
getShortUrlVisits: (shortCode: string, query?: ShlinkVisitsParams, doIntervalFallback?: boolean) => void;
|
||||||
shortUrlVisits: ShortUrlVisitsState;
|
shortUrlVisits: ShortUrlVisitsState;
|
||||||
getShortUrlDetail: Function;
|
getShortUrlDetail: Function;
|
||||||
|
@ -22,9 +23,6 @@ export interface ShortUrlVisitsProps extends CommonVisitsProps, RouteComponentPr
|
||||||
}
|
}
|
||||||
|
|
||||||
const ShortUrlVisits = ({ exportVisits }: VisitsExporter) => boundToMercureHub(({
|
const ShortUrlVisits = ({ exportVisits }: VisitsExporter) => boundToMercureHub(({
|
||||||
history: { goBack },
|
|
||||||
match: { params, url },
|
|
||||||
location: { search },
|
|
||||||
shortUrlVisits,
|
shortUrlVisits,
|
||||||
shortUrlDetail,
|
shortUrlDetail,
|
||||||
getShortUrlVisits,
|
getShortUrlVisits,
|
||||||
|
@ -33,7 +31,9 @@ const ShortUrlVisits = ({ exportVisits }: VisitsExporter) => boundToMercureHub((
|
||||||
settings,
|
settings,
|
||||||
selectedServer,
|
selectedServer,
|
||||||
}: ShortUrlVisitsProps) => {
|
}: ShortUrlVisitsProps) => {
|
||||||
const { shortCode } = params;
|
const { shortCode = '' } = useParams<{ shortCode: string }>();
|
||||||
|
const { search } = useLocation();
|
||||||
|
const goBack = useGoBack();
|
||||||
const { domain } = parseQuery<{ domain?: string }>(search);
|
const { domain } = parseQuery<{ domain?: string }>(search);
|
||||||
const loadVisits = (params: VisitsParams, doIntervalFallback?: boolean) =>
|
const loadVisits = (params: VisitsParams, doIntervalFallback?: boolean) =>
|
||||||
getShortUrlVisits(shortCode, { ...toApiParams(params), domain }, doIntervalFallback);
|
getShortUrlVisits(shortCode, { ...toApiParams(params), domain }, doIntervalFallback);
|
||||||
|
@ -51,7 +51,6 @@ const ShortUrlVisits = ({ exportVisits }: VisitsExporter) => boundToMercureHub((
|
||||||
getVisits={loadVisits}
|
getVisits={loadVisits}
|
||||||
cancelGetVisits={cancelGetShortUrlVisits}
|
cancelGetVisits={cancelGetShortUrlVisits}
|
||||||
visitsInfo={shortUrlVisits}
|
visitsInfo={shortUrlVisits}
|
||||||
baseUrl={url}
|
|
||||||
domain={domain}
|
domain={domain}
|
||||||
settings={settings}
|
settings={settings}
|
||||||
exportCsv={exportCsv}
|
exportCsv={exportCsv}
|
||||||
|
@ -60,6 +59,6 @@ const ShortUrlVisits = ({ exportVisits }: VisitsExporter) => boundToMercureHub((
|
||||||
<ShortUrlVisitsHeader shortUrlDetail={shortUrlDetail} shortUrlVisits={shortUrlVisits} goBack={goBack} />
|
<ShortUrlVisitsHeader shortUrlDetail={shortUrlDetail} shortUrlVisits={shortUrlVisits} goBack={goBack} />
|
||||||
</VisitsStats>
|
</VisitsStats>
|
||||||
);
|
);
|
||||||
}, ({ match }) => [ Topics.shortUrlVisits(match.params.shortCode) ]);
|
}, (_, params) => [ Topics.shortUrlVisits(params.shortCode) ]);
|
||||||
|
|
||||||
export default ShortUrlVisits;
|
export default ShortUrlVisits;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { RouteComponentProps } from 'react-router';
|
import { useParams } from 'react-router-dom';
|
||||||
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
||||||
import ColorGenerator from '../utils/services/ColorGenerator';
|
import ColorGenerator from '../utils/services/ColorGenerator';
|
||||||
import { ShlinkVisitsParams } from '../api/types';
|
import { ShlinkVisitsParams } from '../api/types';
|
||||||
import { Topics } from '../mercure/helpers/Topics';
|
import { Topics } from '../mercure/helpers/Topics';
|
||||||
|
import { useGoBack } from '../utils/helpers/hooks';
|
||||||
import { TagVisits as TagVisitsState } from './reducers/tagVisits';
|
import { TagVisits as TagVisitsState } from './reducers/tagVisits';
|
||||||
import TagVisitsHeader from './TagVisitsHeader';
|
import TagVisitsHeader from './TagVisitsHeader';
|
||||||
import VisitsStats from './VisitsStats';
|
import VisitsStats from './VisitsStats';
|
||||||
|
@ -11,22 +12,21 @@ import { NormalizedVisit } from './types';
|
||||||
import { CommonVisitsProps } from './types/CommonVisitsProps';
|
import { CommonVisitsProps } from './types/CommonVisitsProps';
|
||||||
import { toApiParams } from './types/helpers';
|
import { toApiParams } from './types/helpers';
|
||||||
|
|
||||||
export interface TagVisitsProps extends CommonVisitsProps, RouteComponentProps<{ tag: string }> {
|
export interface TagVisitsProps extends CommonVisitsProps {
|
||||||
getTagVisits: (tag: string, query?: ShlinkVisitsParams, doIntervalFallback?: boolean) => void;
|
getTagVisits: (tag: string, query?: ShlinkVisitsParams, doIntervalFallback?: boolean) => void;
|
||||||
tagVisits: TagVisitsState;
|
tagVisits: TagVisitsState;
|
||||||
cancelGetTagVisits: () => void;
|
cancelGetTagVisits: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TagVisits = (colorGenerator: ColorGenerator, { exportVisits }: VisitsExporter) => boundToMercureHub(({
|
const TagVisits = (colorGenerator: ColorGenerator, { exportVisits }: VisitsExporter) => boundToMercureHub(({
|
||||||
history: { goBack },
|
|
||||||
match: { params, url },
|
|
||||||
getTagVisits,
|
getTagVisits,
|
||||||
tagVisits,
|
tagVisits,
|
||||||
cancelGetTagVisits,
|
cancelGetTagVisits,
|
||||||
settings,
|
settings,
|
||||||
selectedServer,
|
selectedServer,
|
||||||
}: TagVisitsProps) => {
|
}: TagVisitsProps) => {
|
||||||
const { tag } = params;
|
const goBack = useGoBack();
|
||||||
|
const { tag = '' } = useParams();
|
||||||
const loadVisits = (params: ShlinkVisitsParams, doIntervalFallback?: boolean) =>
|
const loadVisits = (params: ShlinkVisitsParams, doIntervalFallback?: boolean) =>
|
||||||
getTagVisits(tag, toApiParams(params), doIntervalFallback);
|
getTagVisits(tag, toApiParams(params), doIntervalFallback);
|
||||||
const exportCsv = (visits: NormalizedVisit[]) => exportVisits(`tag_${tag}_visits.csv`, visits);
|
const exportCsv = (visits: NormalizedVisit[]) => exportVisits(`tag_${tag}_visits.csv`, visits);
|
||||||
|
@ -36,7 +36,6 @@ const TagVisits = (colorGenerator: ColorGenerator, { exportVisits }: VisitsExpor
|
||||||
getVisits={loadVisits}
|
getVisits={loadVisits}
|
||||||
cancelGetVisits={cancelGetTagVisits}
|
cancelGetVisits={cancelGetTagVisits}
|
||||||
visitsInfo={tagVisits}
|
visitsInfo={tagVisits}
|
||||||
baseUrl={url}
|
|
||||||
settings={settings}
|
settings={settings}
|
||||||
exportCsv={exportCsv}
|
exportCsv={exportCsv}
|
||||||
selectedServer={selectedServer}
|
selectedServer={selectedServer}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Button, Card, Nav, NavLink, Progress, Row } from 'reactstrap';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faCalendarAlt, faMapMarkedAlt, faList, faChartPie, faFileDownload } from '@fortawesome/free-solid-svg-icons';
|
import { faCalendarAlt, faMapMarkedAlt, faList, faChartPie, faFileDownload } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { IconDefinition } from '@fortawesome/fontawesome-common-types';
|
import { IconDefinition } from '@fortawesome/fontawesome-common-types';
|
||||||
import { Route, Switch, NavLink as RouterNavLink, Redirect } from 'react-router-dom';
|
import { Route, Routes, NavLink as RouterNavLink, Navigate } from 'react-router-dom';
|
||||||
import { Location } from 'history';
|
import { Location } from 'history';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { DateRangeSelector } from '../utils/dates/DateRangeSelector';
|
import { DateRangeSelector } from '../utils/dates/DateRangeSelector';
|
||||||
|
@ -33,7 +33,6 @@ export interface VisitsStatsProps {
|
||||||
settings: Settings;
|
settings: Settings;
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
cancelGetVisits: () => void;
|
cancelGetVisits: () => void;
|
||||||
baseUrl: string;
|
|
||||||
domain?: string;
|
domain?: string;
|
||||||
exportCsv: (visits: NormalizedVisit[]) => void;
|
exportCsv: (visits: NormalizedVisit[]) => void;
|
||||||
isOrphanVisits?: boolean;
|
isOrphanVisits?: boolean;
|
||||||
|
@ -48,10 +47,10 @@ interface VisitsNavLinkProps {
|
||||||
type Section = 'byTime' | 'byContext' | 'byLocation' | 'list';
|
type Section = 'byTime' | 'byContext' | 'byLocation' | 'list';
|
||||||
|
|
||||||
const sections: Record<Section, VisitsNavLinkProps> = {
|
const sections: Record<Section, VisitsNavLinkProps> = {
|
||||||
byTime: { title: 'By time', subPath: '', icon: faCalendarAlt },
|
byTime: { title: 'By time', subPath: 'by-time', icon: faCalendarAlt },
|
||||||
byContext: { title: 'By context', subPath: '/by-context', icon: faChartPie },
|
byContext: { title: 'By context', subPath: 'by-context', icon: faChartPie },
|
||||||
byLocation: { title: 'By location', subPath: '/by-location', icon: faMapMarkedAlt },
|
byLocation: { title: 'By location', subPath: 'by-location', icon: faMapMarkedAlt },
|
||||||
list: { title: 'List', subPath: '/list', icon: faList },
|
list: { title: 'List', subPath: 'list', icon: faList },
|
||||||
};
|
};
|
||||||
|
|
||||||
let selectedBar: string | undefined;
|
let selectedBar: string | undefined;
|
||||||
|
@ -74,7 +73,6 @@ const VisitsStats: FC<VisitsStatsProps> = ({
|
||||||
visitsInfo,
|
visitsInfo,
|
||||||
getVisits,
|
getVisits,
|
||||||
cancelGetVisits,
|
cancelGetVisits,
|
||||||
baseUrl,
|
|
||||||
domain,
|
domain,
|
||||||
settings,
|
settings,
|
||||||
exportCsv,
|
exportCsv,
|
||||||
|
@ -95,7 +93,7 @@ const VisitsStats: FC<VisitsStatsProps> = ({
|
||||||
const buildSectionUrl = (subPath?: string) => {
|
const buildSectionUrl = (subPath?: string) => {
|
||||||
const query = domain ? `?domain=${domain}` : '';
|
const query = domain ? `?domain=${domain}` : '';
|
||||||
|
|
||||||
return !subPath ? `${baseUrl}${query}` : `${baseUrl}${subPath}${query}`;
|
return !subPath ? `${query}` : `${subPath}${query}`;
|
||||||
};
|
};
|
||||||
const normalizedVisits = useMemo(() => normalizeVisits(visits), [ visits ]);
|
const normalizedVisits = useMemo(() => normalizeVisits(visits), [ visits ]);
|
||||||
const { os, browsers, referrers, countries, cities, citiesForMap, visitedUrls } = useMemo(
|
const { os, browsers, referrers, countries, cities, citiesForMap, visitedUrls } = useMemo(
|
||||||
|
@ -166,104 +164,120 @@ const VisitsStats: FC<VisitsStatsProps> = ({
|
||||||
</Nav>
|
</Nav>
|
||||||
</Card>
|
</Card>
|
||||||
<Row>
|
<Row>
|
||||||
<Switch>
|
<Routes>
|
||||||
<Route exact path={baseUrl}>
|
<Route
|
||||||
<div className="col-12 mt-3">
|
path={sections.byTime.subPath}
|
||||||
<LineChartCard
|
element={(
|
||||||
title="Visits during time"
|
<div className="col-12 mt-3">
|
||||||
visits={normalizedVisits}
|
<LineChartCard
|
||||||
highlightedVisits={highlightedVisits}
|
title="Visits during time"
|
||||||
highlightedLabel={highlightedLabel}
|
visits={normalizedVisits}
|
||||||
setSelectedVisits={setSelectedVisits}
|
highlightedVisits={highlightedVisits}
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route exact path={`${baseUrl}${sections.byContext.subPath}`}>
|
|
||||||
<div className={classNames('mt-3 col-lg-6', { 'col-xl-4': !isOrphanVisits })}>
|
|
||||||
<DoughnutChartCard title="Operating systems" stats={os} />
|
|
||||||
</div>
|
|
||||||
<div className={classNames('mt-3 col-lg-6', { 'col-xl-4': !isOrphanVisits })}>
|
|
||||||
<DoughnutChartCard title="Browsers" stats={browsers} />
|
|
||||||
</div>
|
|
||||||
<div className={classNames('mt-3', { 'col-xl-4': !isOrphanVisits, 'col-lg-6': isOrphanVisits })}>
|
|
||||||
<SortableBarChartCard
|
|
||||||
title="Referrers"
|
|
||||||
stats={referrers}
|
|
||||||
withPagination={false}
|
|
||||||
highlightedStats={highlightedVisitsToStats(highlightedVisits, 'referer')}
|
|
||||||
highlightedLabel={highlightedLabel}
|
|
||||||
sortingItems={{
|
|
||||||
name: 'Referrer name',
|
|
||||||
amount: 'Visits amount',
|
|
||||||
}}
|
|
||||||
onClick={highlightVisitsForProp('referer')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{isOrphanVisits && (
|
|
||||||
<div className="mt-3 col-lg-6">
|
|
||||||
<SortableBarChartCard
|
|
||||||
title="Visited URLs"
|
|
||||||
stats={visitedUrls}
|
|
||||||
highlightedLabel={highlightedLabel}
|
highlightedLabel={highlightedLabel}
|
||||||
highlightedStats={highlightedVisitsToStats(highlightedVisits, 'visitedUrl')}
|
setSelectedVisits={setSelectedVisits}
|
||||||
sortingItems={{
|
|
||||||
visitedUrl: 'Visited URL',
|
|
||||||
amount: 'Visits amount',
|
|
||||||
}}
|
|
||||||
onClick={highlightVisitsForProp('visitedUrl')}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Route>
|
/>
|
||||||
|
|
||||||
<Route exact path={`${baseUrl}${sections.byLocation.subPath}`}>
|
<Route
|
||||||
<div className="col-lg-6 mt-3">
|
path={sections.byContext.subPath}
|
||||||
<SortableBarChartCard
|
element={(
|
||||||
title="Countries"
|
<>
|
||||||
stats={countries}
|
<div className={classNames('mt-3 col-lg-6', { 'col-xl-4': !isOrphanVisits })}>
|
||||||
highlightedStats={highlightedVisitsToStats(highlightedVisits, 'country')}
|
<DoughnutChartCard title="Operating systems" stats={os} />
|
||||||
highlightedLabel={highlightedLabel}
|
</div>
|
||||||
sortingItems={{
|
<div className={classNames('mt-3 col-lg-6', { 'col-xl-4': !isOrphanVisits })}>
|
||||||
name: 'Country name',
|
<DoughnutChartCard title="Browsers" stats={browsers} />
|
||||||
amount: 'Visits amount',
|
</div>
|
||||||
}}
|
<div className={classNames('mt-3', { 'col-xl-4': !isOrphanVisits, 'col-lg-6': isOrphanVisits })}>
|
||||||
onClick={highlightVisitsForProp('country')}
|
<SortableBarChartCard
|
||||||
/>
|
title="Referrers"
|
||||||
</div>
|
stats={referrers}
|
||||||
<div className="col-lg-6 mt-3">
|
withPagination={false}
|
||||||
<SortableBarChartCard
|
highlightedStats={highlightedVisitsToStats(highlightedVisits, 'referer')}
|
||||||
title="Cities"
|
highlightedLabel={highlightedLabel}
|
||||||
stats={cities}
|
sortingItems={{
|
||||||
highlightedStats={highlightedVisitsToStats(highlightedVisits, 'city')}
|
name: 'Referrer name',
|
||||||
highlightedLabel={highlightedLabel}
|
amount: 'Visits amount',
|
||||||
extraHeaderContent={(activeCities: string[]) =>
|
}}
|
||||||
mapLocations.length > 0 &&
|
onClick={highlightVisitsForProp('referer')}
|
||||||
<OpenMapModalBtn modalTitle="Cities" locations={mapLocations} activeCities={activeCities} />
|
/>
|
||||||
}
|
</div>
|
||||||
sortingItems={{
|
{isOrphanVisits && (
|
||||||
name: 'City name',
|
<div className="mt-3 col-lg-6">
|
||||||
amount: 'Visits amount',
|
<SortableBarChartCard
|
||||||
}}
|
title="Visited URLs"
|
||||||
onClick={highlightVisitsForProp('city')}
|
stats={visitedUrls}
|
||||||
/>
|
highlightedLabel={highlightedLabel}
|
||||||
</div>
|
highlightedStats={highlightedVisitsToStats(highlightedVisits, 'visitedUrl')}
|
||||||
</Route>
|
sortingItems={{
|
||||||
|
visitedUrl: 'Visited URL',
|
||||||
|
amount: 'Visits amount',
|
||||||
|
}}
|
||||||
|
onClick={highlightVisitsForProp('visitedUrl')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
<Route exact path={`${baseUrl}${sections.list.subPath}`}>
|
<Route
|
||||||
<div className="col-12">
|
path={sections.byLocation.subPath}
|
||||||
<VisitsTable
|
element={(
|
||||||
visits={normalizedVisits}
|
<>
|
||||||
selectedVisits={highlightedVisits}
|
<div className="col-lg-6 mt-3">
|
||||||
setSelectedVisits={setSelectedVisits}
|
<SortableBarChartCard
|
||||||
isOrphanVisits={isOrphanVisits}
|
title="Countries"
|
||||||
selectedServer={selectedServer}
|
stats={countries}
|
||||||
/>
|
highlightedStats={highlightedVisitsToStats(highlightedVisits, 'country')}
|
||||||
</div>
|
highlightedLabel={highlightedLabel}
|
||||||
</Route>
|
sortingItems={{
|
||||||
|
name: 'Country name',
|
||||||
|
amount: 'Visits amount',
|
||||||
|
}}
|
||||||
|
onClick={highlightVisitsForProp('country')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg-6 mt-3">
|
||||||
|
<SortableBarChartCard
|
||||||
|
title="Cities"
|
||||||
|
stats={cities}
|
||||||
|
highlightedStats={highlightedVisitsToStats(highlightedVisits, 'city')}
|
||||||
|
highlightedLabel={highlightedLabel}
|
||||||
|
extraHeaderContent={(activeCities: string[]) =>
|
||||||
|
mapLocations.length > 0 &&
|
||||||
|
<OpenMapModalBtn modalTitle="Cities" locations={mapLocations} activeCities={activeCities} />
|
||||||
|
}
|
||||||
|
sortingItems={{
|
||||||
|
name: 'City name',
|
||||||
|
amount: 'Visits amount',
|
||||||
|
}}
|
||||||
|
onClick={highlightVisitsForProp('city')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
<Redirect to={baseUrl} />
|
<Route
|
||||||
</Switch>
|
path={sections.list.subPath}
|
||||||
|
element={(
|
||||||
|
<div className="col-12">
|
||||||
|
<VisitsTable
|
||||||
|
visits={normalizedVisits}
|
||||||
|
selectedVisits={highlightedVisits}
|
||||||
|
setSelectedVisits={setSelectedVisits}
|
||||||
|
isOrphanVisits={isOrphanVisits}
|
||||||
|
selectedServer={selectedServer}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Route path="*" element={<Navigate replace to={buildSectionUrl(sections.byTime.subPath)} />} />
|
||||||
|
</Routes>
|
||||||
</Row>
|
</Row>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue