Created custom and better typed version of createAsyncThunk

This commit is contained in:
Alejandro Celaya 2022-11-05 09:10:30 +01:00
parent 1dd26fb76f
commit 62ab86aefa
4 changed files with 32 additions and 32 deletions

View file

@ -1,7 +1,6 @@
import { createAsyncThunk } from '@reduxjs/toolkit'; import { createAsyncThunk } from '../../utils/helpers/redux';
import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder'; import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder';
import { ShlinkDomainRedirects } from '../../api/types'; import { ShlinkDomainRedirects } from '../../api/types';
import { ShlinkState } from '../../container/types';
const EDIT_DOMAIN_REDIRECTS = 'shlink/domainRedirects/EDIT_DOMAIN_REDIRECTS'; const EDIT_DOMAIN_REDIRECTS = 'shlink/domainRedirects/EDIT_DOMAIN_REDIRECTS';
@ -12,11 +11,11 @@ export interface EditDomainRedirects {
export const editDomainRedirects = ( export const editDomainRedirects = (
buildShlinkApiClient: ShlinkApiClientBuilder, buildShlinkApiClient: ShlinkApiClientBuilder,
) => createAsyncThunk<EditDomainRedirects, EditDomainRedirects, { state: ShlinkState }>( ) => createAsyncThunk(
EDIT_DOMAIN_REDIRECTS, EDIT_DOMAIN_REDIRECTS,
async ({ domain, redirects: domainRedirects }, { getState }) => { async ({ domain, redirects: providedRedirects }: EditDomainRedirects, { getState }): Promise<EditDomainRedirects> => {
const { editDomainRedirects: shlinkEditDomainRedirects } = buildShlinkApiClient(getState); const { editDomainRedirects: shlinkEditDomainRedirects } = buildShlinkApiClient(getState);
const redirects = await shlinkEditDomainRedirects({ domain, ...domainRedirects }); const redirects = await shlinkEditDomainRedirects({ domain, ...providedRedirects });
return { domain, redirects }; return { domain, redirects };
}, },

View file

@ -1,7 +1,7 @@
import { createSlice, createAsyncThunk, createAction, SliceCaseReducers, AsyncThunk } from '@reduxjs/toolkit'; import { createSlice, createAction, SliceCaseReducers, AsyncThunk } from '@reduxjs/toolkit';
import { createAsyncThunk } from '../../utils/helpers/redux';
import { ShlinkDomainRedirects } from '../../api/types'; import { ShlinkDomainRedirects } from '../../api/types';
import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder'; import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder';
import { ShlinkState } from '../../container/types';
import { Domain, DomainStatus } from '../data'; import { Domain, DomainStatus } from '../data';
import { hasServerData } from '../../servers/data'; import { hasServerData } from '../../servers/data';
import { replaceAuthorityFromUri } from '../../utils/helpers/uri'; import { replaceAuthorityFromUri } from '../../utils/helpers/uri';
@ -49,22 +49,19 @@ export const domainsListReducerCreator = (
buildShlinkApiClient: ShlinkApiClientBuilder, buildShlinkApiClient: ShlinkApiClientBuilder,
editDomainRedirects: AsyncThunk<EditDomainRedirects, any, any>, editDomainRedirects: AsyncThunk<EditDomainRedirects, any, any>,
) => { ) => {
const listDomains = createAsyncThunk<ListDomains, void, { state: ShlinkState }>( const listDomains = createAsyncThunk(LIST_DOMAINS, async (_, { getState }): Promise<ListDomains> => {
LIST_DOMAINS, const { listDomains: shlinkListDomains } = buildShlinkApiClient(getState);
async (_, { getState }) => { const { data, defaultRedirects } = await shlinkListDomains();
const { listDomains: shlinkListDomains } = buildShlinkApiClient(getState);
const { data, defaultRedirects } = await shlinkListDomains();
return { return {
domains: data.map((domain): Domain => ({ ...domain, status: 'validating' })), domains: data.map((domain): Domain => ({ ...domain, status: 'validating' })),
defaultRedirects, defaultRedirects,
}; };
}, });
);
const checkDomainHealth = createAsyncThunk<ValidateDomain, string, { state: ShlinkState }>( const checkDomainHealth = createAsyncThunk(
VALIDATE_DOMAIN, VALIDATE_DOMAIN,
async (domain: string, { getState }) => { async (domain: string, { getState }): Promise<ValidateDomain> => {
const { selectedServer } = getState(); const { selectedServer } = getState();
if (!hasServerData(selectedServer)) { if (!hasServerData(selectedServer)) {

View file

@ -1,6 +1,6 @@
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit';
import { createAsyncThunk } from '../../utils/helpers/redux';
import { ShlinkMercureInfo } from '../../api/types'; import { ShlinkMercureInfo } from '../../api/types';
import { ShlinkState } from '../../container/types';
import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder'; import { ShlinkApiClientBuilder } from '../../api/services/ShlinkApiClientBuilder';
const GET_MERCURE_INFO = 'shlink/mercure/GET_MERCURE_INFO'; const GET_MERCURE_INFO = 'shlink/mercure/GET_MERCURE_INFO';
@ -17,17 +17,14 @@ const initialState: MercureInfo = {
}; };
export const mercureInfoReducerCreator = (buildShlinkApiClient: ShlinkApiClientBuilder) => { export const mercureInfoReducerCreator = (buildShlinkApiClient: ShlinkApiClientBuilder) => {
const loadMercureInfo = createAsyncThunk<ShlinkMercureInfo, void, { state: ShlinkState }>( const loadMercureInfo = createAsyncThunk(GET_MERCURE_INFO, async (_, { getState }): Promise<ShlinkMercureInfo> => {
GET_MERCURE_INFO, const { settings } = getState();
async (_, { getState }) => { if (!settings.realTimeUpdates.enabled) {
const { settings } = getState(); throw new Error('Real time updates not enabled');
if (!settings.realTimeUpdates.enabled) { }
throw new Error('Real time updates not enabled');
}
return buildShlinkApiClient(getState).mercureInfo(); return buildShlinkApiClient(getState).mercureInfo();
}, });
);
const { reducer } = createSlice({ const { reducer } = createSlice({
name: 'mercureInfoReducer', name: 'mercureInfoReducer',

View file

@ -1,4 +1,6 @@
import { createAsyncThunk as baseCreateAsyncThunk, AsyncThunkPayloadCreator } from '@reduxjs/toolkit';
import { Action } from 'redux'; import { Action } from 'redux';
import { ShlinkState } from '../../container/types';
type ActionHandler<State, AT> = (currentState: State, action: AT) => State; type ActionHandler<State, AT> = (currentState: State, action: AT) => State;
type ActionHandlerMap<State, AT> = Record<string, ActionHandler<State, AT>>; type ActionHandlerMap<State, AT> = Record<string, ActionHandler<State, AT>>;
@ -15,3 +17,8 @@ export const buildReducer = <State, AT extends Action>(map: ActionHandlerMap<Sta
}; };
export const buildActionCreator = <T extends string>(type: T) => (): Action<T> => ({ type }); export const buildActionCreator = <T extends string>(type: T) => (): Action<T> => ({ type });
export const createAsyncThunk = <Returned, ThunkArg>(
typePrefix: string,
payloadCreator: AsyncThunkPayloadCreator<Returned, ThunkArg, { state: ShlinkState }>,
) => baseCreateAsyncThunk(typePrefix, payloadCreator);