Migrated progress and fallback visits actions to payload actions

This commit is contained in:
Alejandro Celaya 2022-11-12 09:01:43 +01:00
parent c6eec8b266
commit 32f7374d92
13 changed files with 55 additions and 47 deletions

View file

@ -33,4 +33,4 @@ export default (container: IContainer) => combineReducers<ShlinkState>({
visitsOverview: container.visitsOverviewReducer,
appUpdated: appUpdatesReducer,
sidebar: sidebarReducer,
});
} as any); // TODO Fix this

View file

@ -1,7 +1,7 @@
import { flatten, prop, range, splitEvery } from 'ramda';
import { Action, Dispatch } from 'redux';
import { ShlinkPaginator, ShlinkVisits, ShlinkVisitsParams } from '../../api/types';
import { Visit } from '../types';
import { Visit, VisitsLoadProgressChangedAction } from '../types';
import { parseApiError } from '../../api/utils';
import { ApiErrorAction } from '../../api/types/actions';
import { dateToMatchingInterval } from '../../utils/dates/types';
@ -36,9 +36,9 @@ export const getVisitsWithLoader = async <T extends Action<string> & { visits: V
const data = await loadVisitsInParallel(pagesBlocks[index]);
dispatch({
dispatch<VisitsLoadProgressChangedAction>({
type: `${actionsPrefix}/progressChanged`,
progress: calcProgress(pagesBlocks.length, index + PARALLEL_STARTING_PAGE),
payload: calcProgress(pagesBlocks.length, index + PARALLEL_STARTING_PAGE),
});
if (index < pagesBlocks.length - 1) {
@ -72,7 +72,7 @@ export const getVisitsWithLoader = async <T extends Action<string> & { visits: V
dispatch(
!visits.length && lastVisit
? { type: `${actionsPrefix}/fallbackToInterval`, fallbackInterval: dateToMatchingInterval(lastVisit.date) }
? { type: `${actionsPrefix}/fallbackToInterval`, payload: dateToMatchingInterval(lastVisit.date) }
: { ...extraFinishActionData, visits, type: `${actionsPrefix}/fulfilled` },
);
} catch (e: any) {

View file

@ -56,11 +56,11 @@ export default buildReducer<DomainVisits, DomainVisitsCombinedAction>({
),
[`${REDUCER_PREFIX}/getDomainVisits/large`]: (state) => ({ ...state, loadingLarge: true }),
[`${REDUCER_PREFIX}/getDomainVisits/cancel`]: (state) => ({ ...state, cancelLoad: true }),
[`${REDUCER_PREFIX}/getDomainVisits/progressChanged`]: (state, { progress }) => ({ ...state, progress }),
[`${REDUCER_PREFIX}/getDomainVisits/fallbackToInterval`]: (state, { fallbackInterval }) => (
[`${REDUCER_PREFIX}/getDomainVisits/progressChanged`]: (state, { payload: progress }) => ({ ...state, progress }),
[`${REDUCER_PREFIX}/getDomainVisits/fallbackToInterval`]: (state, { payload: fallbackInterval }) => (
{ ...state, fallbackInterval }
),
[createNewVisits.toString()]: (state, { payload }) => {
[createNewVisits.toString()]: (state, { payload }: CreateVisitsAction) => {
const { domain, visits, query = {} } = state;
const { startDate, endDate } = query;
const newVisits = payload.createdVisits

View file

@ -54,11 +54,11 @@ export default buildReducer<VisitsInfo, NonOrphanVisitsCombinedAction>({
),
[`${REDUCER_PREFIX}/getNonOrphanVisits/large`]: (state) => ({ ...state, loadingLarge: true }),
[`${REDUCER_PREFIX}/getNonOrphanVisits/cancel`]: (state) => ({ ...state, cancelLoad: true }),
[`${REDUCER_PREFIX}/getNonOrphanVisits/progressChanged`]: (state, { progress }) => ({ ...state, progress }),
[`${REDUCER_PREFIX}/getNonOrphanVisits/fallbackToInterval`]: (state, { fallbackInterval }) => (
[`${REDUCER_PREFIX}/getNonOrphanVisits/progressChanged`]: (state, { payload: progress }) => ({ ...state, progress }),
[`${REDUCER_PREFIX}/getNonOrphanVisits/fallbackToInterval`]: (state, { payload: fallbackInterval }) => (
{ ...state, fallbackInterval }
),
[createNewVisits.toString()]: (state, { payload }) => {
[createNewVisits.toString()]: (state, { payload }: CreateVisitsAction) => {
const { visits, query = {} } = state;
const { startDate, endDate } = query;
const newVisits = payload.createdVisits

View file

@ -55,11 +55,11 @@ export default buildReducer<VisitsInfo, OrphanVisitsCombinedAction>({
),
[`${REDUCER_PREFIX}/getOrphanVisits/large`]: (state) => ({ ...state, loadingLarge: true }),
[`${REDUCER_PREFIX}/getOrphanVisits/cancel`]: (state) => ({ ...state, cancelLoad: true }),
[`${REDUCER_PREFIX}/getOrphanVisits/progressChanged`]: (state, { progress }) => ({ ...state, progress }),
[`${REDUCER_PREFIX}/getOrphanVisits/fallbackToInterval`]: (state, { fallbackInterval }) => (
[`${REDUCER_PREFIX}/getOrphanVisits/progressChanged`]: (state, { payload: progress }) => ({ ...state, progress }),
[`${REDUCER_PREFIX}/getOrphanVisits/fallbackToInterval`]: (state, { payload: fallbackInterval }) => (
{ ...state, fallbackInterval }
),
[createNewVisits.toString()]: (state, { payload }) => {
[createNewVisits.toString()]: (state, { payload }: CreateVisitsAction) => {
const { visits, query = {} } = state;
const { startDate, endDate } = query;
const newVisits = payload.createdVisits

View file

@ -60,11 +60,11 @@ export default buildReducer<ShortUrlVisits, ShortUrlVisitsCombinedAction>({
}),
[`${REDUCER_PREFIX}/getShortUrlVisits/large`]: (state) => ({ ...state, loadingLarge: true }),
[`${REDUCER_PREFIX}/getShortUrlVisits/cancel`]: (state) => ({ ...state, cancelLoad: true }),
[`${REDUCER_PREFIX}/getShortUrlVisits/progressChanged`]: (state, { progress }) => ({ ...state, progress }),
[`${REDUCER_PREFIX}/getShortUrlVisits/fallbackToInterval`]: (state, { fallbackInterval }) => (
[`${REDUCER_PREFIX}/getShortUrlVisits/progressChanged`]: (state, { payload: progress }) => ({ ...state, progress }),
[`${REDUCER_PREFIX}/getShortUrlVisits/fallbackToInterval`]: (state, { payload: fallbackInterval }) => (
{ ...state, fallbackInterval }
),
[createNewVisits.toString()]: (state, { payload }) => {
[createNewVisits.toString()]: (state, { payload }: CreateVisitsAction) => {
const { shortCode, domain, visits, query = {} } = state;
const { startDate, endDate } = query;
const newVisits = payload.createdVisits

View file

@ -53,11 +53,11 @@ export default buildReducer<TagVisits, TagsVisitsCombinedAction>({
),
[`${REDUCER_PREFIX}/getTagVisits/large`]: (state) => ({ ...state, loadingLarge: true }),
[`${REDUCER_PREFIX}/getTagVisits/cancel`]: (state) => ({ ...state, cancelLoad: true }),
[`${REDUCER_PREFIX}/getTagVisits/progressChanged`]: (state, { progress }) => ({ ...state, progress }),
[`${REDUCER_PREFIX}/getTagVisits/fallbackToInterval`]: (state, { fallbackInterval }) => (
[`${REDUCER_PREFIX}/getTagVisits/progressChanged`]: (state, { payload: progress }) => ({ ...state, progress }),
[`${REDUCER_PREFIX}/getTagVisits/fallbackToInterval`]: (state, { payload: fallbackInterval }) => (
{ ...state, fallbackInterval }
),
[createNewVisits.toString()]: (state, { payload }) => {
[createNewVisits.toString()]: (state, { payload }: CreateVisitsAction) => {
const { tag, visits, query = {} } = state;
const { startDate, endDate } = query;
const newVisits = payload.createdVisits

View file

@ -1,4 +1,4 @@
import { Action } from 'redux';
import { PayloadAction } from '@reduxjs/toolkit';
import { ShortUrl } from '../../short-urls/data';
import { ShlinkVisitsParams } from '../../api/types';
import { DateInterval, DateRange } from '../../utils/dates/types';
@ -16,13 +16,9 @@ export interface VisitsInfo {
fallbackInterval?: DateInterval;
}
export interface VisitsLoadProgressChangedAction extends Action<string> {
progress: number;
}
export type VisitsLoadProgressChangedAction = PayloadAction<number>;
export interface VisitsFallbackIntervalAction extends Action<string> {
fallbackInterval: DateInterval;
}
export type VisitsFallbackIntervalAction = PayloadAction<DateInterval>;
export type OrphanVisitType = 'base_url' | 'invalid_short_url' | 'regular_404';

View file

@ -142,14 +142,17 @@ describe('domainVisitsReducer', () => {
});
it('returns new progress on GET_DOMAIN_VISITS_PROGRESS_CHANGED', () => {
const state = reducer(undefined, { type: GET_DOMAIN_VISITS_PROGRESS_CHANGED, progress: 85 } as any);
const state = reducer(undefined, { type: GET_DOMAIN_VISITS_PROGRESS_CHANGED, payload: 85 } as any);
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
});
it('returns fallbackInterval on GET_DOMAIN_VISITS_FALLBACK_TO_INTERVAL', () => {
const fallbackInterval: DateInterval = 'last30Days';
const state = reducer(undefined, { type: GET_DOMAIN_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval } as any);
const state = reducer(
undefined,
{ type: GET_DOMAIN_VISITS_FALLBACK_TO_INTERVAL, payload: fallbackInterval } as any,
);
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
});
@ -205,11 +208,11 @@ describe('domainVisitsReducer', () => {
it.each([
[
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 20)) })],
{ type: GET_DOMAIN_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval: 'last30Days' },
{ type: GET_DOMAIN_VISITS_FALLBACK_TO_INTERVAL, payload: 'last30Days' },
],
[
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 100)) })],
{ type: GET_DOMAIN_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval: 'last180Days' },
{ type: GET_DOMAIN_VISITS_FALLBACK_TO_INTERVAL, payload: 'last180Days' },
],
[[], expect.objectContaining({ type: GET_DOMAIN_VISITS })],
])('dispatches fallback interval when the list of visits is empty', async (lastVisits, expectedSecondDispatch) => {

View file

@ -114,14 +114,17 @@ describe('nonOrphanVisitsReducer', () => {
});
it('returns new progress on GET_NON_ORPHAN_VISITS_PROGRESS_CHANGED', () => {
const state = reducer(undefined, { type: GET_NON_ORPHAN_VISITS_PROGRESS_CHANGED, progress: 85 } as any);
const state = reducer(undefined, { type: GET_NON_ORPHAN_VISITS_PROGRESS_CHANGED, payload: 85 } as any);
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
});
it('returns fallbackInterval on GET_NON_ORPHAN_VISITS_FALLBACK_TO_INTERVAL', () => {
const fallbackInterval: DateInterval = 'last30Days';
const state = reducer(undefined, { type: GET_NON_ORPHAN_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval } as any);
const state = reducer(
undefined,
{ type: GET_NON_ORPHAN_VISITS_FALLBACK_TO_INTERVAL, payload: fallbackInterval } as any,
);
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
});
@ -176,11 +179,11 @@ describe('nonOrphanVisitsReducer', () => {
it.each([
[
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 5)) })],
{ type: GET_NON_ORPHAN_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval: 'last7Days' },
{ type: GET_NON_ORPHAN_VISITS_FALLBACK_TO_INTERVAL, payload: 'last7Days' },
],
[
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 200)) })],
{ type: GET_NON_ORPHAN_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval: 'last365Days' },
{ type: GET_NON_ORPHAN_VISITS_FALLBACK_TO_INTERVAL, payload: 'last365Days' },
],
[[], expect.objectContaining({ type: GET_NON_ORPHAN_VISITS })],
])('dispatches fallback interval when the list of visits is empty', async (lastVisits, expectedSecondDispatch) => {

View file

@ -114,14 +114,17 @@ describe('orphanVisitsReducer', () => {
});
it('returns new progress on GET_ORPHAN_VISITS_PROGRESS_CHANGED', () => {
const state = reducer(undefined, { type: GET_ORPHAN_VISITS_PROGRESS_CHANGED, progress: 85 } as any);
const state = reducer(undefined, { type: GET_ORPHAN_VISITS_PROGRESS_CHANGED, payload: 85 } as any);
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
});
it('returns fallbackInterval on GET_ORPHAN_VISITS_FALLBACK_TO_INTERVAL', () => {
const fallbackInterval: DateInterval = 'last30Days';
const state = reducer(undefined, { type: GET_ORPHAN_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval } as any);
const state = reducer(
undefined,
{ type: GET_ORPHAN_VISITS_FALLBACK_TO_INTERVAL, payload: fallbackInterval } as any,
);
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
});
@ -176,11 +179,11 @@ describe('orphanVisitsReducer', () => {
it.each([
[
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 5)) })],
{ type: GET_ORPHAN_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval: 'last7Days' },
{ type: GET_ORPHAN_VISITS_FALLBACK_TO_INTERVAL, payload: 'last7Days' },
],
[
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 200)) })],
{ type: GET_ORPHAN_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval: 'last365Days' },
{ type: GET_ORPHAN_VISITS_FALLBACK_TO_INTERVAL, payload: 'last365Days' },
],
[[], expect.objectContaining({ type: GET_ORPHAN_VISITS })],
])('dispatches fallback interval when the list of visits is empty', async (lastVisits, expectedSecondDispatch) => {

View file

@ -135,14 +135,17 @@ describe('shortUrlVisitsReducer', () => {
});
it('returns new progress on GET_SHORT_URL_VISITS_PROGRESS_CHANGED', () => {
const state = reducer(undefined, { type: GET_SHORT_URL_VISITS_PROGRESS_CHANGED, progress: 85 } as any);
const state = reducer(undefined, { type: GET_SHORT_URL_VISITS_PROGRESS_CHANGED, payload: 85 } as any);
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
});
it('returns fallbackInterval on GET_SHORT_URL_VISITS_FALLBACK_TO_INTERVAL', () => {
const fallbackInterval: DateInterval = 'last30Days';
const state = reducer(undefined, { type: GET_SHORT_URL_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval } as any);
const state = reducer(
undefined,
{ type: GET_SHORT_URL_VISITS_FALLBACK_TO_INTERVAL, payload: fallbackInterval } as any,
);
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
});
@ -222,11 +225,11 @@ describe('shortUrlVisitsReducer', () => {
it.each([
[
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 5)) })],
{ type: GET_SHORT_URL_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval: 'last7Days' },
{ type: GET_SHORT_URL_VISITS_FALLBACK_TO_INTERVAL, payload: 'last7Days' },
],
[
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 200)) })],
{ type: GET_SHORT_URL_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval: 'last365Days' },
{ type: GET_SHORT_URL_VISITS_FALLBACK_TO_INTERVAL, payload: 'last365Days' },
],
[[], expect.objectContaining({ type: GET_SHORT_URL_VISITS })],
])('dispatches fallback interval when the list of visits is empty', async (lastVisits, expectedSecondDispatch) => {

View file

@ -135,14 +135,14 @@ describe('tagVisitsReducer', () => {
});
it('returns new progress on GET_TAG_VISITS_PROGRESS_CHANGED', () => {
const state = reducer(undefined, { type: GET_TAG_VISITS_PROGRESS_CHANGED, progress: 85 } as any);
const state = reducer(undefined, { type: GET_TAG_VISITS_PROGRESS_CHANGED, payload: 85 } as any);
expect(state).toEqual(expect.objectContaining({ progress: 85 }));
});
it('returns fallbackInterval on GET_TAG_VISITS_FALLBACK_TO_INTERVAL', () => {
const fallbackInterval: DateInterval = 'last30Days';
const state = reducer(undefined, { type: GET_TAG_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval } as any);
const state = reducer(undefined, { type: GET_TAG_VISITS_FALLBACK_TO_INTERVAL, payload: fallbackInterval } as any);
expect(state).toEqual(expect.objectContaining({ fallbackInterval }));
});
@ -198,11 +198,11 @@ describe('tagVisitsReducer', () => {
it.each([
[
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 20)) })],
{ type: GET_TAG_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval: 'last30Days' },
{ type: GET_TAG_VISITS_FALLBACK_TO_INTERVAL, payload: 'last30Days' },
],
[
[Mock.of<Visit>({ date: formatISO(subDays(new Date(), 100)) })],
{ type: GET_TAG_VISITS_FALLBACK_TO_INTERVAL, fallbackInterval: 'last180Days' },
{ type: GET_TAG_VISITS_FALLBACK_TO_INTERVAL, payload: 'last180Days' },
],
[[], expect.objectContaining({ type: GET_TAG_VISITS })],
])('dispatches fallback interval when the list of visits is empty', async (lastVisits, expectedSecondDispatch) => {