From 8699eaca32b63d9159e77de208cb8d7ba94fa32e Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Wed, 1 Nov 2023 10:03:09 +0100 Subject: [PATCH] First batch of ramda removals --- src/common/Home.tsx | 5 ++-- src/common/ShlinkVersions.tsx | 3 +-- src/container/index.ts | 9 +++++-- src/servers/ServersDropdown.tsx | 5 ++-- src/servers/data/index.ts | 4 +-- src/servers/reducers/selectedServer.ts | 8 +++--- src/servers/reducers/servers.ts | 34 ++++++++++++++------------ src/utils/helpers/version.ts | 5 ++-- 8 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/common/Home.tsx b/src/common/Home.tsx index bf7b79bd..3388574e 100644 --- a/src/common/Home.tsx +++ b/src/common/Home.tsx @@ -1,6 +1,5 @@ import { faExternalLinkAlt, faPlus } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { isEmpty, values } from 'ramda'; import { useEffect } from 'react'; import { ExternalLink } from 'react-external-link'; import { Link, useNavigate } from 'react-router-dom'; @@ -16,8 +15,8 @@ interface HomeProps { export const Home = ({ servers }: HomeProps) => { const navigate = useNavigate(); - const serversList = values(servers); - const hasServers = !isEmpty(serversList); + const serversList = Object.values(servers); + const hasServers = serversList.length > 0; useEffect(() => { // Try to redirect to the first server marked as auto-connect diff --git a/src/common/ShlinkVersions.tsx b/src/common/ShlinkVersions.tsx index dad141d5..38a3a4aa 100644 --- a/src/common/ShlinkVersions.tsx +++ b/src/common/ShlinkVersions.tsx @@ -1,11 +1,10 @@ -import { pipe } from 'ramda'; import { ExternalLink } from 'react-external-link'; import type { SelectedServer } from '../servers/data'; import { isReachableServer } from '../servers/data'; import { versionToPrintable, versionToSemVer } from '../utils/helpers/version'; const SHLINK_WEB_CLIENT_VERSION = '%_VERSION_%'; -const normalizeVersion = pipe(versionToSemVer(), versionToPrintable); +const normalizeVersion = (version: string) => versionToPrintable(versionToSemVer(version)); export interface ShlinkVersionsProps { selectedServer: SelectedServer; diff --git a/src/container/index.ts b/src/container/index.ts index 994b95f4..75648877 100644 --- a/src/container/index.ts +++ b/src/container/index.ts @@ -1,6 +1,5 @@ import type { IContainer } from 'bottlejs'; import Bottle from 'bottlejs'; -import { pick } from 'ramda'; import { connect as reduxConnect } from 'react-redux'; import { provideServices as provideApiServices } from '../api/services/provideServices'; import { provideServices as provideAppServices } from '../app/services/provideServices'; @@ -18,14 +17,20 @@ export const { container } = bottle; const lazyService = (cont: IContainer, serviceName: string) => (...args: any[]) => (cont[serviceName] as T)(...args) as K; + const mapActionService = (map: LazyActionMap, actionName: string): LazyActionMap => ({ ...map, // Wrap actual action service in a function so that it is lazily created the first time it is called [actionName]: lazyService(container, actionName), }); + +const pickProps = (propsToPick: string[]) => (obj: any) => Object.fromEntries( + propsToPick.map((key) => [key, obj[key]]), +); + const connect: ConnectDecorator = (propsFromState: string[] | null, actionServiceNames: string[] = []) => reduxConnect( - propsFromState ? pick(propsFromState) : null, + propsFromState ? pickProps(propsFromState) : null, actionServiceNames.reduce(mapActionService, {}), ); diff --git a/src/servers/ServersDropdown.tsx b/src/servers/ServersDropdown.tsx index 0265c610..f15a93e6 100644 --- a/src/servers/ServersDropdown.tsx +++ b/src/servers/ServersDropdown.tsx @@ -1,6 +1,5 @@ import { faPlus as plusIcon, faServer as serverIcon } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { isEmpty, values } from 'ramda'; import { Link } from 'react-router-dom'; import { DropdownItem, DropdownMenu, DropdownToggle, UncontrolledDropdown } from 'reactstrap'; import type { SelectedServer, ServersMap } from './data'; @@ -12,10 +11,10 @@ export interface ServersDropdownProps { } export const ServersDropdown = ({ servers, selectedServer }: ServersDropdownProps) => { - const serversList = values(servers); + const serversList = Object.values(servers); const renderServers = () => { - if (isEmpty(serversList)) { + if (serversList.length === 0) { return ( Add a server diff --git a/src/servers/data/index.ts b/src/servers/data/index.ts index 52a98a6f..35b0e5e6 100644 --- a/src/servers/data/index.ts +++ b/src/servers/data/index.ts @@ -1,4 +1,3 @@ -import { omit } from 'ramda'; import type { SemVer } from '../../utils/helpers/version'; export interface ServerData { @@ -45,5 +44,4 @@ export const isNotFoundServer = (server: SelectedServer): server is NotFoundServ export const getServerId = (server: SelectedServer) => (isServerWithId(server) ? server.id : ''); -export const serverWithIdToServerData = (server: ServerWithId): ServerData => - omit(['id', 'autoConnect'], server); +export const serverWithIdToServerData = ({ id, autoConnect, ...server }: ServerWithId): ServerData => server; diff --git a/src/servers/reducers/selectedServer.ts b/src/servers/reducers/selectedServer.ts index e67a8c0d..5e271a14 100644 --- a/src/servers/reducers/selectedServer.ts +++ b/src/servers/reducers/selectedServer.ts @@ -1,6 +1,6 @@ import { createAction, createSlice } from '@reduxjs/toolkit'; import type { ShlinkHealth } from '@shlinkio/shlink-web-component/api-contract'; -import { memoizeWith, pipe } from 'ramda'; +import { memoizeWith } from 'ramda'; import type { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder'; import { createAsyncThunk } from '../../utils/helpers/redux'; import { versionToPrintable, versionToSemVer as toSemVer } from '../../utils/helpers/version'; @@ -12,9 +12,9 @@ export const MIN_FALLBACK_VERSION = '1.0.0'; export const MAX_FALLBACK_VERSION = '999.999.999'; export const LATEST_VERSION_CONSTRAINT = 'latest'; -const versionToSemVer = pipe( - (version: string) => (version === LATEST_VERSION_CONSTRAINT ? MAX_FALLBACK_VERSION : version), - toSemVer(MIN_FALLBACK_VERSION), +const versionToSemVer = (version: string) => toSemVer( + version === LATEST_VERSION_CONSTRAINT ? MAX_FALLBACK_VERSION : version, + MIN_FALLBACK_VERSION, ); const getServerVersion = memoizeWith( diff --git a/src/servers/reducers/servers.ts b/src/servers/reducers/servers.ts index 2402dc46..c3db31fb 100644 --- a/src/servers/reducers/servers.ts +++ b/src/servers/reducers/servers.ts @@ -1,6 +1,5 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; -import { assoc, dissoc, fromPairs, map, pipe, reduce, toPairs } from 'ramda'; import { v4 as uuid } from 'uuid'; import type { ServerData, ServersMap, ServerWithId } from '../data'; @@ -17,14 +16,17 @@ interface SetAutoConnect { const initialState: ServersMap = {}; const serverWithId = (server: ServerWithId | ServerData): ServerWithId => { - if ((server as ServerWithId).id) { - return server as ServerWithId; + if ('id' in server) { + return server; } - return assoc('id', uuid(), server); + return { ...server, id: uuid() }; }; -const serversListToMap = reduce((acc, server) => assoc(server.id, server, acc), {}); +const serversListToMap = (servers: ServerWithId[]): ServersMap => servers.reduce( + (acc, server) => ({ ...acc, [server.id]: server }), + {}, +); export const { actions, reducer } = createSlice({ name: 'shlink/servers', @@ -37,11 +39,14 @@ export const { actions, reducer } = createSlice({ reducer: (state, { payload }: PayloadAction) => { const { serverId, serverData } = payload; return ( - !state[serverId] ? state : assoc(serverId, { ...state[serverId], ...serverData }, state) + !state[serverId] ? state : { ...state, [serverId]: { ...state[serverId], ...serverData } } ); }, }, - deleteServer: (state, { payload }) => dissoc(payload.id, state), + deleteServer: (state, { payload }) => { + const { [payload.id]: deletedServer, ...rest } = state; + return rest; + }, setAutoConnect: { prepare: ({ id: serverId }: ServerWithId, autoConnect: boolean) => ({ payload: { serverId, autoConnect }, @@ -53,11 +58,11 @@ export const { actions, reducer } = createSlice({ } if (!autoConnect) { - return assoc(serverId, { ...state[serverId], autoConnect }, state); + return { ...state, [serverId]: { ...state[serverId], autoConnect } }; } - return fromPairs( - toPairs(state).map(([evaluatedServerId, server]) => [ + return Object.fromEntries( + Object.entries(state).map(([evaluatedServerId, server]) => [ evaluatedServerId, { ...server, autoConnect: evaluatedServerId === serverId }, ]), @@ -65,11 +70,10 @@ export const { actions, reducer } = createSlice({ }, }, createServers: { - prepare: pipe( - map(serverWithId), - serversListToMap, - (payload: ServersMap) => ({ payload }), - ), + prepare: (servers: ServerData[]) => { + const payload = serversListToMap(servers.map(serverWithId)); + return { payload }; + }, reducer: (state, { payload: newServers }: PayloadAction) => ({ ...state, ...newServers }), }, }, diff --git a/src/utils/helpers/version.ts b/src/utils/helpers/version.ts index 1d5d708d..cda5bbe0 100644 --- a/src/utils/helpers/version.ts +++ b/src/utils/helpers/version.ts @@ -39,5 +39,6 @@ const versionIsValidSemVer = memoizeWith(identity, (version: string): version is export const versionToPrintable = (version: string) => (!versionIsValidSemVer(version) ? version : `v${version}`); -export const versionToSemVer = (defaultValue: SemVer = 'latest') => - (version: string): SemVer => (versionIsValidSemVer(version) ? version : defaultValue); +export const versionToSemVer = (version: string, fallback: SemVer = 'latest'): SemVer => ( + versionIsValidSemVer(version) ? version : fallback +);