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 { serverId: string; serverData: Partial; } interface SetAutoConnect { serverId: string; autoConnect: boolean; } const initialState: ServersMap = {}; const serverWithId = (server: ServerWithId | ServerData): ServerWithId => { if ('id' in server) { return server; } return { ...server, id: randomUUID() }; }; const serversListToMap = (servers: ServerWithId[]): ServersMap => servers.reduce( (acc, server) => ({ ...acc, [server.id]: server }), {}, ); export const { actions, reducer } = createSlice({ name: 'shlink/servers', initialState, reducers: { editServer: { prepare: (serverId: string, serverData: Partial) => ({ payload: { serverId, serverData }, }), reducer: (state, { payload }: PayloadAction) => { const { serverId, serverData } = payload; return ( !state[serverId] ? state : { ...state, [serverId]: { ...state[serverId], ...serverData } } ); }, }, deleteServer: (state, { payload }) => { delete state[payload.id]; return state; }, setAutoConnect: { prepare: ({ id: serverId }: ServerWithId, autoConnect: boolean) => ({ payload: { serverId, autoConnect }, }), reducer: (state, { payload }: PayloadAction) => { const { serverId, autoConnect } = payload; if (!state[serverId]) { return state; } if (!autoConnect) { return { ...state, [serverId]: { ...state[serverId], autoConnect } }; } return Object.fromEntries( Object.entries(state).map(([evaluatedServerId, server]) => [ evaluatedServerId, { ...server, autoConnect: evaluatedServerId === serverId }, ]), ); }, }, createServers: { prepare: (servers: ServerData[]) => { const payload = serversListToMap(servers.map(serverWithId)); return { payload }; }, reducer: (state, { payload: newServers }: PayloadAction) => ({ ...state, ...newServers }), }, }, }); export const { editServer, deleteServer, setAutoConnect, createServers } = actions; export const serversReducer = reducer;