mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-24 01:48:18 +03:00
Merge pull request #332 from acelaya-forks/feature/update-deps
Feature/update deps
This commit is contained in:
commit
dafebc3df9
146 changed files with 12198 additions and 7381 deletions
|
@ -23,6 +23,7 @@
|
||||||
}],
|
}],
|
||||||
"no-mixed-operators": "off",
|
"no-mixed-operators": "off",
|
||||||
"react/display-name": "off",
|
"react/display-name": "off",
|
||||||
|
"react/react-in-jsx-scope": "off",
|
||||||
"@typescript-eslint/require-array-sort-compare": "off"
|
"@typescript-eslint/require-array-sort-compare": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
.github/workflows/docker-image-build.yml
vendored
4
.github/workflows/docker-image-build.yml
vendored
|
@ -22,7 +22,7 @@ jobs:
|
||||||
- name: Login to docker hub
|
- name: Login to docker hub
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v1
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||||
- name: Build the image
|
- name: Build the image
|
||||||
run: bash ./scripts/docker/build
|
run: bash ./scripts/docker/build
|
||||||
|
|
|
@ -16,6 +16,7 @@ node_js:
|
||||||
jobs:
|
jobs:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
allow_failures:
|
allow_failures:
|
||||||
|
- name: 'Lint'
|
||||||
- name: 'Mutation tests'
|
- name: 'Mutation tests'
|
||||||
include:
|
include:
|
||||||
|
|
||||||
|
|
17
CHANGELOG.md
17
CHANGELOG.md
|
@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
### Added
|
||||||
|
* *Nothing*
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
* [#325](https://github.com/shlinkio/shlink-web-client/issues/325) and [#294](https://github.com/shlinkio/shlink-web-client/issues/294) Updated all dependencies, including React 17, Typescript 4, react-datepicker 3 and Stryker 4.
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
* *Nothing*
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
* *Nothing*
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
* [#334](https://github.com/shlinkio/shlink-web-client/issues/334) Fixed color-picker making the app crash when closing the modal without closing the color-picker, and then trying to open the modal again.
|
||||||
|
|
||||||
|
|
||||||
## [2.6.1] - 2020-10-31
|
## [2.6.1] - 2020-10-31
|
||||||
### Added
|
### Added
|
||||||
* *Nothing*
|
* *Nothing*
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Enzyme from 'enzyme';
|
import Enzyme from 'enzyme';
|
||||||
import Adapter from 'enzyme-adapter-react-16';
|
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
|
||||||
|
|
||||||
Enzyme.configure({ adapter: new Adapter() });
|
Enzyme.configure({ adapter: new Adapter() });
|
||||||
|
|
|
@ -13,7 +13,6 @@ const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||||
const safePostCssParser = require('postcss-safe-parser');
|
const safePostCssParser = require('postcss-safe-parser');
|
||||||
const ManifestPlugin = require('webpack-manifest-plugin');
|
const ManifestPlugin = require('webpack-manifest-plugin');
|
||||||
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
|
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
|
||||||
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
|
|
||||||
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
|
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
|
||||||
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
|
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
|
||||||
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
|
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
|
||||||
|
@ -611,25 +610,6 @@ module.exports = (webpackEnv) => {
|
||||||
// You can remove this if you don't use Moment.js:
|
// You can remove this if you don't use Moment.js:
|
||||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||||
|
|
||||||
// Generate a service worker script that will precache, and keep up to date,
|
|
||||||
// the HTML & assets that are part of the Webpack build.
|
|
||||||
isEnvProduction &&
|
|
||||||
new WorkboxWebpackPlugin.GenerateSW({
|
|
||||||
clientsClaim: true,
|
|
||||||
exclude: [ /\.map$/, /asset-manifest\.json$/ ],
|
|
||||||
importWorkboxFrom: 'cdn',
|
|
||||||
navigateFallback: `${publicUrl}/index.html`,
|
|
||||||
navigateFallbackBlacklist: [
|
|
||||||
|
|
||||||
// Exclude URLs starting with /_, as they're likely an API call
|
|
||||||
new RegExp('^/_'),
|
|
||||||
|
|
||||||
// Exclude URLs containing a dot, as they're likely a resource in
|
|
||||||
// public/ and not a SPA route
|
|
||||||
new RegExp('/[^/]+\\.[^/]+$'),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
|
|
||||||
// TypeScript type checking
|
// TypeScript type checking
|
||||||
useTypeScript &&
|
useTypeScript &&
|
||||||
new ForkTsCheckerWebpackPlugin({
|
new ForkTsCheckerWebpackPlugin({
|
||||||
|
|
|
@ -110,7 +110,7 @@ module.exports = function(proxy, allowedHost) {
|
||||||
// We do this in development to avoid hitting the production cache if
|
// We do this in development to avoid hitting the production cache if
|
||||||
// it used the same host and port.
|
// it used the same host and port.
|
||||||
// https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
|
// https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
|
||||||
app.use(noopServiceWorkerMiddleware());
|
app.use(noopServiceWorkerMiddleware(paths.publicUrl));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
18964
package-lock.json
generated
18964
package-lock.json
generated
File diff suppressed because it is too large
Load diff
189
package.json
189
package.json
|
@ -17,147 +17,148 @@
|
||||||
"test": "node scripts/test.js --env=jsdom --colors",
|
"test": "node scripts/test.js --env=jsdom --colors",
|
||||||
"test:ci": "npm run test -- --coverage --coverageReporters=text --coverageReporters=text-summary --coverageReporters=clover",
|
"test:ci": "npm run test -- --coverage --coverageReporters=text --coverageReporters=text-summary --coverageReporters=clover",
|
||||||
"test:pretty": "npm run test -- --coverage --coverageReporters=text --coverageReporters=text-summary --coverageReporters=html",
|
"test:pretty": "npm run test -- --coverage --coverageReporters=text --coverageReporters=text-summary --coverageReporters=html",
|
||||||
"mutate": "./node_modules/.bin/stryker run",
|
"mutate": "./node_modules/.bin/stryker run --concurrency 4",
|
||||||
"mutate:ci": "npm run mutate -- --mutate=$MUTATION_FILES"
|
"mutate:ci": "npm run mutate -- --mutate=$MUTATION_FILES"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-free": "^5.14.0",
|
"@fortawesome/fontawesome-free": "^5.15.1",
|
||||||
"@fortawesome/fontawesome-svg-core": "^1.2.30",
|
"@fortawesome/fontawesome-svg-core": "^1.2.32",
|
||||||
"@fortawesome/free-regular-svg-icons": "^5.14.0",
|
"@fortawesome/free-regular-svg-icons": "^5.15.1",
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.14.0",
|
"@fortawesome/free-solid-svg-icons": "^5.15.1",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.11",
|
"@fortawesome/react-fontawesome": "^0.1.12",
|
||||||
"array-filter": "^1.0.0",
|
"axios": "^0.21.0",
|
||||||
"array-map": "^0.0.0",
|
"bootstrap": "^4.5.3",
|
||||||
"array-reduce": "^0.0.0",
|
|
||||||
"axios": "^0.20.0",
|
|
||||||
"bootstrap": "^4.5.2",
|
|
||||||
"bottlejs": "^2.0.0",
|
"bottlejs": "^2.0.0",
|
||||||
"bowser": "^2.10.0",
|
"bowser": "^2.11.0",
|
||||||
"chart.js": "^2.9.3",
|
"chart.js": "^2.9.4",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"compare-versions": "^3.6.0",
|
"compare-versions": "^3.6.0",
|
||||||
"csvjson": "^5.1.0",
|
"csvjson": "^5.1.0",
|
||||||
"event-source-polyfill": "^1.0.17",
|
"event-source-polyfill": "^1.0.21",
|
||||||
"leaflet": "^1.7.1",
|
"leaflet": "^1.7.1",
|
||||||
"moment": "^2.27.0",
|
"moment": "^2.29.1",
|
||||||
"promise": "^8.0.3",
|
"promise": "^8.1.0",
|
||||||
"qs": "^6.9.4",
|
"qs": "^6.9.4",
|
||||||
"ramda": "^0.27.1",
|
"ramda": "^0.27.1",
|
||||||
"react": "^16.13.1",
|
"react": "^17.0.1",
|
||||||
"react-autosuggest": "^10.0.2",
|
"react-autosuggest": "^10.0.3",
|
||||||
"react-chartjs-2": "^2.10.0",
|
"react-chartjs-2": "^2.11.1",
|
||||||
"react-color": "^2.18.1",
|
"react-color": "^2.19.3",
|
||||||
"react-copy-to-clipboard": "^5.0.2",
|
"react-copy-to-clipboard": "^5.0.2",
|
||||||
"react-datepicker": "~1.5.0",
|
"react-datepicker": "^3.3.0",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^17.0.1",
|
||||||
"react-external-link": "^1.1.1",
|
"react-external-link": "^1.1.1",
|
||||||
"react-leaflet": "^2.7.0",
|
"react-leaflet": "^3.0.2",
|
||||||
"react-moment": "^0.9.7",
|
"react-moment": "^1.0.0",
|
||||||
"react-redux": "^7.2.1",
|
"react-redux": "^7.2.2",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-swipeable": "^5.5.1",
|
"react-swipeable": "^6.0.0",
|
||||||
"react-tagsinput": "^3.19.0",
|
"react-tagsinput": "^3.19.0",
|
||||||
"reactstrap": "^8.0.1",
|
"reactstrap": "^8.7.1",
|
||||||
"redux": "^4.0.4",
|
"redux": "^4.0.5",
|
||||||
"redux-localstorage-simple": "^2.2.0",
|
"redux-localstorage-simple": "^2.3.1",
|
||||||
"redux-thunk": "^2.3.0",
|
"redux-thunk": "^2.3.0",
|
||||||
"uuid": "^3.3.3"
|
"uuid": "^8.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.6.2",
|
"@babel/core": "^7.12.3",
|
||||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4",
|
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1",
|
||||||
"@babel/plugin-proposal-optional-chaining": "^7.11.0",
|
"@babel/plugin-proposal-optional-chaining": "^7.12.1",
|
||||||
"@shlinkio/eslint-config-js-coding-standard": "~1.1.0",
|
"@shlinkio/eslint-config-js-coding-standard": "~1.1.0",
|
||||||
"@stryker-mutator/core": "^3.2.4",
|
"@stryker-mutator/core": "^4.1.2",
|
||||||
"@stryker-mutator/typescript": "^3.2.4",
|
"@stryker-mutator/jest-runner": "^4.1.2",
|
||||||
"@stryker-mutator/jest-runner": "^3.2.4",
|
"@stryker-mutator/typescript-checker": "^4.1.2",
|
||||||
"@svgr/webpack": "^4.3.3",
|
"@svgr/webpack": "^5.4.0",
|
||||||
"@types/chart.js": "^2.9.24",
|
"@types/chart.js": "^2.9.27",
|
||||||
"@types/classnames": "^2.2.10",
|
"@types/classnames": "^2.2.11",
|
||||||
"@types/enzyme": "^3.10.5",
|
"@types/enzyme": "^3.10.8",
|
||||||
"@types/jest": "^26.0.10",
|
"@types/jest": "^26.0.15",
|
||||||
"@types/leaflet": "^1.5.17",
|
"@types/leaflet": "^1.5.19",
|
||||||
"@types/moment": "^2.13.0",
|
"@types/moment": "^2.13.0",
|
||||||
"@types/qs": "^6.9.4",
|
"@types/qs": "^6.9.5",
|
||||||
"@types/ramda": "^0.27.14",
|
"@types/ramda": "^0.27.32",
|
||||||
"@types/react": "^16.9.46",
|
"@types/react": "^16.9.56",
|
||||||
"@types/react-autosuggest": "^10.0.0",
|
"@types/react-autosuggest": "^10.0.1",
|
||||||
"@types/react-color": "^2.17.4",
|
"@types/react-color": "^3.0.4",
|
||||||
"@types/react-copy-to-clipboard": "^4.3.0",
|
"@types/react-copy-to-clipboard": "^4.3.0",
|
||||||
"@types/react-datepicker": "~1.8.0",
|
"@types/react-datepicker": "^3.1.1",
|
||||||
"@types/react-dom": "^16.9.8",
|
"@types/react-dom": "^16.9.9",
|
||||||
"@types/react-leaflet": "^2.5.2",
|
"@types/react-leaflet": "^2.5.2",
|
||||||
"@types/react-redux": "^7.1.9",
|
"@types/react-redux": "^7.1.11",
|
||||||
"@types/react-router-dom": "^5.1.5",
|
"@types/react-router-dom": "^5.1.6",
|
||||||
"@types/react-tagsinput": "^3.19.7",
|
"@types/react-tagsinput": "^3.19.7",
|
||||||
"@types/reactstrap": "^8.5.1",
|
|
||||||
"@types/uuid": "^8.3.0",
|
"@types/uuid": "^8.3.0",
|
||||||
"adm-zip": "^0.4.13",
|
"@typescript-eslint/parser": "^4.7.0",
|
||||||
"autoprefixer": "^9.6.3",
|
"@wojtekmaj/enzyme-adapter-react-17": "^0.3.1",
|
||||||
|
"adm-zip": "^0.4.16",
|
||||||
|
"autoprefixer": "^10.0.2",
|
||||||
"babel-core": "7.0.0-bridge.0",
|
"babel-core": "7.0.0-bridge.0",
|
||||||
"babel-jest": "^26.3.0",
|
"babel-jest": "^26.6.3",
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.2.1",
|
||||||
"babel-plugin-named-asset-import": "^0.3.4",
|
"babel-plugin-named-asset-import": "^0.3.7",
|
||||||
"babel-preset-react-app": "^9.0.2",
|
"babel-preset-react-app": "^10.0.0",
|
||||||
"babel-runtime": "^6.26.0",
|
"babel-runtime": "^6.26.0",
|
||||||
"bfj": "^7.0.1",
|
"bfj": "^7.0.2",
|
||||||
"case-sensitive-paths-webpack-plugin": "^2.2.0",
|
"case-sensitive-paths-webpack-plugin": "^2.3.0",
|
||||||
"chalk": "^2.4.2",
|
"chalk": "^4.1.0",
|
||||||
"css-loader": "^3.2.0",
|
"css-loader": "^5.0.1",
|
||||||
"dart-sass": "^1.25.0",
|
"dart-sass": "^1.25.0",
|
||||||
"dotenv": "^8.1.0",
|
"dotenv": "^8.2.0",
|
||||||
"dotenv-expand": "^5.1.0",
|
"dotenv-expand": "^5.1.0",
|
||||||
"enzyme": "^3.11.0",
|
"enzyme": "^3.11.0",
|
||||||
"enzyme-adapter-react-16": "^1.15.2",
|
"eslint": "^7.13.0",
|
||||||
"eslint": "^6.8.0",
|
"eslint-loader": "^4.0.2",
|
||||||
"eslint-loader": "^3.0.2",
|
"file-loader": "^6.2.0",
|
||||||
"file-loader": "^4.2.0",
|
|
||||||
"fork-ts-checker-webpack-plugin-alt": "^0.4.14",
|
"fork-ts-checker-webpack-plugin-alt": "^0.4.14",
|
||||||
"fs-extra": "^8.1.0",
|
"fs-extra": "^9.0.1",
|
||||||
"html-webpack-plugin": "^4.0.0-beta.8",
|
"html-webpack-plugin": "^4.5.0",
|
||||||
"identity-obj-proxy": "^3.0.0",
|
"identity-obj-proxy": "^3.0.0",
|
||||||
"jest": "^26.4.2",
|
"jest": "^26.6.3",
|
||||||
"jest-pnp-resolver": "^1.2.2",
|
"jest-pnp-resolver": "^1.2.2",
|
||||||
"jest-resolve": "^26.4.0",
|
"jest-resolve": "^26.6.2",
|
||||||
"mini-css-extract-plugin": "^0.8.0",
|
"mini-css-extract-plugin": "^1.3.1",
|
||||||
"object-assign": "^4.1.1",
|
"object-assign": "^4.1.1",
|
||||||
"ocular.js": "^0.1.0",
|
"ocular.js": "^0.1.0",
|
||||||
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
"optimize-css-assets-webpack-plugin": "^5.0.4",
|
||||||
"pnp-webpack-plugin": "^1.5.0",
|
"pnp-webpack-plugin": "^1.6.4",
|
||||||
"postcss": "^7.0.18",
|
"postcss": "^8.1.7",
|
||||||
"postcss-flexbugs-fixes": "^4.1.0",
|
"postcss-flexbugs-fixes": "^4.2.1",
|
||||||
"postcss-loader": "^3.0.0",
|
"postcss-loader": "^3.0.0",
|
||||||
"postcss-preset-env": "^6.7.0",
|
"postcss-preset-env": "^6.7.0",
|
||||||
"postcss-safe-parser": "^4.0.1",
|
"postcss-safe-parser": "^5.0.2",
|
||||||
"raf": "^3.4.1",
|
"raf": "^3.4.1",
|
||||||
"react-app-polyfill": "^1.0.6",
|
"react-app-polyfill": "^2.0.0",
|
||||||
"react-dev-utils": "^9.1.0",
|
"react-dev-utils": "^11.0.0",
|
||||||
"resolve": "^1.12.0",
|
"resolve": "^1.19.0",
|
||||||
"sass": "^1.28.0",
|
"sass": "^1.29.0",
|
||||||
"sass-loader": "^10.0.2",
|
"sass-loader": "^10.1.0",
|
||||||
"serve": "^11.3.2",
|
"serve": "^11.3.2",
|
||||||
"stryker-cli": "^1.0.0",
|
"stryker-cli": "^1.0.0",
|
||||||
"style-loader": "^1.2.1",
|
"style-loader": "^2.0.0",
|
||||||
"stylelint": "^13.7.0",
|
"stylelint": "^13.7.2",
|
||||||
"stylelint-config-adidas": "^1.3.0",
|
"stylelint-config-adidas": "^1.3.0",
|
||||||
"stylelint-config-adidas-bem": "^1.2.0",
|
"stylelint-config-adidas-bem": "^1.2.0",
|
||||||
"stylelint-config-recommended-scss": "^4.2.0",
|
"stylelint-config-recommended-scss": "^4.2.0",
|
||||||
"stylelint-scss": "^3.18.0",
|
"stylelint-scss": "^3.18.0",
|
||||||
"sw-precache-webpack-plugin": "^0.11.5",
|
"sw-precache-webpack-plugin": "^1.0.0",
|
||||||
"terser-webpack-plugin": "^2.1.2",
|
"terser-webpack-plugin": "^4.2.3",
|
||||||
"ts-jest": "^26.3.0",
|
"ts-jest": "^26.4.4",
|
||||||
"ts-mockery": "^1.2.0",
|
"ts-mockery": "^1.2.0",
|
||||||
"typescript": "^3.9.7",
|
"typescript": "^4.0.5",
|
||||||
"url-loader": "^2.2.0",
|
"url-loader": "^4.1.1",
|
||||||
"webpack": "^4.41.0",
|
"webpack": "^4.44.2",
|
||||||
"webpack-dev-server": "^3.8.2",
|
"webpack-dev-server": "^3.11.0",
|
||||||
"webpack-manifest-plugin": "^2.2.0",
|
"webpack-manifest-plugin": "^2.2.0",
|
||||||
"whatwg-fetch": "^3.0.0",
|
"whatwg-fetch": "^3.5.0"
|
||||||
"workbox-webpack-plugin": "^4.3.1"
|
|
||||||
},
|
},
|
||||||
"babel": {
|
"babel": {
|
||||||
"presets": [
|
"presets": [
|
||||||
"react-app"
|
[
|
||||||
|
"react-app",
|
||||||
|
{
|
||||||
|
"runtime": "automatic"
|
||||||
|
}
|
||||||
|
]
|
||||||
],
|
],
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"@babel/plugin-proposal-optional-chaining",
|
"@babel/plugin-proposal-optional-chaining",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect, FC } from 'react';
|
import { useEffect, FC } from 'react';
|
||||||
import { Route, Switch } from 'react-router-dom';
|
import { Route, Switch } from 'react-router-dom';
|
||||||
import NotFound from './common/NotFound';
|
import NotFound from './common/NotFound';
|
||||||
import { ServersMap } from './servers/data';
|
import { ServersMap } from './servers/data';
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
faPen as editIcon,
|
faPen as editIcon,
|
||||||
} from '@fortawesome/free-solid-svg-icons';
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import React, { 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 { Location } from 'history';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { ReactNode } from 'react';
|
import { Component, ReactNode } from 'react';
|
||||||
import { Button } from 'reactstrap';
|
import { Button } from 'reactstrap';
|
||||||
import './ErrorHandler.scss';
|
import './ErrorHandler.scss';
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ interface ErrorHandlerState {
|
||||||
const ErrorHandler = (
|
const ErrorHandler = (
|
||||||
{ location }: Window,
|
{ location }: Window,
|
||||||
{ error }: Console,
|
{ error }: Console,
|
||||||
) => class ErrorHandler extends React.Component<any, ErrorHandlerState> {
|
) => class ErrorHandler extends Component<any, ErrorHandlerState> {
|
||||||
public constructor(props: object) {
|
public constructor(props: object) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { hasError: false };
|
this.state = { hasError: false };
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { isEmpty, values } from 'ramda';
|
import { isEmpty, values } from 'ramda';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import ServersListGroup from '../servers/ServersListGroup';
|
import ServersListGroup from '../servers/ServersListGroup';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { faPlus as plusIcon, faChevronDown as arrowIcon, faCogs as cogsIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faPlus as plusIcon, 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 React, { FC, useEffect } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } 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';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { FC, useEffect } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
import { Route, Switch } from 'react-router-dom';
|
import { Route, Switch } from 'react-router-dom';
|
||||||
import { EventData, Swipeable } from 'react-swipeable';
|
import { useSwipeable } from 'react-swipeable';
|
||||||
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';
|
||||||
|
@ -33,7 +33,7 @@ const MenuLayout = (
|
||||||
const burgerClasses = classNames('menu-layout__burger-icon', {
|
const burgerClasses = classNames('menu-layout__burger-icon', {
|
||||||
'menu-layout__burger-icon--active': sidebarVisible,
|
'menu-layout__burger-icon--active': sidebarVisible,
|
||||||
});
|
});
|
||||||
const swipeMenuIfNoModalExists = (callback: () => void) => (e: EventData) => {
|
const swipeMenuIfNoModalExists = (callback: () => void) => (e: any) => {
|
||||||
const swippedOnVisitsTable = (e.event.composedPath() as HTMLElement[]).some(
|
const swippedOnVisitsTable = (e.event.composedPath() as HTMLElement[]).some(
|
||||||
({ classList }) => classList?.contains('visits-table'),
|
({ classList }) => classList?.contains('visits-table'),
|
||||||
);
|
);
|
||||||
|
@ -44,17 +44,17 @@ const MenuLayout = (
|
||||||
|
|
||||||
callback();
|
callback();
|
||||||
};
|
};
|
||||||
|
const swipeableProps = useSwipeable({
|
||||||
|
delta: 40,
|
||||||
|
onSwipedLeft: swipeMenuIfNoModalExists(hideSidebar),
|
||||||
|
onSwipedRight: swipeMenuIfNoModalExists(showSidebar),
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<>
|
||||||
<FontAwesomeIcon icon={burgerIcon} className={burgerClasses} onClick={toggleSidebar} />
|
<FontAwesomeIcon icon={burgerIcon} className={burgerClasses} onClick={toggleSidebar} />
|
||||||
|
|
||||||
<Swipeable
|
<div {...swipeableProps} className="menu-layout__swipeable">
|
||||||
delta={40}
|
|
||||||
className="menu-layout__swipeable"
|
|
||||||
onSwipedLeft={swipeMenuIfNoModalExists(hideSidebar)}
|
|
||||||
onSwipedRight={swipeMenuIfNoModalExists(showSidebar)}
|
|
||||||
>
|
|
||||||
<div className="row menu-layout__swipeable-inner">
|
<div className="row menu-layout__swipeable-inner">
|
||||||
<AsideMenu className="col-lg-2 col-md-3" selectedServer={selectedServer} showOnMobile={sidebarVisible} />
|
<AsideMenu className="col-lg-2 col-md-3" selectedServer={selectedServer} showOnMobile={sidebarVisible} />
|
||||||
<div className="col-lg-10 offset-lg-2 col-md-9 offset-md-3" onClick={() => hideSidebar()}>
|
<div className="col-lg-10 offset-lg-2 col-md-9 offset-md-3" onClick={() => hideSidebar()}>
|
||||||
|
@ -72,8 +72,8 @@ const MenuLayout = (
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Swipeable>
|
</div>
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
}, ServerError);
|
}, ServerError);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import './NoMenuLayout.scss';
|
import './NoMenuLayout.scss';
|
||||||
|
|
||||||
const NoMenuLayout: FC = ({ children }) => <div className="no-menu-wrapper">{children}</div>;
|
const NoMenuLayout: FC = ({ children }) => <div className="no-menu-wrapper">{children}</div>;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
interface NotFoundProps {
|
interface NotFoundProps {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { PropsWithChildren, useEffect } from 'react';
|
import { PropsWithChildren, useEffect } from 'react';
|
||||||
import { RouteComponentProps } from 'react-router';
|
import { RouteComponentProps } from 'react-router';
|
||||||
|
|
||||||
const ScrollToTop = () => ({ location, children }: PropsWithChildren<RouteComponentProps>) => {
|
const ScrollToTop = () => ({ location, children }: PropsWithChildren<RouteComponentProps>) => {
|
||||||
|
@ -6,7 +6,7 @@ const ScrollToTop = () => ({ location, children }: PropsWithChildren<RouteCompon
|
||||||
scrollTo(0, 0);
|
scrollTo(0, 0);
|
||||||
}, [ location ]);
|
}, [ location ]);
|
||||||
|
|
||||||
return <React.Fragment>{children}</React.Fragment>;
|
return <>{children}</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ScrollToTop;
|
export default ScrollToTop;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { pipe } from 'ramda';
|
import { pipe } from 'ramda';
|
||||||
import { ExternalLink } from 'react-external-link';
|
import { ExternalLink } from 'react-external-link';
|
||||||
|
@ -28,7 +27,7 @@ const ShlinkVersions = (
|
||||||
return (
|
return (
|
||||||
<small className={classNames('text-muted', className)}>
|
<small className={classNames('text-muted', className)}>
|
||||||
{isReachableServer(selectedServer) &&
|
{isReachableServer(selectedServer) &&
|
||||||
<React.Fragment>Server: <VersionLink project="shlink" version={selectedServer.printableVersion} /> - </React.Fragment>
|
<>Server: <VersionLink project="shlink" version={selectedServer.printableVersion} /> - </>
|
||||||
}
|
}
|
||||||
Client: <VersionLink project="shlink-web-client" version={normalizedClientVersion} />
|
Client: <VersionLink project="shlink-web-client" version={normalizedClientVersion} />
|
||||||
</small>
|
</small>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Pagination, PaginationItem, PaginationLink } from 'reactstrap';
|
import { Pagination, PaginationItem, PaginationLink } from 'reactstrap';
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { render } from 'react-dom';
|
import { render } from 'react-dom';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
import { BrowserRouter } from 'react-router-dom';
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC, useEffect } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
import { pipe } from 'ramda';
|
import { pipe } from 'ramda';
|
||||||
import { CreateVisit } from '../../visits/types';
|
import { CreateVisit } from '../../visits/types';
|
||||||
import { MercureInfo } from '../reducers/mercureInfo';
|
import { MercureInfo } from '../reducers/mercureInfo';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { RouterProps } from 'react-router';
|
import { RouterProps } from 'react-router';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { faMinusCircle as deleteIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faMinusCircle as deleteIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { useToggle } from '../utils/helpers/hooks';
|
import { useToggle } from '../utils/helpers/hooks';
|
||||||
|
@ -17,14 +17,14 @@ const DeleteServerButton = (DeleteServerModal: FC<DeleteServerModalProps>): FC<D
|
||||||
const [ isModalOpen, , showModal, hideModal ] = useToggle();
|
const [ isModalOpen, , showModal, hideModal ] = useToggle();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<>
|
||||||
<span className={className} onClick={showModal}>
|
<span className={className} onClick={showModal}>
|
||||||
{!children && <FontAwesomeIcon icon={deleteIcon} />}
|
{!children && <FontAwesomeIcon icon={deleteIcon} />}
|
||||||
<span className={textClassName}>{children ?? 'Remove this server'}</span>
|
<span className={textClassName}>{children ?? 'Remove this server'}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<DeleteServerModal server={server} isOpen={isModalOpen} toggle={hideModal} />
|
<DeleteServerModal server={server} isOpen={isModalOpen} toggle={hideModal} />
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
||||||
import { RouterProps } from 'react-router';
|
import { RouterProps } from 'react-router';
|
||||||
import { ServerWithId } from './data';
|
import { ServerWithId } from './data';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { 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 { ServerForm } from './helpers/ServerForm';
|
import { ServerForm } from './helpers/ServerForm';
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { isEmpty, values } from 'ramda';
|
import { isEmpty, values } from 'ramda';
|
||||||
import React from 'react';
|
|
||||||
import { DropdownItem, DropdownMenu, DropdownToggle, UncontrolledDropdown } from 'reactstrap';
|
import { DropdownItem, DropdownMenu, DropdownToggle, UncontrolledDropdown } from 'reactstrap';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import ServersExporter from './services/ServersExporter';
|
import ServersExporter from './services/ServersExporter';
|
||||||
|
@ -19,7 +18,7 @@ const ServersDropdown = (serversExporter: ServersExporter) => ({ servers, select
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<>
|
||||||
{serversList.map(({ name, id }) => (
|
{serversList.map(({ name, id }) => (
|
||||||
<DropdownItem
|
<DropdownItem
|
||||||
key={id}
|
key={id}
|
||||||
|
@ -34,7 +33,7 @@ const ServersDropdown = (serversExporter: ServersExporter) => ({ servers, select
|
||||||
<DropdownItem className="servers-dropdown__export-item" onClick={async () => serversExporter.exportServers()}>
|
<DropdownItem className="servers-dropdown__export-item" onClick={async () => serversExporter.exportServers()}>
|
||||||
Export servers
|
Export servers
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { ListGroup, ListGroupItem } from 'reactstrap';
|
import { ListGroup, ListGroupItem } from 'reactstrap';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faChevronRight as chevronIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faChevronRight as chevronIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import './ServersListGroup.scss';
|
|
||||||
import { ServerWithId } from './data';
|
import { ServerWithId } from './data';
|
||||||
|
import './ServersListGroup.scss';
|
||||||
|
|
||||||
interface ServersListGroup {
|
interface ServersListGroup {
|
||||||
servers: ServerWithId[];
|
servers: ServerWithId[];
|
||||||
|
@ -18,7 +18,7 @@ const ServerListItem = ({ id, name }: { id: string; name: string }) => (
|
||||||
);
|
);
|
||||||
|
|
||||||
const ServersListGroup: FC<ServersListGroup> = ({ servers, children }) => (
|
const ServersListGroup: FC<ServersListGroup> = ({ servers, children }) => (
|
||||||
<React.Fragment>
|
<>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<h5>{children}</h5>
|
<h5>{children}</h5>
|
||||||
</div>
|
</div>
|
||||||
|
@ -27,7 +27,7 @@ const ServersListGroup: FC<ServersListGroup> = ({ servers, children }) => (
|
||||||
{servers.map(({ id, name }) => <ServerListItem key={id} id={id} name={name} />)}
|
{servers.map(({ id, name }) => <ServerListItem key={id} id={id} name={name} />)}
|
||||||
</ListGroup>
|
</ListGroup>
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default ServersListGroup;
|
export default ServersListGroup;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { versionMatch, Versions } from '../../utils/helpers/version';
|
import { versionMatch, Versions } from '../../utils/helpers/version';
|
||||||
import { isReachableServer, SelectedServer } from '../data';
|
import { isReachableServer, SelectedServer } from '../data';
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ const ForServerVersion: FC<ForServerVersionProps> = ({ minVersion, maxVersion, s
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return <React.Fragment>{children}</React.Fragment>;
|
return <>{children}</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ForServerVersion;
|
export default ForServerVersion;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useRef, RefObject, ChangeEvent, MutableRefObject } from 'react';
|
import { useRef, RefObject, ChangeEvent, MutableRefObject } from 'react';
|
||||||
import { UncontrolledTooltip } from 'reactstrap';
|
import { UncontrolledTooltip } from 'reactstrap';
|
||||||
import ServersImporter from '../services/ServersImporter';
|
import ServersImporter from '../services/ServersImporter';
|
||||||
import { ServerData } from '../data';
|
import { ServerData } from '../data';
|
||||||
|
@ -33,7 +33,7 @@ const ImportServersBtn = ({ importServersFromFile }: ServersImporter) => ({
|
||||||
.catch(onImportError);
|
.catch(onImportError);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-outline-secondary mr-2"
|
className="btn btn-outline-secondary mr-2"
|
||||||
|
@ -47,7 +47,7 @@ const ImportServersBtn = ({ importServersFromFile }: ServersImporter) => ({
|
||||||
</UncontrolledTooltip>
|
</UncontrolledTooltip>
|
||||||
|
|
||||||
<input type="file" accept="text/csv" className="create-server__csv-select" ref={ref} onChange={onChange} />
|
<input type="file" accept="text/csv" className="create-server__csv-select" ref={ref} onChange={onChange} />
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import Message from '../../utils/Message';
|
import Message from '../../utils/Message';
|
||||||
import ServersListGroup from '../ServersListGroup';
|
import ServersListGroup from '../ServersListGroup';
|
||||||
|
@ -19,10 +19,10 @@ export const ServerError = (DeleteServerButton: FC<DeleteServerButtonProps>): FC
|
||||||
<Message type="error">
|
<Message type="error">
|
||||||
{!isServerWithId(selectedServer) && 'Could not find this Shlink server.'}
|
{!isServerWithId(selectedServer) && 'Could not find this Shlink server.'}
|
||||||
{isServerWithId(selectedServer) && (
|
{isServerWithId(selectedServer) && (
|
||||||
<React.Fragment>
|
<>
|
||||||
<p>Oops! Could not connect to this Shlink server.</p>
|
<p>Oops! Could not connect to this Shlink server.</p>
|
||||||
Make sure you have internet connection, and the server is properly configured and on-line.
|
Make sure you have internet connection, and the server is properly configured and on-line.
|
||||||
</React.Fragment>
|
</>
|
||||||
)}
|
)}
|
||||||
</Message>
|
</Message>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { HorizontalFormGroup } from '../../utils/HorizontalFormGroup';
|
import { HorizontalFormGroup } from '../../utils/HorizontalFormGroup';
|
||||||
import { handleEventPreventingDefault } from '../../utils/utils';
|
import { handleEventPreventingDefault } from '../../utils/utils';
|
||||||
import { ServerData } from '../data';
|
import { ServerData } from '../data';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC, useEffect } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
import { RouteComponentProps } from 'react-router';
|
import { RouteComponentProps } from 'react-router';
|
||||||
import Message from '../../utils/Message';
|
import Message from '../../utils/Message';
|
||||||
import { isNotFoundServer, SelectedServer } from '../data';
|
import { isNotFoundServer, SelectedServer } from '../data';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC, useEffect } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
|
|
||||||
interface WithoutSelectedServerProps {
|
interface WithoutSelectedServerProps {
|
||||||
resetSelectedServer: Function;
|
resetSelectedServer: Function;
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { Card, CardBody, CardHeader, FormGroup, Input } from 'reactstrap';
|
import { Card, CardBody, CardHeader, FormGroup, Input } from 'reactstrap';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import ToggleSwitch from '../utils/ToggleSwitch';
|
import ToggleSwitch from '../utils/ToggleSwitch';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import NoMenuLayout from '../common/NoMenuLayout';
|
import NoMenuLayout from '../common/NoMenuLayout';
|
||||||
|
|
||||||
const Settings = (RealTimeUpdates: FC) => () => (
|
const Settings = (RealTimeUpdates: FC) => () => (
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { faAngleDoubleDown as downIcon, faAngleDoubleUp as upIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faAngleDoubleDown as downIcon, faAngleDoubleUp as upIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { isEmpty, pipe, replace, trim } from 'ramda';
|
import { isEmpty, pipe, replace, trim } from 'ramda';
|
||||||
import React, { FC, useState } from 'react';
|
import { FC, useState } from 'react';
|
||||||
import { Collapse, FormGroup, Input } from 'reactstrap';
|
import { Collapse, FormGroup, Input } from 'reactstrap';
|
||||||
import { InputType } from 'reactstrap/lib/Input';
|
import { InputType } from 'reactstrap/lib/Input';
|
||||||
import * as m from 'moment';
|
import * as m from 'moment';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { Pagination, PaginationItem, PaginationLink } from 'reactstrap';
|
import { Pagination, PaginationItem, PaginationLink } from 'reactstrap';
|
||||||
import { pageIsEllipsis, keyForPage, progressivePagination, prettifyPageNumber } from '../utils/helpers/pagination';
|
import { pageIsEllipsis, keyForPage, progressivePagination, prettifyPageNumber } from '../utils/helpers/pagination';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { faTags as tagsIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faTags as tagsIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { isEmpty, pipe } from 'ramda';
|
import { isEmpty, pipe } from 'ramda';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import SearchField from '../utils/SearchField';
|
import SearchField from '../utils/SearchField';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { ShlinkShortUrlsResponse } from '../utils/services/types';
|
import { ShlinkShortUrlsResponse } from '../utils/services/types';
|
||||||
import Paginator from './Paginator';
|
import Paginator from './Paginator';
|
||||||
import { ShortUrlsListProps, WithList } from './ShortUrlsList';
|
import { ShortUrlsListProps, WithList } from './ShortUrlsList';
|
||||||
|
@ -20,13 +20,13 @@ const ShortUrls = (SearchBar: FC, ShortUrlsList: FC<ShortUrlsListProps & WithLis
|
||||||
}, [ serverId, page ]);
|
}, [ serverId, page ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<>
|
||||||
<div className="form-group"><SearchBar /></div>
|
<div className="form-group"><SearchBar /></div>
|
||||||
<div>
|
<div>
|
||||||
<ShortUrlsList {...props} shortUrlsList={data} key={urlsListKey} />
|
<ShortUrlsList {...props} shortUrlsList={data} key={urlsListKey} />
|
||||||
<Paginator paginator={pagination} serverId={serverId} />
|
<Paginator paginator={pagination} serverId={serverId} />
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { faCaretDown as caretDownIcon, faCaretUp as caretUpIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faCaretDown as caretDownIcon, faCaretUp as caretUpIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { head, isEmpty, keys, values } from 'ramda';
|
import { head, isEmpty, keys, values } from 'ramda';
|
||||||
import React, { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
import { RouteComponentProps } from 'react-router';
|
import { RouteComponentProps } from 'react-router';
|
||||||
import SortingDropdown from '../utils/SortingDropdown';
|
import SortingDropdown from '../utils/SortingDropdown';
|
||||||
|
@ -107,7 +107,7 @@ const ShortUrlsList = (ShortUrlsRow: FC<ShortUrlsRowProps>) => boundToMercureHub
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<>
|
||||||
<div className="d-block d-md-none mb-3">
|
<div className="d-block d-md-none mb-3">
|
||||||
<SortingDropdown
|
<SortingDropdown
|
||||||
items={SORTABLE_FIELDS}
|
items={SORTABLE_FIELDS}
|
||||||
|
@ -154,7 +154,7 @@ const ShortUrlsList = (ShortUrlsRow: FC<ShortUrlsRowProps>) => boundToMercureHub
|
||||||
{renderShortUrls()}
|
{renderShortUrls()}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
}, () => 'https://shlink.io/new-visit');
|
}, () => 'https://shlink.io/new-visit');
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faInfoCircle as infoIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faInfoCircle as infoIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { Modal, ModalBody, ModalHeader } from 'reactstrap';
|
import { Modal, ModalBody, ModalHeader } from 'reactstrap';
|
||||||
|
@ -41,12 +40,12 @@ const UseExistingIfFoundInfoIcon = () => {
|
||||||
const [ isModalOpen, toggleModal ] = useToggle();
|
const [ isModalOpen, toggleModal ] = useToggle();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<>
|
||||||
<span title="What does this mean?">
|
<span title="What does this mean?">
|
||||||
<FontAwesomeIcon icon={infoIcon} style={{ cursor: 'pointer' }} onClick={toggleModal} />
|
<FontAwesomeIcon icon={infoIcon} style={{ cursor: 'pointer' }} onClick={toggleModal} />
|
||||||
</span>
|
</span>
|
||||||
<InfoModal isOpen={isModalOpen} toggle={toggleModal} />
|
<InfoModal isOpen={isModalOpen} toggle={toggleModal} />
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { faCopy as copyIcon } from '@fortawesome/free-regular-svg-icons';
|
import { faCopy as copyIcon } from '@fortawesome/free-regular-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { isNil } from 'ramda';
|
import { isNil } from 'ramda';
|
||||||
import React, { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||||
import { Card, CardBody, Tooltip } from 'reactstrap';
|
import { Card, CardBody, Tooltip } from 'reactstrap';
|
||||||
import { ShortUrlCreation } from '../reducers/shortUrlCreation';
|
import { ShortUrlCreation } from '../reducers/shortUrlCreation';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
||||||
import { identity, pipe } from 'ramda';
|
import { identity, pipe } from 'ramda';
|
||||||
import { ShortUrlDeletion } from '../reducers/shortUrlDeletion';
|
import { ShortUrlDeletion } from '../reducers/shortUrlDeletion';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { ChangeEvent, useState } from 'react';
|
import { ChangeEvent, useState } from 'react';
|
||||||
import { Modal, ModalBody, ModalFooter, ModalHeader, FormGroup, Input, UncontrolledTooltip } from 'reactstrap';
|
import { Modal, ModalBody, ModalFooter, ModalHeader, FormGroup, Input, UncontrolledTooltip } from 'reactstrap';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faInfoCircle as infoIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faInfoCircle as infoIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
@ -17,10 +17,10 @@ interface EditMetaModalConnectProps extends ShortUrlModalProps {
|
||||||
editShortUrlMeta: (shortCode: string, domain: OptionalString, meta: Nullable<ShortUrlMeta>) => Promise<void>;
|
editShortUrlMeta: (shortCode: string, domain: OptionalString, meta: Nullable<ShortUrlMeta>) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dateOrUndefined = (shortUrl: ShortUrl | undefined, dateName: 'validSince' | 'validUntil') => {
|
const dateOrNull = (shortUrl: ShortUrl | undefined, dateName: 'validSince' | 'validUntil') => {
|
||||||
const date = shortUrl?.meta?.[dateName];
|
const date = shortUrl?.meta?.[dateName];
|
||||||
|
|
||||||
return date ? moment(date) : undefined;
|
return date ? moment(date) : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const EditMetaModal = (
|
const EditMetaModal = (
|
||||||
|
@ -28,8 +28,8 @@ const EditMetaModal = (
|
||||||
) => {
|
) => {
|
||||||
const { saving, error } = shortUrlMeta;
|
const { saving, error } = shortUrlMeta;
|
||||||
const url = shortUrl && (shortUrl.shortUrl || '');
|
const url = shortUrl && (shortUrl.shortUrl || '');
|
||||||
const [ validSince, setValidSince ] = useState(dateOrUndefined(shortUrl, 'validSince'));
|
const [ validSince, setValidSince ] = useState(dateOrNull(shortUrl, 'validSince'));
|
||||||
const [ validUntil, setValidUntil ] = useState(dateOrUndefined(shortUrl, 'validUntil'));
|
const [ validUntil, setValidUntil ] = useState(dateOrNull(shortUrl, 'validUntil'));
|
||||||
const [ maxVisits, setMaxVisits ] = useState(shortUrl?.meta?.maxVisits);
|
const [ maxVisits, setMaxVisits ] = useState(shortUrl?.meta?.maxVisits);
|
||||||
|
|
||||||
const close = pipe(resetShortUrlMeta, toggle);
|
const close = pipe(resetShortUrlMeta, toggle);
|
||||||
|
@ -56,7 +56,7 @@ const EditMetaModal = (
|
||||||
selected={validSince}
|
selected={validSince}
|
||||||
maxDate={validUntil}
|
maxDate={validUntil}
|
||||||
isClearable
|
isClearable
|
||||||
onChange={setValidSince as any}
|
onChange={setValidSince}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Modal, ModalBody, ModalFooter, ModalHeader, FormGroup, Input, Button } from 'reactstrap';
|
import { Modal, ModalBody, ModalFooter, ModalHeader, FormGroup, Input, Button } from 'reactstrap';
|
||||||
import { ExternalLink } from 'react-external-link';
|
import { ExternalLink } from 'react-external-link';
|
||||||
import { ShortUrlEdition } from '../reducers/shortUrlEdition';
|
import { ShortUrlEdition } from '../reducers/shortUrlEdition';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
||||||
import { ExternalLink } from 'react-external-link';
|
import { ExternalLink } from 'react-external-link';
|
||||||
import { ShortUrlTags } from '../reducers/shortUrlTags';
|
import { ShortUrlTags } from '../reducers/shortUrlTags';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { Modal, ModalBody, ModalHeader } from 'reactstrap';
|
import { Modal, ModalBody, ModalHeader } from 'reactstrap';
|
||||||
import { ExternalLink } from 'react-external-link';
|
import { ExternalLink } from 'react-external-link';
|
||||||
import { ShortUrlModalProps } from '../data';
|
import { ShortUrlModalProps } from '../data';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { Modal, ModalBody, ModalHeader } from 'reactstrap';
|
import { Modal, ModalBody, ModalHeader } from 'reactstrap';
|
||||||
import { ExternalLink } from 'react-external-link';
|
import { ExternalLink } from 'react-external-link';
|
||||||
import { ShortUrlModalProps } from '../data';
|
import { ShortUrlModalProps } from '../data';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faInfoCircle as infoIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faInfoCircle as infoIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { UncontrolledTooltip } from 'reactstrap';
|
import { UncontrolledTooltip } from 'reactstrap';
|
||||||
|
@ -32,7 +32,7 @@ const ShortUrlVisitsCount = ({ visitsCount, shortUrl, selectedServer, active = f
|
||||||
const tooltipRef = useRef<HTMLElement | null>();
|
const tooltipRef = useRef<HTMLElement | null>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<>
|
||||||
<span className="indivisible">
|
<span className="indivisible">
|
||||||
{visitsLink}
|
{visitsLink}
|
||||||
<small
|
<small
|
||||||
|
@ -50,7 +50,7 @@ const ShortUrlVisitsCount = ({ visitsCount, shortUrl, selectedServer, active = f
|
||||||
<UncontrolledTooltip target={(() => tooltipRef.current) as any} placement="bottom">
|
<UncontrolledTooltip target={(() => tooltipRef.current) as any} placement="bottom">
|
||||||
This short URL will not accept more than <b>{prettifiedMaxVisits}</b> visits.
|
This short URL will not accept more than <b>{prettifiedMaxVisits}</b> visits.
|
||||||
</UncontrolledTooltip>
|
</UncontrolledTooltip>
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { isEmpty } from 'ramda';
|
import { isEmpty } from 'ramda';
|
||||||
import React, { FC, useEffect, useRef } from 'react';
|
import { FC, useEffect, useRef } from 'react';
|
||||||
import Moment from 'react-moment';
|
import Moment from 'react-moment';
|
||||||
import { ExternalLink } from 'react-external-link';
|
import { ExternalLink } from 'react-external-link';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
faLink as linkIcon,
|
faLink as linkIcon,
|
||||||
} from '@fortawesome/free-solid-svg-icons';
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { ButtonDropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap';
|
import { ButtonDropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap';
|
||||||
import { useToggle } from '../../utils/helpers/hooks';
|
import { useToggle } from '../../utils/helpers/hooks';
|
||||||
import { ShortUrl, ShortUrlModalProps } from '../data';
|
import { ShortUrl, ShortUrlModalProps } from '../data';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { isServerWithId, SelectedServer, ServerWithId } from '../../servers/data';
|
import { isServerWithId, SelectedServer, ServerWithId } from '../../servers/data';
|
||||||
import { ShortUrl } from '../data';
|
import { ShortUrl } from '../data';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Card, CardHeader, CardBody, Button, Collapse } from 'reactstrap';
|
import { Card, CardHeader, CardBody, Button, Collapse } from 'reactstrap';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faTrash as deleteIcon, faPencilAlt as editIcon, faLink, faEye } from '@fortawesome/free-solid-svg-icons';
|
import { faTrash as deleteIcon, faPencilAlt as editIcon, faLink, faEye } from '@fortawesome/free-solid-svg-icons';
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { prettify } from '../utils/helpers/numbers';
|
import { prettify } from '../utils/helpers/numbers';
|
||||||
import { useToggle } from '../utils/helpers/hooks';
|
import { useToggle } from '../utils/helpers/hooks';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { splitEvery } from 'ramda';
|
import { splitEvery } from 'ramda';
|
||||||
import Message from '../utils/Message';
|
import Message from '../utils/Message';
|
||||||
import SearchField from '../utils/SearchField';
|
import SearchField from '../utils/SearchField';
|
||||||
|
@ -48,7 +48,7 @@ const TagsList = (TagCard: FC<TagCardProps>) => boundToMercureHub((
|
||||||
const tagsGroups = splitEvery(ceil(tagsCount / TAGS_GROUPS_AMOUNT), tagsList.filteredTags);
|
const tagsGroups = splitEvery(ceil(tagsCount / TAGS_GROUPS_AMOUNT), tagsList.filteredTags);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<>
|
||||||
{tagsGroups.map((group, index) => (
|
{tagsGroups.map((group, index) => (
|
||||||
<div key={index} className="col-md-6 col-xl-3">
|
<div key={index} className="col-md-6 col-xl-3">
|
||||||
{group.map((tag) => (
|
{group.map((tag) => (
|
||||||
|
@ -63,17 +63,17 @@ const TagsList = (TagCard: FC<TagCardProps>) => boundToMercureHub((
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<>
|
||||||
{!tagsList.loading && <SearchField className="mb-3" placeholder="Search tags..." onChange={filterTags} />}
|
{!tagsList.loading && <SearchField className="mb-3" placeholder="Search tags..." onChange={filterTags} />}
|
||||||
<div className="row">
|
<div className="row">
|
||||||
{renderContent()}
|
{renderContent()}
|
||||||
</div>
|
</div>
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
}, () => 'https://shlink.io/new-visit');
|
}, () => 'https://shlink.io/new-visit');
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
||||||
import { TagDeletion } from '../reducers/tagDelete';
|
import { TagDeletion } from '../reducers/tagDelete';
|
||||||
import { TagModalProps } from '../data';
|
import { TagModalProps } from '../data';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Modal, ModalBody, ModalFooter, ModalHeader, Popover } from 'reactstrap';
|
import { Modal, ModalBody, ModalFooter, ModalHeader, Popover } from 'reactstrap';
|
||||||
import { ChromePicker } from 'react-color';
|
import { ChromePicker } from 'react-color';
|
||||||
import { faPalette as colorIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faPalette as colorIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
@ -21,14 +21,14 @@ const EditTagModal = ({ getColorForKey }: ColorGenerator) => (
|
||||||
) => {
|
) => {
|
||||||
const [ newTagName, setNewTagName ] = useState(tag);
|
const [ newTagName, setNewTagName ] = useState(tag);
|
||||||
const [ color, setColor ] = useState(getColorForKey(tag));
|
const [ color, setColor ] = useState(getColorForKey(tag));
|
||||||
const [ showColorPicker, toggleColorPicker ] = useToggle();
|
const [ showColorPicker, toggleColorPicker, , hideColorPicker ] = useToggle();
|
||||||
const saveTag = handleEventPreventingDefault(async () => editTag(tag, newTagName, color)
|
const saveTag = handleEventPreventingDefault(async () => editTag(tag, newTagName, color)
|
||||||
.then(() => tagEdited(tag, newTagName, color))
|
.then(() => tagEdited(tag, newTagName, color))
|
||||||
.then(toggle)
|
.then(toggle)
|
||||||
.catch(() => {}));
|
.catch(() => {}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} toggle={toggle} centered>
|
<Modal isOpen={isOpen} toggle={toggle} centered onClosed={hideColorPicker}>
|
||||||
<form onSubmit={saveTag}>
|
<form onSubmit={saveTag}>
|
||||||
<ModalHeader toggle={toggle}>Edit tag</ModalHeader>
|
<ModalHeader toggle={toggle}>Edit tag</ModalHeader>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import ColorGenerator from '../../utils/services/ColorGenerator';
|
import ColorGenerator from '../../utils/services/ColorGenerator';
|
||||||
import './Tag.scss';
|
import './Tag.scss';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import ColorGenerator from '../../utils/services/ColorGenerator';
|
import ColorGenerator from '../../utils/services/ColorGenerator';
|
||||||
import './TagBullet.scss';
|
import './TagBullet.scss';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { ChangeEvent, useEffect } from 'react';
|
import { ChangeEvent, useEffect } from 'react';
|
||||||
import TagsInput, { RenderInputProps, RenderTagProps } from 'react-tagsinput';
|
import TagsInput, { RenderInputProps, RenderTagProps } from 'react-tagsinput';
|
||||||
import Autosuggest, { ChangeEvent as AutoChangeEvent, SuggestionSelectedEventData } from 'react-autosuggest';
|
import Autosuggest, { ChangeEvent as AutoChangeEvent, SuggestionSelectedEventData } from 'react-autosuggest';
|
||||||
import ColorGenerator from '../../utils/services/ColorGenerator';
|
import ColorGenerator from '../../utils/services/ColorGenerator';
|
||||||
|
@ -50,10 +50,10 @@ const TagsSelector = (colorGenerator: ColorGenerator) => (
|
||||||
shouldRenderSuggestions={(value: string) => value.trim().length > 0}
|
shouldRenderSuggestions={(value: string) => value.trim().length > 0}
|
||||||
getSuggestionValue={(suggestion) => suggestion}
|
getSuggestionValue={(suggestion) => suggestion}
|
||||||
renderSuggestion={(suggestion) => (
|
renderSuggestion={(suggestion) => (
|
||||||
<React.Fragment>
|
<>
|
||||||
<TagBullet tag={suggestion} colorGenerator={colorGenerator} />
|
<TagBullet tag={suggestion} colorGenerator={colorGenerator} />
|
||||||
{suggestion}
|
{suggestion}
|
||||||
</React.Fragment>
|
</>
|
||||||
)}
|
)}
|
||||||
onSuggestionsFetchRequested={() => {}}
|
onSuggestionsFetchRequested={() => {}}
|
||||||
onSuggestionsClearRequested={() => {}}
|
onSuggestionsClearRequested={() => {}}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { ChangeEvent, FC } from 'react';
|
import { ChangeEvent, FC } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import BooleanControl, { BooleanControlProps } from './BooleanControl';
|
import BooleanControl, { BooleanControlProps } from './BooleanControl';
|
||||||
|
|
||||||
const Checkbox: FC<BooleanControlProps> = (props) => <BooleanControl type="checkbox" {...props} />;
|
const Checkbox: FC<BooleanControlProps> = (props) => <BooleanControl type="checkbox" {...props} />;
|
||||||
|
|
|
@ -1,26 +1,45 @@
|
||||||
import React, { Component, RefObject } from 'react';
|
import { useRef } from 'react';
|
||||||
import { isNil } from 'ramda';
|
import { isNil, dissoc } from 'ramda';
|
||||||
import DatePicker, { ReactDatePickerProps } from 'react-datepicker';
|
import DatePicker, { ReactDatePickerProps } from 'react-datepicker';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faCalendarAlt as calendarIcon } from '@fortawesome/free-regular-svg-icons';
|
import { faCalendarAlt as calendarIcon } from '@fortawesome/free-regular-svg-icons';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import moment from 'moment';
|
||||||
import './DateInput.scss';
|
import './DateInput.scss';
|
||||||
|
|
||||||
export interface DateInputProps extends ReactDatePickerProps {
|
interface DatePropsInterface {
|
||||||
ref?: RefObject<Component<ReactDatePickerProps> & { input: HTMLInputElement }>;
|
endDate?: moment.Moment | null;
|
||||||
|
maxDate?: moment.Moment | null;
|
||||||
|
minDate?: moment.Moment | null;
|
||||||
|
selected?: moment.Moment | null;
|
||||||
|
startDate?: moment.Moment | null;
|
||||||
|
onChange?: (date: moment.Moment | null) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type DateInputProps = DatePropsInterface & Omit<ReactDatePickerProps, keyof DatePropsInterface>;
|
||||||
|
|
||||||
|
const transformProps = (props: DateInputProps): ReactDatePickerProps => ({
|
||||||
|
...dissoc('ref', props),
|
||||||
|
endDate: props.endDate?.toDate(),
|
||||||
|
maxDate: props.maxDate?.toDate(),
|
||||||
|
minDate: props.minDate?.toDate(),
|
||||||
|
selected: props.selected?.toDate(),
|
||||||
|
startDate: props.startDate?.toDate(),
|
||||||
|
onChange: (date: Date | null) => props.onChange?.(date && moment(date)),
|
||||||
|
});
|
||||||
|
|
||||||
const DateInput = (props: DateInputProps) => {
|
const DateInput = (props: DateInputProps) => {
|
||||||
const { className, isClearable, selected, ref = React.createRef() } = props;
|
const { className, isClearable, selected } = props;
|
||||||
const showCalendarIcon = !isClearable || isNil(selected);
|
const showCalendarIcon = !isClearable || isNil(selected);
|
||||||
|
const ref = useRef<{ input: HTMLInputElement }>();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="date-input-container">
|
<div className="date-input-container">
|
||||||
<DatePicker
|
<DatePicker
|
||||||
{...props}
|
{...transformProps(props)}
|
||||||
|
dateFormat="yyyy-MM-dd"
|
||||||
className={classNames('date-input-container__input form-control', className)}
|
className={classNames('date-input-container__input form-control', className)}
|
||||||
dateFormat="YYYY-MM-DD"
|
// @ts-expect-error
|
||||||
readOnly
|
|
||||||
ref={ref}
|
ref={ref}
|
||||||
/>
|
/>
|
||||||
{showCalendarIcon && (
|
{showCalendarIcon && (
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import DateInput from './DateInput';
|
import DateInput from './DateInput';
|
||||||
import './DateRangeRow.scss';
|
import './DateRangeRow.scss';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { InputType } from 'reactstrap/lib/Input';
|
import { InputType } from 'reactstrap/lib/Input';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { Card } from 'reactstrap';
|
import { Card } from 'reactstrap';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { faCircleNotch as preloader } from '@fortawesome/free-solid-svg-icons';
|
import { faCircleNotch as preloader } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { DropdownItem, DropdownMenu, DropdownToggle, UncontrolledDropdown } from 'reactstrap';
|
import { DropdownItem, DropdownMenu, DropdownToggle, UncontrolledDropdown } from 'reactstrap';
|
||||||
|
|
||||||
interface PaginationDropdownProps {
|
interface PaginationDropdownProps {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faSearch as searchIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faSearch as searchIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { UncontrolledDropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
|
import { UncontrolledDropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
|
||||||
import { toPairs } from 'ramda';
|
import { toPairs } from 'ramda';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import BooleanControl, { BooleanControlProps } from './BooleanControl';
|
import BooleanControl, { BooleanControlProps } from './BooleanControl';
|
||||||
|
|
||||||
const ToggleSwitch: FC<BooleanControlProps> = (props) => <BooleanControl type="switch" {...props} />;
|
const ToggleSwitch: FC<BooleanControlProps> = (props) => <BooleanControl type="switch" {...props} />;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import qs from 'qs';
|
import qs from 'qs';
|
||||||
import { RouteComponentProps } from 'react-router';
|
import { RouteComponentProps } from 'react-router';
|
||||||
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { UncontrolledTooltip } from 'reactstrap';
|
import { UncontrolledTooltip } from 'reactstrap';
|
||||||
import Moment from 'react-moment';
|
import Moment from 'react-moment';
|
||||||
import React from 'react';
|
|
||||||
import { ExternalLink } from 'react-external-link';
|
import { ExternalLink } from 'react-external-link';
|
||||||
import { ShortUrlDetail } from './reducers/shortUrlDetail';
|
import { ShortUrlDetail } from './reducers/shortUrlDetail';
|
||||||
import { ShortUrlVisits } from './reducers/shortUrlVisits';
|
import { ShortUrlVisits } from './reducers/shortUrlVisits';
|
||||||
|
@ -30,9 +29,9 @@ const ShortUrlVisitsHeader = ({ shortUrlDetail, shortUrlVisits, goBack }: ShortU
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
const visitsStatsTitle = (
|
const visitsStatsTitle = (
|
||||||
<React.Fragment>
|
<>
|
||||||
Visits for <ExternalLink href={shortLink} />
|
Visits for <ExternalLink href={shortLink} />
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { RouteComponentProps } from 'react-router';
|
import { RouteComponentProps } from 'react-router';
|
||||||
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub';
|
||||||
import ColorGenerator from '../utils/services/ColorGenerator';
|
import ColorGenerator from '../utils/services/ColorGenerator';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import Tag from '../tags/helpers/Tag';
|
import Tag from '../tags/helpers/Tag';
|
||||||
import ColorGenerator from '../utils/services/ColorGenerator';
|
import ColorGenerator from '../utils/services/ColorGenerator';
|
||||||
import VisitsHeader from './VisitsHeader';
|
import VisitsHeader from './VisitsHeader';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Button, Card } from 'reactstrap';
|
import { Button, Card } from 'reactstrap';
|
||||||
import React, { FC, ReactNode } from 'react';
|
import { FC, ReactNode } from 'react';
|
||||||
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 ShortUrlVisitsCount from '../short-urls/helpers/ShortUrlVisitsCount';
|
import ShortUrlVisitsCount from '../short-urls/helpers/ShortUrlVisitsCount';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { isEmpty, propEq, values } from 'ramda';
|
import { isEmpty, propEq, values } from 'ramda';
|
||||||
import React, { useState, useEffect, useMemo, FC } from 'react';
|
import { useState, useEffect, useMemo, FC } from 'react';
|
||||||
import { Button, Card, Collapse, Progress } from 'reactstrap';
|
import { Button, Card, Collapse, Progress } from 'reactstrap';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
@ -186,7 +186,7 @@ const VisitsStats: FC<VisitsStatsProps> = (
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<>
|
||||||
{children}
|
{children}
|
||||||
|
|
||||||
<section className="mt-4">
|
<section className="mt-4">
|
||||||
|
@ -244,7 +244,7 @@ const VisitsStats: FC<VisitsStatsProps> = (
|
||||||
<section>
|
<section>
|
||||||
{renderVisitsContent()}
|
{renderVisitsContent()}
|
||||||
</section>
|
</section>
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import Moment from 'react-moment';
|
import Moment from 'react-moment';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { min, splitEvery } from 'ramda';
|
import { min, splitEvery } from 'ramda';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
import { Doughnut, HorizontalBar } from 'react-chartjs-2';
|
import { Doughnut, HorizontalBar } from 'react-chartjs-2';
|
||||||
import { keys, values } from 'ramda';
|
import { keys, values } from 'ramda';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Card, CardHeader, CardBody, CardFooter } from 'reactstrap';
|
import { Card, CardHeader, CardBody, CardFooter } from 'reactstrap';
|
||||||
import React, { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
import DefaultChart, { DefaultChartProps } from './DefaultChart';
|
import DefaultChart, { DefaultChartProps } from './DefaultChart';
|
||||||
import './GraphCard.scss';
|
import './GraphCard.scss';
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState, useMemo } from 'react';
|
import { useState, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardHeader,
|
CardHeader,
|
||||||
|
@ -199,7 +199,6 @@ const LineChartCard = (
|
||||||
},
|
},
|
||||||
tooltips: {
|
tooltips: {
|
||||||
intersect: false,
|
intersect: false,
|
||||||
// @ts-expect-error
|
|
||||||
axis: 'x',
|
axis: 'x',
|
||||||
callbacks: {
|
callbacks: {
|
||||||
label: renderNonDoughnutChartLabel('yLabel'),
|
label: renderNonDoughnutChartLabel('yLabel'),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { Modal, ModalBody } from 'reactstrap';
|
import { Modal, ModalBody } from 'reactstrap';
|
||||||
import { Map, TileLayer, Marker, Popup } from 'react-leaflet';
|
import { MapContainer, TileLayer, Marker, Popup, MapContainerProps } from 'react-leaflet';
|
||||||
import { prop } from 'ramda';
|
import { prop } from 'ramda';
|
||||||
import { CityStats } from '../types';
|
import { CityStats } from '../types';
|
||||||
import './MapModal.scss';
|
import './MapModal.scss';
|
||||||
|
@ -19,7 +19,7 @@ const OpenStreetMapTile: FC = () => (
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const calculateMapProps = (locations: CityStats[]): any => {
|
const calculateMapProps = (locations: CityStats[]): MapContainerProps => {
|
||||||
if (locations.length === 0) {
|
if (locations.length === 0) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -42,14 +42,14 @@ const MapModal = ({ toggle, isOpen, title, locations = [] }: MapModalProps) => (
|
||||||
{title}
|
{title}
|
||||||
<button type="button" className="close" onClick={toggle}>×</button>
|
<button type="button" className="close" onClick={toggle}>×</button>
|
||||||
</h3>
|
</h3>
|
||||||
<Map {...calculateMapProps(locations)}>
|
<MapContainer {...calculateMapProps(locations)}>
|
||||||
<OpenStreetMapTile />
|
<OpenStreetMapTile />
|
||||||
{locations.map(({ cityName, latLong, count }, index) => (
|
{locations.map(({ cityName, latLong, count }, index) => (
|
||||||
<Marker key={index} position={latLong}>
|
<Marker key={index} position={latLong}>
|
||||||
<Popup><b>{count}</b> visit{count > 1 ? 's' : ''} from <b>{cityName}</b></Popup>
|
<Popup><b>{count}</b> visit{count > 1 ? 's' : ''} from <b>{cityName}</b></Popup>
|
||||||
</Marker>
|
</Marker>
|
||||||
))}
|
))}
|
||||||
</Map>
|
</MapContainer>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useRef, useState } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { faMapMarkedAlt as mapIcon } from '@fortawesome/free-solid-svg-icons';
|
import { faMapMarkedAlt as mapIcon } from '@fortawesome/free-solid-svg-icons';
|
||||||
import { Dropdown, DropdownItem, DropdownMenu, UncontrolledTooltip } from 'reactstrap';
|
import { Dropdown, DropdownItem, DropdownMenu, UncontrolledTooltip } from 'reactstrap';
|
||||||
|
@ -36,7 +36,7 @@ const OpenMapModalBtn = ({ modalTitle, activeCities, locations = [] }: OpenMapMo
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<>
|
||||||
<button className="btn btn-link open-map-modal-btn__btn" ref={buttonRef as any} onClick={onClick}>
|
<button className="btn btn-link open-map-modal-btn__btn" ref={buttonRef as any} onClick={onClick}>
|
||||||
<FontAwesomeIcon icon={mapIcon} />
|
<FontAwesomeIcon icon={mapIcon} />
|
||||||
</button>
|
</button>
|
||||||
|
@ -48,7 +48,7 @@ const OpenMapModalBtn = ({ modalTitle, activeCities, locations = [] }: OpenMapMo
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
<MapModal toggle={closeMap} isOpen={mapIsOpened} title={modalTitle} locations={locationsToShow} />
|
<MapModal toggle={closeMap} isOpen={mapIsOpened} title={modalTitle} locations={locationsToShow} />
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { fromPairs, pipe, reverse, sortBy, splitEvery, toLower, toPairs, type, zipObj } from 'ramda';
|
import { fromPairs, pipe, reverse, sortBy, splitEvery, toLower, toPairs, type, zipObj } from 'ramda';
|
||||||
import SortingDropdown from '../../utils/SortingDropdown';
|
import SortingDropdown from '../../utils/SortingDropdown';
|
||||||
import PaginationDropdown from '../../utils/PaginationDropdown';
|
import PaginationDropdown from '../../utils/PaginationDropdown';
|
||||||
|
@ -94,7 +94,7 @@ const SortableBarGraph = ({
|
||||||
);
|
);
|
||||||
const activeCities = Object.keys(currentPageStats);
|
const activeCities = Object.keys(currentPageStats);
|
||||||
const computeTitle = () => (
|
const computeTitle = () => (
|
||||||
<React.Fragment>
|
<>
|
||||||
{title}
|
{title}
|
||||||
<div className="float-right">
|
<div className="float-right">
|
||||||
<SortingDropdown
|
<SortingDropdown
|
||||||
|
@ -127,7 +127,7 @@ const SortableBarGraph = ({
|
||||||
{extraHeaderContent(pagination ? activeCities : undefined)}
|
{extraHeaderContent(pagination ? activeCities : undefined)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -2,7 +2,8 @@ const jestConfig = require(`${__dirname}/jest.config.js`);
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mutate: jestConfig.collectCoverageFrom,
|
mutate: jestConfig.collectCoverageFrom,
|
||||||
mutator: 'typescript',
|
checkers: [ 'typescript' ],
|
||||||
|
tsconfigFile: 'tsconfig.json',
|
||||||
testRunner: 'jest',
|
testRunner: 'jest',
|
||||||
reporters: [ 'progress', 'clear-text' ],
|
reporters: [ 'progress', 'clear-text' ],
|
||||||
coverageAnalysis: 'off',
|
coverageAnalysis: 'off',
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import { Route } from 'react-router-dom';
|
import { Route } from 'react-router-dom';
|
||||||
import { identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import React from 'react';
|
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import asideMenuCreator from '../../src/common/AsideMenu';
|
import asideMenuCreator from '../../src/common/AsideMenu';
|
||||||
import { ServerWithId } from '../../src/servers/data';
|
import { ServerWithId } from '../../src/servers/data';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import { Button } from 'reactstrap';
|
import { Button } from 'reactstrap';
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import React from 'react';
|
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import Home, { HomeProps } from '../../src/common/Home';
|
import Home, { HomeProps } from '../../src/common/Home';
|
||||||
import { ServerWithId } from '../../src/servers/data';
|
import { ServerWithId } from '../../src/servers/data';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import NotFound from '../../src/common/NotFound';
|
import NotFound from '../../src/common/NotFound';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import { RouteComponentProps } from 'react-router';
|
import { RouteComponentProps } from 'react-router';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import ShlinkVersions, { ShlinkVersionsProps } from '../../src/common/ShlinkVersions';
|
import ShlinkVersions, { ShlinkVersionsProps } from '../../src/common/ShlinkVersions';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import { identity } from 'ramda';
|
import { identity } from 'ramda';
|
||||||
import { PaginationItem } from 'reactstrap';
|
import { PaginationItem } from 'reactstrap';
|
||||||
|
@ -8,7 +7,6 @@ import { ELLIPSIS } from '../../src/utils/helpers/pagination';
|
||||||
describe('<SimplePaginator />', () => {
|
describe('<SimplePaginator />', () => {
|
||||||
let wrapper: ShallowWrapper;
|
let wrapper: ShallowWrapper;
|
||||||
const createWrapper = (pagesCount: number, currentPage = 1) => {
|
const createWrapper = (pagesCount: number, currentPage = 1) => {
|
||||||
// @ts-expect-error
|
|
||||||
wrapper = shallow(<SimplePaginator pagesCount={pagesCount} currentPage={currentPage} setCurrentPage={identity} />);
|
wrapper = shallow(<SimplePaginator pagesCount={pagesCount} currentPage={currentPage} setCurrentPage={identity} />);
|
||||||
|
|
||||||
return wrapper;
|
return wrapper;
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
import React from 'react';
|
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import { identity } from 'ramda';
|
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import { History } from 'history';
|
import { History } from 'history';
|
||||||
import createServerConstruct from '../../src/servers/CreateServer';
|
import createServerConstruct from '../../src/servers/CreateServer';
|
||||||
|
@ -18,9 +16,7 @@ describe('<CreateServer />', () => {
|
||||||
.mockReturnValueOnce([ importFailed, () => '' ]);
|
.mockReturnValueOnce([ importFailed, () => '' ]);
|
||||||
const CreateServer = createServerConstruct(ImportServersBtn, useStateFlagTimeout);
|
const CreateServer = createServerConstruct(ImportServersBtn, useStateFlagTimeout);
|
||||||
|
|
||||||
wrapper = shallow(
|
wrapper = shallow(<CreateServer createServer={createServerMock} history={historyMock} />);
|
||||||
<CreateServer createServer={createServerMock} resetSelectedServer={identity} history={historyMock} />,
|
|
||||||
);
|
|
||||||
|
|
||||||
return wrapper;
|
return wrapper;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import deleteServerButtonConstruct from '../../src/servers/DeleteServerButton';
|
import deleteServerButtonConstruct from '../../src/servers/DeleteServerButton';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
import { Modal, ModalBody, ModalFooter, ModalHeader } from 'reactstrap';
|
||||||
import { History } from 'history';
|
import { History } from 'history';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { mount, ReactWrapper } from 'enzyme';
|
import { mount, ReactWrapper } from 'enzyme';
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import { History, Location } from 'history';
|
import { History, Location } from 'history';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { values } from 'ramda';
|
import { values } from 'ramda';
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import React, { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import { DropdownItem, DropdownToggle } from 'reactstrap';
|
import { DropdownItem, DropdownToggle } from 'reactstrap';
|
||||||
import serversDropdownCreator, { ServersDropdownProps } from '../../src/servers/ServersDropdown';
|
import serversDropdownCreator, { ServersDropdownProps } from '../../src/servers/ServersDropdown';
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import React from 'react';
|
|
||||||
import { ListGroup } from 'reactstrap';
|
import { ListGroup } from 'reactstrap';
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import ServersListGroup from '../../src/servers/ServersListGroup';
|
import ServersListGroup from '../../src/servers/ServersListGroup';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { mount, ReactWrapper } from 'enzyme';
|
import { mount, ReactWrapper } from 'enzyme';
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import ForServerVersion from '../../../src/servers/helpers/ForServerVersion';
|
import ForServerVersion from '../../../src/servers/helpers/ForServerVersion';
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import React from 'react';
|
|
||||||
import { shallow, ShallowWrapper } from 'enzyme';
|
import { shallow, ShallowWrapper } from 'enzyme';
|
||||||
import { UncontrolledTooltip } from 'reactstrap';
|
import { UncontrolledTooltip } from 'reactstrap';
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue