Compare commits

..

43 Commits

Author SHA1 Message Date
Alejandro Celaya
2e438f9814 Merge pull request #1351 from shlinkio/develop
Release 4.2.2
2024-10-19 12:15:18 +02:00
Alejandro Celaya
ae014e2a14 Update to @shlinkio/shlink-web-component 0.10.1 2024-10-19 12:13:34 +02:00
Alejandro Celaya
5f5b66a21e Merge pull request #1350 from acelaya-forks/feature/update-packages
Update to latest shlink-web-component and shlink-frontend-kit
2024-10-19 11:32:27 +02:00
Alejandro Celaya
723e8696af Update to latest shlink-web-component and shlink-frontend-kit 2024-10-19 11:23:20 +02:00
Alejandro Celaya
32c3c9955c Merge pull request #1346 from shlinkio/dependabot/npm_and_yarn/eslint-9.13.0
Bump eslint from 9.12.0 to 9.13.0
2024-10-19 11:15:19 +02:00
Alejandro Celaya
847a23ddeb Merge pull request #1343 from shlinkio/dependabot/npm_and_yarn/vite-dddd68210b
Bump vite from 5.4.8 to 5.4.9 in the vite group
2024-10-19 11:15:11 +02:00
dependabot[bot]
08e3e01526 Bump vite from 5.4.8 to 5.4.9 in the vite group
Bumps the vite group with 1 update: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 5.4.8 to 5.4.9
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.9/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.9/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: vite
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-19 09:12:14 +00:00
dependabot[bot]
82b26add88 Bump eslint from 9.12.0 to 9.13.0
Bumps [eslint](https://github.com/eslint/eslint) from 9.12.0 to 9.13.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v9.12.0...v9.13.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-19 09:12:01 +00:00
Alejandro Celaya
e3ab34eae1 Merge pull request #1341 from shlinkio/dependabot/npm_and_yarn/eslint-plugins-6f16f7b45b
Bump typescript-eslint from 8.8.1 to 8.10.0 in the eslint-plugins group
2024-10-19 11:11:25 +02:00
Alejandro Celaya
65d9a4125f Merge pull request #1344 from shlinkio/dependabot/npm_and_yarn/vitest-704a82ba63
Bump the vitest group with 2 updates
2024-10-19 11:10:34 +02:00
Alejandro Celaya
d05344eea7 Merge pull request #1345 from shlinkio/dependabot/npm_and_yarn/axe-core-4.10.1
Bump axe-core from 4.10.0 to 4.10.1
2024-10-19 11:10:23 +02:00
dependabot[bot]
47a2d981c8 Bump typescript-eslint from 8.8.1 to 8.10.0 in the eslint-plugins group
Bumps the eslint-plugins group with 1 update: [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `typescript-eslint` from 8.8.1 to 8.10.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.10.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint-plugins
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-19 09:02:49 +00:00
Alejandro Celaya
2229573101 Merge pull request #1347 from shlinkio/dependabot/npm_and_yarn/reduxjs/toolkit-2.3.0
Bump @reduxjs/toolkit from 2.2.8 to 2.3.0
2024-10-19 11:02:00 +02:00
Alejandro Celaya
a8059c6f1f Merge pull request #1348 from shlinkio/dependabot/npm_and_yarn/sass-1.80.3
Bump sass from 1.79.5 to 1.80.3
2024-10-19 11:01:54 +02:00
Alejandro Celaya
51c1963f4b Merge pull request #1349 from shlinkio/dependabot/docker/node-23.0-alpine
Bump node from 22.9-alpine to 23.0-alpine
2024-10-19 11:01:44 +02:00
dependabot[bot]
8c10daeddd Bump node from 22.9-alpine to 23.0-alpine
Bumps node from 22.9-alpine to 23.0-alpine.

---
updated-dependencies:
- dependency-name: node
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-19 07:57:04 +00:00
dependabot[bot]
d168e98607 Bump sass from 1.79.5 to 1.80.3
Bumps [sass](https://github.com/sass/dart-sass) from 1.79.5 to 1.80.3.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.79.5...1.80.3)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-19 07:12:39 +00:00
dependabot[bot]
a45d990eb7 Bump @reduxjs/toolkit from 2.2.8 to 2.3.0
Bumps [@reduxjs/toolkit](https://github.com/reduxjs/redux-toolkit) from 2.2.8 to 2.3.0.
- [Release notes](https://github.com/reduxjs/redux-toolkit/releases)
- [Commits](https://github.com/reduxjs/redux-toolkit/compare/v2.2.8...v2.3.0)

---
updated-dependencies:
- dependency-name: "@reduxjs/toolkit"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-19 07:12:28 +00:00
dependabot[bot]
31ae43708a Bump axe-core from 4.10.0 to 4.10.1
Bumps [axe-core](https://github.com/dequelabs/axe-core) from 4.10.0 to 4.10.1.
- [Release notes](https://github.com/dequelabs/axe-core/releases)
- [Changelog](https://github.com/dequelabs/axe-core/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/dequelabs/axe-core/compare/v4.10.0...v4.10.1)

---
updated-dependencies:
- dependency-name: axe-core
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-19 07:12:03 +00:00
dependabot[bot]
cefe327251 Bump the vitest group with 2 updates
Bumps the vitest group with 2 updates: [@vitest/coverage-v8](https://github.com/vitest-dev/vitest/tree/HEAD/packages/coverage-v8) and [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest).


Updates `@vitest/coverage-v8` from 2.1.2 to 2.1.3
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v2.1.3/packages/coverage-v8)

Updates `vitest` from 2.1.2 to 2.1.3
- [Release notes](https://github.com/vitest-dev/vitest/releases)
- [Commits](https://github.com/vitest-dev/vitest/commits/v2.1.3/packages/vitest)

---
updated-dependencies:
- dependency-name: "@vitest/coverage-v8"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: vitest
- dependency-name: vitest
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: vitest
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-19 07:11:38 +00:00
Alejandro Celaya
22280e9d89 Remove twitter badge from readme 2024-10-17 16:26:41 +02:00
Alejandro Celaya
c73ece41f0 Merge pull request #1339 from acelaya-forks/feature/avoid-side-effects
Remove not needed usages of useEffect
2024-10-14 18:02:04 +02:00
Alejandro Celaya
7825f7666f Remove not needed usages of useEffect 2024-10-14 17:59:56 +02:00
Alejandro Celaya
fc6901ee65 Merge pull request #1338 from shlinkio/dependabot/npm_and_yarn/eslint-plugins-0f7f25a9f5
Bump typescript-eslint from 8.8.0 to 8.8.1 in the eslint-plugins group across 1 directory
2024-10-12 20:21:15 +02:00
dependabot[bot]
1794a07204 Bump typescript-eslint in the eslint-plugins group across 1 directory
Bumps the eslint-plugins group with 1 update in the / directory: [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint).


Updates `typescript-eslint` from 8.8.0 to 8.8.1
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.8.1/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: eslint-plugins
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-12 18:11:31 +00:00
Alejandro Celaya
7215d188a2 Merge pull request #1337 from acelaya-forks/feature/eslint-9
Feature/eslint 9
2024-10-12 20:10:31 +02:00
Alejandro Celaya
94890da48f Update to ESLint 9 2024-10-12 20:09:02 +02:00
Alejandro Celaya
078c5c8889 Merge pull request #1332 from shlinkio/dependabot/npm_and_yarn/types-0d175a54fb
Bump @types/react-dom from 18.3.0 to 18.3.1 in the types group
2024-10-12 10:34:11 +02:00
Alejandro Celaya
23a0cb1245 Merge pull request #1333 from shlinkio/dependabot/npm_and_yarn/react-router-dom-6.27.0
Bump react-router-dom from 6.26.2 to 6.27.0
2024-10-12 10:34:03 +02:00
Alejandro Celaya
b4015bd8d1 Merge pull request #1334 from shlinkio/dependabot/npm_and_yarn/typescript-5.6.3
Bump typescript from 5.6.2 to 5.6.3
2024-10-12 10:33:51 +02:00
dependabot[bot]
3cffaa6e32 Bump typescript from 5.6.2 to 5.6.3
Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.6.2 to 5.6.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/microsoft/TypeScript/compare/v5.6.2...v5.6.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-12 08:33:32 +00:00
Alejandro Celaya
e68faa63c5 Merge pull request #1335 from shlinkio/dependabot/npm_and_yarn/reduxjs/toolkit-2.2.8
Bump @reduxjs/toolkit from 2.2.7 to 2.2.8
2024-10-12 10:32:54 +02:00
Alejandro Celaya
e0706a6a89 Merge pull request #1336 from shlinkio/dependabot/npm_and_yarn/sass-1.79.5
Bump sass from 1.79.4 to 1.79.5
2024-10-12 10:32:43 +02:00
dependabot[bot]
adcb405643 Bump sass from 1.79.4 to 1.79.5
Bumps [sass](https://github.com/sass/dart-sass) from 1.79.4 to 1.79.5.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.79.4...1.79.5)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-12 07:30:03 +00:00
dependabot[bot]
63df7db2f5 Bump @reduxjs/toolkit from 2.2.7 to 2.2.8
Bumps [@reduxjs/toolkit](https://github.com/reduxjs/redux-toolkit) from 2.2.7 to 2.2.8.
- [Release notes](https://github.com/reduxjs/redux-toolkit/releases)
- [Commits](https://github.com/reduxjs/redux-toolkit/compare/v2.2.7...v2.2.8)

---
updated-dependencies:
- dependency-name: "@reduxjs/toolkit"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-12 07:29:47 +00:00
dependabot[bot]
04eb1b1b0e Bump react-router-dom from 6.26.2 to 6.27.0
Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.26.2 to 6.27.0.
- [Release notes](https://github.com/remix-run/react-router/releases)
- [Changelog](https://github.com/remix-run/react-router/blob/react-router-dom@6.27.0/packages/react-router-dom/CHANGELOG.md)
- [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.27.0/packages/react-router-dom)

---
updated-dependencies:
- dependency-name: react-router-dom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-12 07:29:10 +00:00
dependabot[bot]
40bf57882a Bump @types/react-dom from 18.3.0 to 18.3.1 in the types group
Bumps the types group with 1 update: [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom).


Updates `@types/react-dom` from 18.3.0 to 18.3.1
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom)

---
updated-dependencies:
- dependency-name: "@types/react-dom"
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: types
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-12 07:28:32 +00:00
Alejandro Celaya
9a798c20c0 Merge pull request #1329 from shlinkio/develop
Release 4.2.1
2024-10-09 14:33:56 +02:00
Alejandro Celaya
45a9783e04 Remove extra empty line from changelog 2024-10-09 14:32:29 +02:00
Alejandro Celaya
ac95ff0166 Merge pull request #1328 from acelaya-forks/feature/web-client-0.8.1
Update to shlink-web-client 0.8.1
2024-10-09 14:31:40 +02:00
Alejandro Celaya
a0df3eeb93 Update to shlink-web-client 0.8.1 2024-10-09 14:29:47 +02:00
Alejandro Celaya
e8c5ac8320 Merge pull request #1327 from acelaya-forks/feature/uuid-fix
Get dependency on uuid package back to fix error on non-secure contexts
2024-10-09 09:30:10 +02:00
Alejandro Celaya
453d245924 Get dependency on uuid package back to fix error on non-secure contexts 2024-10-09 09:27:08 +02:00
18 changed files with 2725 additions and 1745 deletions

View File

@@ -12,11 +12,12 @@ updates:
fontawesome:
patterns:
- '@fortawesome/*'
eslint-plugins: # TODO Add eslint back once updated to v9
eslint:
patterns:
- '@shlinkio/eslint-config-js-coding-standard'
- 'typescript-eslint'
- '*eslint-plugin*'
- 'eslint'
shlink:
patterns:
- '@shlinkio/*'

View File

@@ -4,6 +4,44 @@ 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).
## [4.2.2] - 2024-10-19
### Added
* *Nothing*
### Changed
* Update to `@shlinkio/shlink-frontend-kit` 0.6.0
* Update to `@shlinkio/shlink-web-component` 0.10.1
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [shlink-web-component#475](https://github.com/shlinkio/shlink-web-component/issues/475) Fix incorrect amount of dots being displayed in line charts when the difference in days/weeks/months is rounded up.
## [4.2.1] - 2024-10-09
### Added
* *Nothing*
### Changed
* *Nothing*
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1325](https://github.com/shlinkio/shlink-web-client/issues/1325) Get dependency on `uuid` package back, as `crypto.randomUUID()` can only be used in [secure contexts](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts).
* [shlink-web-component#461](https://github.com/shlinkio/shlink-web-component/issues/461) Ensure `shortUrlsList.confirmDeletion` setting is `true` in any case, except when explicitly set to `false`.
* [shlink-web-component#237](https://github.com/shlinkio/shlink-web-component/issues/237) Set darker color for previous period in charts, when light theme is enabled.
* [shlink-web-component#246](https://github.com/shlinkio/shlink-web-component/issues/246) Fix selected date range not reflected in visits comparison date range selector, when selecting it in the line chart via drag'n'drop.
## [4.2.0] - 2024-10-07
### Added
* [shlink-web-component#411](https://github.com/shlinkio/shlink-web-component/issues/411) Add support for `ip-address` redirect conditions when Shlink server is >=4.2

View File

@@ -1,4 +1,4 @@
FROM node:22.9-alpine as node
FROM node:23.0-alpine as node
COPY . /shlink-web-client
ARG VERSION="latest"
ENV VERSION ${VERSION}

View File

@@ -7,7 +7,6 @@
[![GitHub license](https://img.shields.io/github/license/shlinkio/shlink-web-client.svg?style=flat-square)](https://github.com/shlinkio/shlink-web-client/blob/main/LICENSE)
[![Mastodon](https://img.shields.io/mastodon/follow/109329425426175098?color=%236364ff&domain=https%3A%2F%2Ffosstodon.org&label=follow&logo=mastodon&logoColor=white&style=flat-square)](https://fosstodon.org/@shlinkio)
[![Twitter](https://img.shields.io/badge/follow-shlinkio-blue.svg?style=flat-square&logo=x&color=black)](https://twitter.com/shlinkio)
[![Bluesky](https://img.shields.io/badge/follow-shlinkio-0285FF.svg?style=flat-square&logo=bluesky&logoColor=white)](https://bsky.app/profile/shlinkio.bsky.social)
[![Paypal Donate](https://img.shields.io/badge/Donate-paypal-blue.svg?style=flat-square&logo=paypal&colorA=cccccc)](https://slnk.to/donate)

4311
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -31,11 +31,11 @@
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@fortawesome/react-fontawesome": "^0.2.2",
"@json2csv/plainjs": "^7.0.6",
"@reduxjs/toolkit": "^2.2.7",
"@reduxjs/toolkit": "^2.3.0",
"@shlinkio/data-manipulation": "^1.0.3",
"@shlinkio/shlink-frontend-kit": "^0.5.2",
"@shlinkio/shlink-frontend-kit": "^0.6.0",
"@shlinkio/shlink-js-sdk": "^1.2.0",
"@shlinkio/shlink-web-component": "^0.8.0",
"@shlinkio/shlink-web-component": "^0.10.1",
"bootstrap": "5.2.3",
"bottlejs": "^2.0.1",
"clsx": "^2.1.1",
@@ -46,9 +46,10 @@
"react-dom": "^18.3.1",
"react-external-link": "^2.3.1",
"react-redux": "^9.1.2",
"react-router-dom": "^6.26.2",
"react-router-dom": "^6.27.0",
"reactstrap": "^9.2.3",
"redux-localstorage-simple": "^2.5.1",
"uuid": "^10.0.0",
"workbox-core": "^7.1.0",
"workbox-expiration": "^7.1.0",
"workbox-precaching": "^7.1.0",
@@ -56,7 +57,7 @@
"workbox-strategies": "^7.1.0"
},
"devDependencies": {
"@shlinkio/eslint-config-js-coding-standard": "~3.1.0",
"@shlinkio/eslint-config-js-coding-standard": "~3.2.0",
"@shlinkio/stylelint-config-css-coding-standard": "~1.1.1",
"@stylistic/eslint-plugin": "^2.9.0",
"@testing-library/jest-dom": "^6.5.0",
@@ -64,25 +65,25 @@
"@testing-library/user-event": "^14.5.2",
"@total-typescript/shoehorn": "^0.1.2",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.0",
"@types/react-dom": "^18.3.1",
"@types/uuid": "^10.0.0",
"@vitejs/plugin-react": "^4.3.2",
"@vitest/coverage-v8": "^2.1.2",
"@vitest/coverage-v8": "^2.1.3",
"adm-zip": "^0.5.16",
"axe-core": "^4.10.0",
"axe-core": "^4.10.1",
"chalk": "^5.3.0",
"eslint": "^8.57.0",
"eslint": "^9.13.0",
"eslint-plugin-jsx-a11y": "^6.10.0",
"eslint-plugin-react": "^7.37.1",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-simple-import-sort": "^12.1.1",
"history": "^5.3.0",
"jsdom": "^25.0.1",
"sass": "^1.79.4",
"sass": "^1.80.3",
"stylelint": "^15.11.0",
"typescript": "^5.6.2",
"typescript-eslint": "^8.8.0",
"vite": "^5.4.8",
"typescript": "^5.6.3",
"typescript-eslint": "^8.10.0",
"vite": "^5.4.9",
"vite-plugin-pwa": "^0.20.5",
"vitest": "^2.0.2"
},

View File

@@ -20,7 +20,6 @@ export function componentFactory<Deps, CompType = Omit<Partial<Deps>, keyof FC>>
console.error(`[Debug] Could not find "${dep as string}" dependency in container`);
}
// eslint-disable-next-line no-param-reassign
Component[dep] = resolvedDependency;
});

View File

@@ -10,7 +10,7 @@ import './index.scss';
const store = setUpStore(container);
const { App, ScrollToTop, ErrorHandler, appUpdateAvailable } = container;
createRoot(document.getElementById('root')!).render( // eslint-disable-line @typescript-eslint/no-non-null-assertion
createRoot(document.getElementById('root')!).render(
<Provider store={store}>
<BrowserRouter basename={pack.homepage}>
<ErrorHandler>

View File

@@ -1,13 +1,14 @@
import type { TimeoutToggle } from '@shlinkio/shlink-frontend-kit';
import { Result, useToggle } from '@shlinkio/shlink-frontend-kit';
import type { FC } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { useCallback, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Button } from 'reactstrap';
import { NoMenuLayout } from '../common/NoMenuLayout';
import type { FCWithDeps } from '../container/utils';
import { componentFactory, useDependencies } from '../container/utils';
import { useGoBack } from '../utils/helpers/hooks';
import { randomUUID } from '../utils/utils';
import type { ServerData, ServersMap, ServerWithId } from './data';
import { DuplicatedServersModal } from './helpers/DuplicatedServersModal';
import type { ImportServersBtnProps } from './helpers/ImportServersBtn';
@@ -44,31 +45,28 @@ const CreateServer: FCWithDeps<CreateServerProps, CreateServerDeps> = ({ servers
const [isConfirmModalOpen, toggleConfirmModal] = useToggle();
const [serverData, setServerData] = useState<ServerData>();
const saveNewServer = useCallback((theServerData: ServerData) => {
const id = crypto.randomUUID();
const id = randomUUID();
createServers([{ ...theServerData, id }]);
navigate(`/server/${id}`);
}, [createServers, navigate]);
useEffect(() => {
if (!serverData) {
return;
}
const onSubmit = useCallback((newServerData: ServerData) => {
setServerData(newServerData);
const serverExists = Object.values(servers).some(
({ url, apiKey }) => serverData?.url === url && serverData?.apiKey === apiKey,
({ url, apiKey }) => newServerData.url === url && newServerData.apiKey === apiKey,
);
if (serverExists) {
toggleConfirmModal();
} else {
saveNewServer(serverData);
saveNewServer(newServerData);
}
}, [saveNewServer, serverData, servers, toggleConfirmModal]);
}, [saveNewServer, servers, toggleConfirmModal]);
return (
<NoMenuLayout>
<ServerForm title={<h5 className="mb-0">Add new server</h5>} onSubmit={setServerData}>
<ServerForm title={<h5 className="mb-0">Add new server</h5>} onSubmit={onSubmit}>
{!hasServers && (
<ImportServersBtn tooltipPlacement="top" onImport={setServersImported} onImportError={setErrorImporting} />
)}

View File

@@ -3,7 +3,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import type { TimeoutToggle } from '@shlinkio/shlink-frontend-kit';
import { Result, SearchField, SimpleCard } from '@shlinkio/shlink-frontend-kit';
import type { FC } from 'react';
import { useEffect, useState } from 'react';
import { useMemo, useState } from 'react';
import { Link } from 'react-router-dom';
import { Button, Row } from 'reactstrap';
import { NoMenuLayout } from '../common/NoMenuLayout';
@@ -34,26 +34,23 @@ const ManageServers: FCWithDeps<ManageServersProps, ManageServersDeps> = ({ serv
useTimeoutToggle,
ManageServersRow,
} = useDependencies(ManageServers);
const allServers = Object.values(servers);
const [serversList, setServersList] = useState(allServers);
const filterServers = (searchTerm: string) => setServersList(
allServers.filter(({ name, url }) => `${name} ${url}`.toLowerCase().match(searchTerm.toLowerCase())),
const [searchTerm, setSearchTerm] = useState('');
const allServers = useMemo(() => Object.values(servers), [servers]);
const filteredServers = useMemo(
() => allServers.filter(({ name, url }) => `${name} ${url}`.toLowerCase().match(searchTerm.toLowerCase())),
[allServers, searchTerm],
);
const hasAutoConnect = serversList.some(({ autoConnect }) => !!autoConnect);
const hasAutoConnect = allServers.some(({ autoConnect }) => !!autoConnect);
const [errorImporting, setErrorImporting] = useTimeoutToggle(false, SHOW_IMPORT_MSG_TIME);
useEffect(() => {
setServersList(Object.values(servers));
}, [servers]);
return (
<NoMenuLayout>
<SearchField className="mb-3" onChange={filterServers} />
<SearchField className="mb-3" onChange={setSearchTerm} />
<Row className="mb-3">
<div className="col-md-6 d-flex d-md-block mb-2 mb-md-0">
<ImportServersBtn className="flex-fill" onImportError={setErrorImporting}>Import servers</ImportServersBtn>
{allServers.length > 0 && (
{filteredServers.length > 0 && (
<Button outline className="ms-2 flex-fill" onClick={async () => serversExporter.exportServers()}>
<FontAwesomeIcon icon={exportIcon} fixedWidth /> Export servers
</Button>
@@ -77,8 +74,8 @@ const ManageServers: FCWithDeps<ManageServersProps, ManageServersDeps> = ({ serv
</tr>
</thead>
<tbody>
{!serversList.length && <tr className="text-center"><td colSpan={4}>No servers found.</td></tr>}
{serversList.map((server) => (
{!filteredServers.length && <tr className="text-center"><td colSpan={4}>No servers found.</td></tr>}
{filteredServers.map((server) => (
<ManageServersRow key={server.id} server={server} hasAutoConnect={hasAutoConnect} />
))}
</tbody>

View File

@@ -67,7 +67,7 @@ const ImportServersBtn: FCWithDeps<ImportServersBtnConnectProps, ImportServersBt
})
.then(() => {
// Reset input after processing file
(target as { value: string | null }).value = null; // eslint-disable-line no-param-reassign
(target as { value: string | null }).value = null;
})
.catch(onImportError),
[create, onImportError, servers, serversImporter, showModal],

View File

@@ -1,6 +1,6 @@
import { InputFormGroup, SimpleCard } from '@shlinkio/shlink-frontend-kit';
import type { FC, PropsWithChildren, ReactNode } from 'react';
import { useEffect, useState } from 'react';
import { useState } from 'react';
import { handleEventPreventingDefault } from '../../utils/utils';
import type { ServerData } from '../data';
@@ -11,19 +11,11 @@ type ServerFormProps = PropsWithChildren<{
}>;
export const ServerForm: FC<ServerFormProps> = ({ onSubmit, initialValues, children, title }) => {
const [name, setName] = useState('');
const [url, setUrl] = useState('');
const [apiKey, setApiKey] = useState('');
const [name, setName] = useState(initialValues?.name ?? '');
const [url, setUrl] = useState(initialValues?.url ?? '');
const [apiKey, setApiKey] = useState(initialValues?.apiKey ?? '');
const handleSubmit = handleEventPreventingDefault(() => onSubmit({ name, url, apiKey }));
useEffect(() => {
if (initialValues) {
setName(initialValues.name);
setUrl(initialValues.url);
setApiKey(initialValues.apiKey);
}
}, [initialValues]);
return (
<form className="server-form" name="serverForm" onSubmit={handleSubmit}>
<SimpleCard className="mb-3" title={title}>

View File

@@ -1,5 +1,6 @@
import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';
import { randomUUID } from '../../utils/utils';
import type { ServerData, ServersMap, ServerWithId } from '../data';
interface EditServer {
@@ -19,7 +20,7 @@ const serverWithId = (server: ServerWithId | ServerData): ServerWithId => {
return server;
}
return { ...server, id: crypto.randomUUID() };
return { ...server, id: randomUUID() };
};
const serversListToMap = (servers: ServerWithId[]): ServersMap => servers.reduce<ServersMap>(

View File

@@ -22,7 +22,7 @@ export class ServersExporter {
saveCsv(this.window, csv, SERVERS_FILENAME);
} catch (e) {
// FIXME Handle error
console.error(e); // eslint-disable-line no-console
console.error(e);
}
};
}

View File

@@ -1,6 +1,5 @@
import type { ShlinkState } from '../../container/types';
/* eslint-disable no-param-reassign */
export const migrateDeprecatedSettings = (state: Partial<ShlinkState>): Partial<ShlinkState> => {
if (!state.settings) {
return state;

View File

@@ -1,6 +1,9 @@
import type { SyntheticEvent } from 'react';
import { v4 } from 'uuid';
export const handleEventPreventingDefault = <T>(handler: () => T) => (e: SyntheticEvent) => {
e.preventDefault();
handler();
};
export const randomUUID = () => v4();

View File

@@ -39,7 +39,7 @@ describe('ShlinkApiClientBuilder', () => {
const apiKey = 'apiKey';
const apiClient = buildShlinkApiClient(fromPartial({}))(server({ url, apiKey }));
expect(apiClient['serverInfo'].baseUrl).toEqual(url); // eslint-disable-line @typescript-eslint/dot-notation
expect(apiClient['serverInfo'].apiKey).toEqual(apiKey); // eslint-disable-line @typescript-eslint/dot-notation
expect(apiClient['serverInfo'].baseUrl).toEqual(url);
expect(apiClient['serverInfo'].apiKey).toEqual(apiKey);
});
});

View File

@@ -9,6 +9,7 @@ import {
selectedServerReducerCreator,
selectServer as selectServerCreator,
} from '../../../src/servers/reducers/selectedServer';
import { randomUUID } from '../../../src/utils/utils';
describe('selectedServerReducer', () => {
const dispatch = vi.fn();
@@ -40,7 +41,7 @@ describe('selectedServerReducer', () => {
['latest', MAX_FALLBACK_VERSION, 'latest'],
['%invalid_semver%', MIN_FALLBACK_VERSION, '%invalid_semver%'],
])('dispatches proper actions', async (serverVersion, expectedVersion, expectedPrintableVersion) => {
const id = crypto.randomUUID();
const id = randomUUID();
const getState = createGetStateMock(id);
const expectedSelectedServer = {
id,
@@ -59,7 +60,7 @@ describe('selectedServerReducer', () => {
});
it('dispatches error when health endpoint fails', async () => {
const id = crypto.randomUUID();
const id = randomUUID();
const getState = createGetStateMock(id);
const expectedSelectedServer = fromPartial<NonReachableServer>({ id, serverNotReachable: true });
@@ -72,7 +73,7 @@ describe('selectedServerReducer', () => {
});
it('dispatches error when server is not found', async () => {
const id = crypto.randomUUID();
const id = randomUUID();
const getState = vi.fn(() => fromPartial<ShlinkState>({ servers: {} }));
const expectedSelectedServer: NotFoundServer = { serverNotFound: true };