Migrated selectServer action to RTK and moved loadMercureInfo to an action listener

This commit is contained in:
Alejandro Celaya
2022-11-10 22:44:25 +01:00
parent 2e0e24d87b
commit 6221f9ed05
6 changed files with 71 additions and 68 deletions

View File

@@ -20,5 +20,5 @@ export const setUpStore = (container: IContainer) => configureStore({
preloadedState,
middleware: (defaultMiddlewaresIncludingReduxThunk) => defaultMiddlewaresIncludingReduxThunk(
{ immutableCheck: false, serializableCheck: false }, // State is too big for these
).concat(save(localStorageConfig)),
).prepend(container.selectServerListener.middleware).concat(save(localStorageConfig)),
});

View File

@@ -1,5 +1,5 @@
import { IContainer } from 'bottlejs';
import { combineReducers } from 'redux';
import { combineReducers } from '@reduxjs/toolkit';
import { serversReducer } from '../servers/reducers/servers';
import selectedServerReducer from '../servers/reducers/selectedServer';
import shortUrlVisitsReducer from '../visits/reducers/shortUrlVisits';

View File

@@ -1,15 +1,13 @@
import { PayloadAction } from '@reduxjs/toolkit';
import { createAction, createListenerMiddleware, PayloadAction } from '@reduxjs/toolkit';
import { identity, memoizeWith, pipe } from 'ramda';
import { Action, Dispatch } from 'redux';
import { versionToPrintable, versionToSemVer as toSemVer } from '../../utils/helpers/version';
import { SelectedServer } from '../data';
import { GetState } from '../../container/types';
import { isReachableServer, SelectedServer } from '../data';
import { ShlinkHealth } from '../../api/types';
import { buildActionCreator, buildReducer } from '../../utils/helpers/redux';
import { buildReducer, createAsyncThunk } from '../../utils/helpers/redux';
import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder';
export const SELECT_SERVER = 'shlink/selectedServer/SELECT_SERVER';
export const RESET_SELECTED_SERVER = 'shlink/selectedServer/RESET_SELECTED_SERVER';
export const SELECT_SERVER = 'shlink/selectedServer/selectServer';
export const RESET_SELECTED_SERVER = 'shlink/selectedServer/resetSelectedServer';
export const MIN_FALLBACK_VERSION = '1.0.0';
export const MAX_FALLBACK_VERSION = '999.999.999';
@@ -35,50 +33,49 @@ const initialState: SelectedServer = null;
export default buildReducer<SelectedServer, SelectServerAction>({
[RESET_SELECTED_SERVER]: () => initialState,
[SELECT_SERVER]: (_, { payload }) => payload,
[`${SELECT_SERVER}/fulfilled`]: (_, { payload }) => payload,
}, initialState);
export const resetSelectedServer = buildActionCreator(RESET_SELECTED_SERVER);
export const resetSelectedServer = createAction<void>(RESET_SELECTED_SERVER);
export const selectServer = (
buildShlinkApiClient: ShlinkApiClientBuilder,
loadMercureInfo: () => Action,
) => (
serverId: string,
) => async (
dispatch: Dispatch,
getState: GetState,
) => {
) => createAsyncThunk(SELECT_SERVER, async (serverId: string, { dispatch, getState }): Promise<SelectedServer> => {
dispatch(resetSelectedServer());
const { servers } = getState();
const selectedServer = servers[serverId];
if (!selectedServer) {
dispatch<SelectServerAction>({
type: SELECT_SERVER,
payload: { serverNotFound: true },
});
return;
return { serverNotFound: true };
}
try {
const { health } = buildShlinkApiClient(selectedServer);
const { version, printableVersion } = await getServerVersion(serverId, health);
dispatch<SelectServerAction>({
type: SELECT_SERVER,
payload: {
...selectedServer,
version,
printableVersion,
},
});
dispatch(loadMercureInfo());
return {
...selectedServer,
version,
printableVersion,
};
} catch (e) {
dispatch<SelectServerAction>({
type: SELECT_SERVER,
payload: { ...selectedServer, serverNotReachable: true },
});
return { ...selectedServer, serverNotReachable: true };
}
});
export const selectServerListener = (
selectServerThunk: ReturnType<typeof selectServer>,
loadMercureInfo: () => PayloadAction<any>, // TODO Consider setting actual type, if relevant
) => {
const listener = createListenerMiddleware();
listener.startListening({
actionCreator: selectServerThunk.fulfilled,
effect: ({ payload }, { dispatch }) => {
isReachableServer(payload) && dispatch(loadMercureInfo());
},
});
return listener;
};

View File

@@ -5,7 +5,7 @@ import { DeleteServerModal } from '../DeleteServerModal';
import { DeleteServerButton } from '../DeleteServerButton';
import { EditServer } from '../EditServer';
import { ImportServersBtn } from '../helpers/ImportServersBtn';
import { resetSelectedServer, selectServer } from '../reducers/selectedServer';
import { resetSelectedServer, selectServer, selectServerListener } from '../reducers/selectedServer';
import { createServers, deleteServer, editServer, setAutoConnect } from '../reducers/servers';
import { fetchServers } from '../reducers/remoteServers';
import { ServerError } from '../helpers/ServerError';
@@ -77,6 +77,9 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
bottle.serviceFactory('fetchServers', fetchServers, 'axios');
bottle.serviceFactory('resetSelectedServer', () => resetSelectedServer);
// Reducers
bottle.serviceFactory('selectServerListener', selectServerListener, 'selectServer', 'loadMercureInfo');
};
export default provideServices;

View File

@@ -1,13 +1,11 @@
import { createAction, PayloadAction } from '@reduxjs/toolkit';
import { CreateVisit } from '../types';
const CREATE_VISITS = 'shlink/visitCreation/CREATE_VISITS';
export type CreateVisitsAction = PayloadAction<{
createdVisits: CreateVisit[];
}>;
export const createNewVisits = createAction(
CREATE_VISITS,
'shlink/visitCreation/createNewVisits',
(createdVisits: CreateVisit[]) => ({ payload: { createdVisits } }),
);