diff --git a/CHANGELOG.md b/CHANGELOG.md index de8853b8..1a6754ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ 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). -## [Unreleased] +## [3.9.0] - 2022-12-31 ### Added * [#750](https://github.com/shlinkio/shlink-web-client/issues/750) Added new icon indicators telling if a short URL can be normally visited, it received the max amount of visits, is still not enabled, etc. * [#764](https://github.com/shlinkio/shlink-web-client/issues/764) Added support to exclude visits from visits on short URLs list when consuming Shlink 3.4.0. @@ -26,7 +26,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), * [#774](https://github.com/shlinkio/shlink-web-client/issues/774) Dropped support for Shlink older than 2.8.0. ### Fixed -* *Nothing* +* [#715](https://github.com/shlinkio/shlink-web-client/issues/715) Fixed connection still failing on miss-configured servers, after editing their params to set proper values. ## [3.8.2] - 2022-12-17 diff --git a/src/common/MenuLayout.tsx b/src/common/MenuLayout.tsx index 0fc05448..58f7da2d 100644 --- a/src/common/MenuLayout.tsx +++ b/src/common/MenuLayout.tsx @@ -38,7 +38,6 @@ export const MenuLayout = ( useEffect(() => hideSidebar(), [location]); useEffect(() => { showContent && sidebarPresent(); - return () => sidebarNotPresent(); }, []); diff --git a/src/servers/EditServer.tsx b/src/servers/EditServer.tsx index c89b4468..e95b4daa 100644 --- a/src/servers/EditServer.tsx +++ b/src/servers/EditServer.tsx @@ -1,7 +1,7 @@ import { FC } from 'react'; import { Button } from 'reactstrap'; import { NoMenuLayout } from '../common/NoMenuLayout'; -import { useGoBack } from '../utils/helpers/hooks'; +import { useGoBack, useParsedQuery } from '../utils/helpers/hooks'; import { ServerForm } from './helpers/ServerForm'; import { withSelectedServer } from './helpers/withSelectedServer'; import { isServerWithId, ServerData } from './data'; @@ -10,8 +10,11 @@ interface EditServerProps { editServer: (serverId: string, serverData: ServerData) => void; } -export const EditServer = (ServerError: FC) => withSelectedServer(({ editServer, selectedServer }) => { +export const EditServer = (ServerError: FC) => withSelectedServer(( + { editServer, selectedServer, selectServer }, +) => { const goBack = useGoBack(); + const { reconnect } = useParsedQuery<{ reconnect?: 'true' }>(); if (!isServerWithId(selectedServer)) { return null; @@ -19,6 +22,7 @@ export const EditServer = (ServerError: FC) => withSelectedServer { editServer(selectedServer.id, serverData); + reconnect === 'true' && selectServer(selectedServer.id); goBack(); }; diff --git a/src/servers/helpers/ServerError.tsx b/src/servers/helpers/ServerError.tsx index 6f605969..f133d494 100644 --- a/src/servers/helpers/ServerError.tsx +++ b/src/servers/helpers/ServerError.tsx @@ -37,7 +37,7 @@ export const ServerError = (DeleteServerButton: FC): FC
Alternatively, if you think you may have miss-configured this server, you can remove it or  - edit it. + edit it.
)} diff --git a/src/servers/reducers/selectedServer.ts b/src/servers/reducers/selectedServer.ts index 3415a15c..b69647f0 100644 --- a/src/servers/reducers/selectedServer.ts +++ b/src/servers/reducers/selectedServer.ts @@ -1,7 +1,7 @@ import { createAction, createListenerMiddleware, createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { identity, memoizeWith, pipe } from 'ramda'; +import { memoizeWith, pipe } from 'ramda'; import { versionToPrintable, versionToSemVer as toSemVer } from '../../utils/helpers/version'; -import { isReachableServer, SelectedServer } from '../data'; +import { isReachableServer, SelectedServer, ServerWithId } from '../data'; import { ShlinkHealth } from '../../api/types'; import { createAsyncThunk } from '../../utils/helpers/redux'; import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder'; @@ -18,8 +18,8 @@ const versionToSemVer = pipe( ); const getServerVersion = memoizeWith( - identity, - async (_serverId: string, health: () => Promise) => health().then(({ version }) => ({ + (server: ServerWithId) => `${server.id}_${server.url}_${server.apiKey}`, + async (_server: ServerWithId, health: () => Promise) => health().then(({ version }) => ({ version: versionToSemVer(version), printableVersion: versionToPrintable(version), })), @@ -43,7 +43,7 @@ export const selectServer = (buildShlinkApiClient: ShlinkApiClientBuilder) => cr try { const { health } = buildShlinkApiClient(selectedServer); - const { version, printableVersion } = await getServerVersion(serverId, health); + const { version, printableVersion } = await getServerVersion(selectedServer, health); return { ...selectedServer, diff --git a/src/utils/helpers/hooks.ts b/src/utils/helpers/hooks.ts index 2e033cd8..56406afa 100644 --- a/src/utils/helpers/hooks.ts +++ b/src/utils/helpers/hooks.ts @@ -1,6 +1,6 @@ import { useState, useRef, EffectCallback, DependencyList, useEffect } from 'react'; import { useSwipeable as useReactSwipeable } from 'react-swipeable'; -import { useNavigate } from 'react-router-dom'; +import { useLocation, useNavigate } from 'react-router-dom'; import { v4 as uuid } from 'uuid'; import { parseQuery, stringifyQuery } from './query'; @@ -82,6 +82,11 @@ export const useGoBack = () => { return () => navigate(-1); }; +export const useParsedQuery = (): T => { + const { search } = useLocation(); + return parseQuery(search); +}; + export const useDomId = (): string => { const { current: id } = useRef(`dom-${uuid()}`); return id; diff --git a/test/servers/EditServer.test.tsx b/test/servers/EditServer.test.tsx index 771a6210..c5181bc0 100644 --- a/test/servers/EditServer.test.tsx +++ b/test/servers/EditServer.test.tsx @@ -1,6 +1,6 @@ import { fireEvent, screen } from '@testing-library/react'; import { Mock } from 'ts-mockery'; -import { useNavigate } from 'react-router-dom'; +import { MemoryRouter, useNavigate } from 'react-router-dom'; import { EditServer as editServerConstruct } from '../../src/servers/EditServer'; import { ReachableServer, SelectedServer } from '../../src/servers/data'; import { renderWithEvents } from '../__helpers__/setUpTest'; @@ -19,7 +19,9 @@ describe('', () => { }); const EditServer = editServerConstruct(ServerError); const setUp = (selectedServer: SelectedServer = defaultSelectedServer) => renderWithEvents( - , + + + , ); beforeEach(() => { diff --git a/test/servers/reducers/selectedServer.test.ts b/test/servers/reducers/selectedServer.test.ts index a8db0c95..bbb93798 100644 --- a/test/servers/reducers/selectedServer.test.ts +++ b/test/servers/reducers/selectedServer.test.ts @@ -39,11 +39,12 @@ describe('selectedServerReducer', () => { }); describe('selectServer', () => { - const selectedServer = { - id: 'abc123', - }; const version = '1.19.0'; - const createGetStateMock = (id: string) => jest.fn().mockReturnValue({ servers: { [id]: selectedServer } }); + const createGetStateMock = (id: string) => jest.fn().mockReturnValue({ + servers: { + [id]: { id }, + }, + }); it.each([ [version, version, `v${version}`], @@ -53,7 +54,7 @@ describe('selectedServerReducer', () => { const id = uuid(); const getState = createGetStateMock(id); const expectedSelectedServer = { - ...selectedServer, + id, version: expectedVersion, printableVersion: expectedPrintableVersion, }; @@ -84,7 +85,7 @@ describe('selectedServerReducer', () => { it('dispatches error when health endpoint fails', async () => { const id = uuid(); const getState = createGetStateMock(id); - const expectedSelectedServer = Mock.of({ ...selectedServer, serverNotReachable: true }); + const expectedSelectedServer = Mock.of({ id, serverNotReachable: true }); health.mockRejectedValue({}); diff --git a/vite.config.ts b/vite.config.ts index b74d3435..2b0cf261 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -7,6 +7,7 @@ import pack from './package.json'; // https://vitejs.dev/config/ export default defineConfig({ plugins: [react(), VitePWA({ + mode: process.env.NODE_ENV === 'development' ? 'development' : 'production', strategies: 'injectManifest', srcDir: './src', filename: 'service-worker.ts',