mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-09 09:47:28 +03:00
Migrated progress and fallback visits actions to payload actions
This commit is contained in:
parent
c6eec8b266
commit
32f7374d92
13 changed files with 55 additions and 47 deletions
|
@ -33,4 +33,4 @@ export default (container: IContainer) => combineReducers<ShlinkState>({
|
|||
visitsOverview: container.visitsOverviewReducer,
|
||||
appUpdated: appUpdatesReducer,
|
||||
sidebar: sidebarReducer,
|
||||
});
|
||||
} as any); // TODO Fix this
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
Loading…
Reference in a new issue