mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2024-12-23 09:30:31 +03:00
Migrated servers reducer to RTK
This commit is contained in:
parent
6f67f7bbf0
commit
10d4419387
4 changed files with 86 additions and 92 deletions
|
@ -1,6 +1,6 @@
|
||||||
import { IContainer } from 'bottlejs';
|
import { IContainer } from 'bottlejs';
|
||||||
import { combineReducers } from 'redux';
|
import { combineReducers } from 'redux';
|
||||||
import serversReducer from '../servers/reducers/servers';
|
import { serversReducer } from '../servers/reducers/servers';
|
||||||
import selectedServerReducer from '../servers/reducers/selectedServer';
|
import selectedServerReducer from '../servers/reducers/selectedServer';
|
||||||
import shortUrlsListReducer from '../short-urls/reducers/shortUrlsList';
|
import shortUrlsListReducer from '../short-urls/reducers/shortUrlsList';
|
||||||
import shortUrlCreationReducer from '../short-urls/reducers/shortUrlCreation';
|
import shortUrlCreationReducer from '../short-urls/reducers/shortUrlCreation';
|
||||||
|
|
|
@ -1,24 +1,17 @@
|
||||||
import { PayloadAction } from '@reduxjs/toolkit';
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||||
import { assoc, dissoc, fromPairs, map, pipe, reduce, toPairs } from 'ramda';
|
import { assoc, dissoc, fromPairs, map, pipe, reduce, toPairs } from 'ramda';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { ServerData, ServersMap, ServerWithId } from '../data';
|
import { ServerData, ServersMap, ServerWithId } from '../data';
|
||||||
import { buildReducer } from '../../utils/helpers/redux';
|
|
||||||
|
|
||||||
export const EDIT_SERVER = 'shlink/servers/EDIT_SERVER';
|
interface EditServer {
|
||||||
export const DELETE_SERVER = 'shlink/servers/DELETE_SERVER';
|
|
||||||
export const CREATE_SERVERS = 'shlink/servers/CREATE_SERVERS';
|
|
||||||
export const SET_AUTO_CONNECT = 'shlink/servers/SET_AUTO_CONNECT';
|
|
||||||
|
|
||||||
export type CreateServersAction = PayloadAction<ServersMap>;
|
|
||||||
|
|
||||||
type DeleteServerAction = PayloadAction<{
|
|
||||||
serverId: string;
|
serverId: string;
|
||||||
}>;
|
serverData: Partial<ServerData>;
|
||||||
|
}
|
||||||
|
|
||||||
type SetAutoConnectAction = PayloadAction<{
|
interface SetAutoConnect {
|
||||||
serverId: string;
|
serverId: string;
|
||||||
autoConnect: boolean;
|
autoConnect: boolean;
|
||||||
}>;
|
}
|
||||||
|
|
||||||
const initialState: ServersMap = {};
|
const initialState: ServersMap = {};
|
||||||
|
|
||||||
|
@ -30,53 +23,57 @@ const serverWithId = (server: ServerWithId | ServerData): ServerWithId => {
|
||||||
return assoc('id', uuid(), server);
|
return assoc('id', uuid(), server);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default buildReducer<ServersMap, CreateServersAction & DeleteServerAction & SetAutoConnectAction>({
|
|
||||||
[CREATE_SERVERS]: (state, { payload: newServers }) => ({ ...state, ...newServers }),
|
|
||||||
[DELETE_SERVER]: (state, { payload }) => dissoc(payload.serverId, state),
|
|
||||||
[EDIT_SERVER]: (state, { payload }: any) => {
|
|
||||||
const { serverId, serverData } = payload;
|
|
||||||
return (
|
|
||||||
!state[serverId] ? state : assoc(serverId, { ...state[serverId], ...serverData }, state)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
[SET_AUTO_CONNECT]: (state, { payload }) => {
|
|
||||||
const { serverId, autoConnect } = payload;
|
|
||||||
if (!state[serverId]) {
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!autoConnect) {
|
|
||||||
return assoc(serverId, { ...state[serverId], autoConnect }, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fromPairs(
|
|
||||||
toPairs(state).map(([evaluatedServerId, server]) => [
|
|
||||||
evaluatedServerId,
|
|
||||||
{ ...server, autoConnect: evaluatedServerId === serverId },
|
|
||||||
]),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
}, initialState);
|
|
||||||
|
|
||||||
const serversListToMap = reduce<ServerWithId, ServersMap>((acc, server) => assoc(server.id, server, acc), {});
|
const serversListToMap = reduce<ServerWithId, ServersMap>((acc, server) => assoc(server.id, server, acc), {});
|
||||||
|
|
||||||
export const createServers = pipe(
|
export const { actions, reducer } = createSlice({
|
||||||
map(serverWithId),
|
name: 'serversReducer',
|
||||||
serversListToMap,
|
initialState,
|
||||||
(newServers: ServersMap) => ({ type: CREATE_SERVERS, payload: newServers }),
|
reducers: {
|
||||||
);
|
editServer: {
|
||||||
|
prepare: (serverId: string, serverData: Partial<ServerData>) => ({
|
||||||
|
payload: { serverId, serverData },
|
||||||
|
}),
|
||||||
|
reducer: (state, { payload }: PayloadAction<EditServer>) => {
|
||||||
|
const { serverId, serverData } = payload;
|
||||||
|
return (
|
||||||
|
!state[serverId] ? state : assoc(serverId, { ...state[serverId], ...serverData }, state)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
deleteServer: (state, { payload }) => dissoc(payload.id, state),
|
||||||
|
setAutoConnect: {
|
||||||
|
prepare: ({ id: serverId }: ServerWithId, autoConnect: boolean) => ({
|
||||||
|
payload: { serverId, autoConnect },
|
||||||
|
}),
|
||||||
|
reducer: (state, { payload }: PayloadAction<SetAutoConnect>) => {
|
||||||
|
const { serverId, autoConnect } = payload;
|
||||||
|
if (!state[serverId]) {
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
export const editServer = (serverId: string, serverData: Partial<ServerData>) => ({
|
if (!autoConnect) {
|
||||||
type: EDIT_SERVER,
|
return assoc(serverId, { ...state[serverId], autoConnect }, state);
|
||||||
payload: { serverId, serverData },
|
}
|
||||||
|
|
||||||
|
return fromPairs(
|
||||||
|
toPairs(state).map(([evaluatedServerId, server]) => [
|
||||||
|
evaluatedServerId,
|
||||||
|
{ ...server, autoConnect: evaluatedServerId === serverId },
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
createServers: {
|
||||||
|
prepare: pipe(
|
||||||
|
map(serverWithId),
|
||||||
|
serversListToMap,
|
||||||
|
(payload: ServersMap) => ({ payload }),
|
||||||
|
),
|
||||||
|
reducer: (state, { payload: newServers }: PayloadAction<ServersMap>) => ({ ...state, ...newServers }),
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const deleteServer = ({ id }: ServerWithId): DeleteServerAction => ({
|
export const { editServer, deleteServer, setAutoConnect, createServers } = actions;
|
||||||
type: DELETE_SERVER,
|
|
||||||
payload: { serverId: id },
|
|
||||||
});
|
|
||||||
|
|
||||||
export const setAutoConnect = ({ id }: ServerWithId, autoConnect: boolean): SetAutoConnectAction => ({
|
export const serversReducer = reducer;
|
||||||
type: SET_AUTO_CONNECT,
|
|
||||||
payload: { serverId: id, autoConnect },
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import { AxiosInstance } from 'axios';
|
import { AxiosInstance } from 'axios';
|
||||||
import { fetchServers } from '../../../src/servers/reducers/remoteServers';
|
import { fetchServers } from '../../../src/servers/reducers/remoteServers';
|
||||||
import { CREATE_SERVERS } from '../../../src/servers/reducers/servers';
|
import { createServers } from '../../../src/servers/reducers/servers';
|
||||||
|
|
||||||
describe('remoteServersReducer', () => {
|
describe('remoteServersReducer', () => {
|
||||||
afterEach(jest.clearAllMocks);
|
afterEach(jest.clearAllMocks);
|
||||||
|
@ -87,7 +87,7 @@ describe('remoteServersReducer', () => {
|
||||||
|
|
||||||
await fetchServers(axios)()(dispatch);
|
await fetchServers(axios)()(dispatch);
|
||||||
|
|
||||||
expect(dispatch).toHaveBeenCalledWith({ type: CREATE_SERVERS, payload: expectedNewServers });
|
expect(dispatch).toHaveBeenCalledWith({ type: createServers.toString(), payload: expectedNewServers });
|
||||||
expect(get).toHaveBeenCalledTimes(1);
|
expect(get).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
import { dissoc, values } from 'ramda';
|
import { dissoc, values } from 'ramda';
|
||||||
import { Mock } from 'ts-mockery';
|
import { Mock } from 'ts-mockery';
|
||||||
import reducer, {
|
import {
|
||||||
deleteServer,
|
deleteServer,
|
||||||
createServers,
|
createServers,
|
||||||
editServer,
|
editServer,
|
||||||
setAutoConnect,
|
setAutoConnect,
|
||||||
EDIT_SERVER,
|
serversReducer,
|
||||||
DELETE_SERVER,
|
|
||||||
CREATE_SERVERS,
|
|
||||||
SET_AUTO_CONNECT,
|
|
||||||
} from '../../../src/servers/reducers/servers';
|
} from '../../../src/servers/reducers/servers';
|
||||||
import { RegularServer } from '../../../src/servers/data';
|
import { RegularServer } from '../../../src/servers/data';
|
||||||
|
|
||||||
|
@ -22,38 +19,38 @@ describe('serversReducer', () => {
|
||||||
|
|
||||||
describe('reducer', () => {
|
describe('reducer', () => {
|
||||||
it('returns edited server when action is EDIT_SERVER', () =>
|
it('returns edited server when action is EDIT_SERVER', () =>
|
||||||
expect(reducer(list, {
|
expect(serversReducer(list, {
|
||||||
type: EDIT_SERVER,
|
type: editServer.toString(),
|
||||||
payload: { serverId: 'abc123', serverData: { foo: 'foo' } },
|
payload: { serverId: 'abc123', serverData: { foo: 'foo' } },
|
||||||
} as any)).toEqual({
|
})).toEqual({
|
||||||
abc123: { id: 'abc123', foo: 'foo' },
|
abc123: { id: 'abc123', foo: 'foo' },
|
||||||
def456: { id: 'def456' },
|
def456: { id: 'def456' },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('returns as it is when action is EDIT_SERVER and server does not exist', () =>
|
it('returns as it is when action is EDIT_SERVER and server does not exist', () =>
|
||||||
expect(reducer(list, {
|
expect(serversReducer(list, {
|
||||||
type: EDIT_SERVER,
|
type: editServer.toString(),
|
||||||
payload: { serverId: 'invalid', serverData: { foo: 'foo' } },
|
payload: { serverId: 'invalid', serverData: { foo: 'foo' } },
|
||||||
} as any)).toEqual({
|
})).toEqual({
|
||||||
abc123: { id: 'abc123' },
|
abc123: { id: 'abc123' },
|
||||||
def456: { id: 'def456' },
|
def456: { id: 'def456' },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('removes server when action is DELETE_SERVER', () =>
|
it('removes server when action is DELETE_SERVER', () =>
|
||||||
expect(reducer(list, {
|
expect(serversReducer(list, {
|
||||||
type: DELETE_SERVER,
|
type: deleteServer.toString(),
|
||||||
payload: { serverId: 'abc123' },
|
payload: { id: 'abc123' },
|
||||||
} as any)).toEqual({
|
})).toEqual({
|
||||||
def456: { id: 'def456' },
|
def456: { id: 'def456' },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('appends server when action is CREATE_SERVERS', () =>
|
it('appends server when action is CREATE_SERVERS', () =>
|
||||||
expect(reducer(list, {
|
expect(serversReducer(list, {
|
||||||
type: CREATE_SERVERS,
|
type: createServers.toString(),
|
||||||
payload: {
|
payload: {
|
||||||
ghi789: { id: 'ghi789' },
|
ghi789: { id: 'ghi789' },
|
||||||
},
|
},
|
||||||
} as any)).toEqual({
|
})).toEqual({
|
||||||
abc123: { id: 'abc123' },
|
abc123: { id: 'abc123' },
|
||||||
def456: { id: 'def456' },
|
def456: { id: 'def456' },
|
||||||
ghi789: { id: 'ghi789' },
|
ghi789: { id: 'ghi789' },
|
||||||
|
@ -63,10 +60,10 @@ describe('serversReducer', () => {
|
||||||
[true],
|
[true],
|
||||||
[false],
|
[false],
|
||||||
])('returns state as it is when trying to set auto-connect on invalid server', (autoConnect) =>
|
])('returns state as it is when trying to set auto-connect on invalid server', (autoConnect) =>
|
||||||
expect(reducer(list, {
|
expect(serversReducer(list, {
|
||||||
type: SET_AUTO_CONNECT,
|
type: setAutoConnect.toString(),
|
||||||
payload: { serverId: 'invalid', autoConnect },
|
payload: { serverId: 'invalid', autoConnect },
|
||||||
} as any)).toEqual({
|
})).toEqual({
|
||||||
abc123: { id: 'abc123' },
|
abc123: { id: 'abc123' },
|
||||||
def456: { id: 'def456' },
|
def456: { id: 'def456' },
|
||||||
}));
|
}));
|
||||||
|
@ -77,10 +74,10 @@ describe('serversReducer', () => {
|
||||||
abc123: { ...list.abc123, autoConnect: true },
|
abc123: { ...list.abc123, autoConnect: true },
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(reducer(listWithDisabledAutoConnect, {
|
expect(serversReducer(listWithDisabledAutoConnect, {
|
||||||
type: SET_AUTO_CONNECT,
|
type: setAutoConnect.toString(),
|
||||||
payload: { serverId: 'abc123', autoConnect: false },
|
payload: { serverId: 'abc123', autoConnect: false },
|
||||||
} as any)).toEqual({
|
})).toEqual({
|
||||||
abc123: { id: 'abc123', autoConnect: false },
|
abc123: { id: 'abc123', autoConnect: false },
|
||||||
def456: { id: 'def456' },
|
def456: { id: 'def456' },
|
||||||
});
|
});
|
||||||
|
@ -92,10 +89,10 @@ describe('serversReducer', () => {
|
||||||
abc123: { ...list.abc123, autoConnect: true },
|
abc123: { ...list.abc123, autoConnect: true },
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(reducer(listWithEnabledAutoConnect, {
|
expect(serversReducer(listWithEnabledAutoConnect, {
|
||||||
type: SET_AUTO_CONNECT,
|
type: setAutoConnect.toString(),
|
||||||
payload: { serverId: 'def456', autoConnect: true },
|
payload: { serverId: 'def456', autoConnect: true },
|
||||||
} as any)).toEqual({
|
})).toEqual({
|
||||||
abc123: { id: 'abc123', autoConnect: false },
|
abc123: { id: 'abc123', autoConnect: false },
|
||||||
def456: { id: 'def456', autoConnect: true },
|
def456: { id: 'def456', autoConnect: true },
|
||||||
});
|
});
|
||||||
|
@ -109,7 +106,7 @@ describe('serversReducer', () => {
|
||||||
const result = editServer('123', serverData);
|
const result = editServer('123', serverData);
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
type: EDIT_SERVER,
|
type: editServer.toString(),
|
||||||
payload: { serverId: '123', serverData },
|
payload: { serverId: '123', serverData },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -121,8 +118,8 @@ describe('serversReducer', () => {
|
||||||
const result = deleteServer(serverToDelete);
|
const result = deleteServer(serverToDelete);
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
type: DELETE_SERVER,
|
type: deleteServer.toString(),
|
||||||
payload: { serverId: 'abc123' },
|
payload: { id: 'abc123' },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -132,7 +129,7 @@ describe('serversReducer', () => {
|
||||||
const newServers = values(list);
|
const newServers = values(list);
|
||||||
const result = createServers(newServers);
|
const result = createServers(newServers);
|
||||||
|
|
||||||
expect(result).toEqual(expect.objectContaining({ type: CREATE_SERVERS }));
|
expect(result).toEqual(expect.objectContaining({ type: createServers.toString() }));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('generates an id for every provided server if they do not have it', () => {
|
it('generates an id for every provided server if they do not have it', () => {
|
||||||
|
@ -152,7 +149,7 @@ describe('serversReducer', () => {
|
||||||
const result = setAutoConnect(serverToEdit, autoConnect);
|
const result = setAutoConnect(serverToEdit, autoConnect);
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
type: SET_AUTO_CONNECT,
|
type: setAutoConnect.toString(),
|
||||||
payload: { serverId: 'abc123', autoConnect },
|
payload: { serverId: 'abc123', autoConnect },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue