Ensured a recconnection happens to selected server when its params are edited

This commit is contained in:
Alejandro Celaya 2022-12-31 16:42:04 +01:00
parent d34b9b1233
commit 91f4d09608
7 changed files with 23 additions and 12 deletions

View file

@ -38,7 +38,6 @@ export const MenuLayout = (
useEffect(() => hideSidebar(), [location]); useEffect(() => hideSidebar(), [location]);
useEffect(() => { useEffect(() => {
showContent && sidebarPresent(); showContent && sidebarPresent();
return () => sidebarNotPresent(); return () => sidebarNotPresent();
}, []); }, []);

View file

@ -1,7 +1,7 @@
import { FC } from 'react'; import { FC } from 'react';
import { Button } from 'reactstrap'; import { Button } from 'reactstrap';
import { NoMenuLayout } from '../common/NoMenuLayout'; import { NoMenuLayout } from '../common/NoMenuLayout';
import { useGoBack } from '../utils/helpers/hooks'; import { useGoBack, useParsedQuery } from '../utils/helpers/hooks';
import { ServerForm } from './helpers/ServerForm'; import { ServerForm } from './helpers/ServerForm';
import { withSelectedServer } from './helpers/withSelectedServer'; import { withSelectedServer } from './helpers/withSelectedServer';
import { isServerWithId, ServerData } from './data'; import { isServerWithId, ServerData } from './data';
@ -10,8 +10,11 @@ interface EditServerProps {
editServer: (serverId: string, serverData: ServerData) => void; editServer: (serverId: string, serverData: ServerData) => void;
} }
export const EditServer = (ServerError: FC) => withSelectedServer<EditServerProps>(({ editServer, selectedServer }) => { export const EditServer = (ServerError: FC) => withSelectedServer<EditServerProps>((
{ editServer, selectedServer, selectServer },
) => {
const goBack = useGoBack(); const goBack = useGoBack();
const { reconnect } = useParsedQuery<{ reconnect?: 'true' }>();
if (!isServerWithId(selectedServer)) { if (!isServerWithId(selectedServer)) {
return null; return null;
@ -19,6 +22,7 @@ export const EditServer = (ServerError: FC) => withSelectedServer<EditServerProp
const handleSubmit = (serverData: ServerData) => { const handleSubmit = (serverData: ServerData) => {
editServer(selectedServer.id, serverData); editServer(selectedServer.id, serverData);
reconnect === 'true' && selectServer(selectedServer.id);
goBack(); goBack();
}; };

View file

@ -37,7 +37,7 @@ export const ServerError = (DeleteServerButton: FC<DeleteServerButtonProps>): FC
<h5> <h5>
Alternatively, if you think you may have miss-configured this server, you Alternatively, if you think you may have miss-configured this server, you
can <DeleteServerButton server={selectedServer} className="server-error__delete-btn">remove it</DeleteServerButton> or&nbsp; can <DeleteServerButton server={selectedServer} className="server-error__delete-btn">remove it</DeleteServerButton> or&nbsp;
<Link to={`/server/${selectedServer.id}/edit`}>edit it</Link>. <Link to={`/server/${selectedServer.id}/edit?reconnect=true`}>edit it</Link>.
</h5> </h5>
</div> </div>
)} )}

View file

@ -1,7 +1,7 @@
import { createAction, createListenerMiddleware, createSlice, PayloadAction } from '@reduxjs/toolkit'; 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 { 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 { ShlinkHealth } from '../../api/types';
import { createAsyncThunk } from '../../utils/helpers/redux'; import { createAsyncThunk } from '../../utils/helpers/redux';
import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder'; import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder';
@ -18,8 +18,8 @@ const versionToSemVer = pipe(
); );
const getServerVersion = memoizeWith( const getServerVersion = memoizeWith(
identity, (server: ServerWithId) => `${server.id}_${server.url}_${server.apiKey}`,
async (_serverId: string, health: () => Promise<ShlinkHealth>) => health().then(({ version }) => ({ async (_server: ServerWithId, health: () => Promise<ShlinkHealth>) => health().then(({ version }) => ({
version: versionToSemVer(version), version: versionToSemVer(version),
printableVersion: versionToPrintable(version), printableVersion: versionToPrintable(version),
})), })),
@ -43,7 +43,7 @@ export const selectServer = (buildShlinkApiClient: ShlinkApiClientBuilder) => cr
try { try {
const { health } = buildShlinkApiClient(selectedServer); const { health } = buildShlinkApiClient(selectedServer);
const { version, printableVersion } = await getServerVersion(serverId, health); const { version, printableVersion } = await getServerVersion(selectedServer, health);
return { return {
...selectedServer, ...selectedServer,

View file

@ -1,6 +1,6 @@
import { useState, useRef, EffectCallback, DependencyList, useEffect } from 'react'; import { useState, useRef, EffectCallback, DependencyList, useEffect } from 'react';
import { useSwipeable as useReactSwipeable } from 'react-swipeable'; import { useSwipeable as useReactSwipeable } from 'react-swipeable';
import { useNavigate } from 'react-router-dom'; import { useLocation, useNavigate } from 'react-router-dom';
import { v4 as uuid } from 'uuid'; import { v4 as uuid } from 'uuid';
import { parseQuery, stringifyQuery } from './query'; import { parseQuery, stringifyQuery } from './query';
@ -82,6 +82,11 @@ export const useGoBack = () => {
return () => navigate(-1); return () => navigate(-1);
}; };
export const useParsedQuery = <T>(): T => {
const { search } = useLocation();
return parseQuery<T>(search);
};
export const useDomId = (): string => { export const useDomId = (): string => {
const { current: id } = useRef(`dom-${uuid()}`); const { current: id } = useRef(`dom-${uuid()}`);
return id; return id;

View file

@ -1,6 +1,6 @@
import { fireEvent, screen } from '@testing-library/react'; import { fireEvent, screen } from '@testing-library/react';
import { Mock } from 'ts-mockery'; 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 { EditServer as editServerConstruct } from '../../src/servers/EditServer';
import { ReachableServer, SelectedServer } from '../../src/servers/data'; import { ReachableServer, SelectedServer } from '../../src/servers/data';
import { renderWithEvents } from '../__helpers__/setUpTest'; import { renderWithEvents } from '../__helpers__/setUpTest';
@ -19,7 +19,9 @@ describe('<EditServer />', () => {
}); });
const EditServer = editServerConstruct(ServerError); const EditServer = editServerConstruct(ServerError);
const setUp = (selectedServer: SelectedServer = defaultSelectedServer) => renderWithEvents( const setUp = (selectedServer: SelectedServer = defaultSelectedServer) => renderWithEvents(
<EditServer editServer={editServerMock} selectedServer={selectedServer} selectServer={jest.fn()} />, <MemoryRouter>
<EditServer editServer={editServerMock} selectedServer={selectedServer} selectServer={jest.fn()} />
</MemoryRouter>,
); );
beforeEach(() => { beforeEach(() => {

View file

@ -7,6 +7,7 @@ import pack from './package.json';
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
plugins: [react(), VitePWA({ plugins: [react(), VitePWA({
mode: process.env.NODE_ENV === 'development' ? 'development' : 'production',
strategies: 'injectManifest', strategies: 'injectManifest',
srcDir: './src', srcDir: './src',
filename: 'service-worker.ts', filename: 'service-worker.ts',