mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2026-03-14 11:33:51 +00:00
Provide API client to shlink-web-component
This commit is contained in:
@@ -22,7 +22,7 @@ type LastVisitLoader = (excludeBots?: boolean) => Promise<Visit | undefined>;
|
||||
|
||||
interface VisitsAsyncThunkOptions<T extends LoadVisits = LoadVisits, R extends VisitsLoaded = VisitsLoaded> {
|
||||
typePrefix: string;
|
||||
createLoaders: (params: T, getState: () => ShlinkState) => [VisitsLoader, LastVisitLoader];
|
||||
createLoaders: (params: T) => [VisitsLoader, LastVisitLoader];
|
||||
getExtraFulfilledPayload: (params: T) => Partial<R>;
|
||||
shouldCancel: (getState: () => ShlinkState) => boolean;
|
||||
}
|
||||
@@ -35,7 +35,7 @@ export const createVisitsAsyncThunk = <T extends LoadVisits = LoadVisits, R exte
|
||||
const fallbackToInterval = createAction<DateInterval>(`${typePrefix}/fallbackToInterval`);
|
||||
|
||||
const asyncThunk = createAsyncThunk(typePrefix, async (params: T, { getState, dispatch }): Promise<Partial<R>> => {
|
||||
const [visitsLoader, lastVisitLoader] = createLoaders(params, getState);
|
||||
const [visitsLoader, lastVisitLoader] = createLoaders(params);
|
||||
|
||||
const loadVisitsInParallel = async (pages: number[]): Promise<Visit[]> =>
|
||||
Promise.all(pages.map(async (page) => visitsLoader(page, ITEMS_PER_PAGE).then(prop('data')))).then(flatten);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ShlinkApiClientBuilder } from '../../../api/services/ShlinkApiClientBuilder';
|
||||
import type { ShlinkApiClient } from '../../../api/services/ShlinkApiClient';
|
||||
import { isBetween } from '../../../utils/helpers/date';
|
||||
import { domainMatches } from '../../short-urls/helpers';
|
||||
import { createVisitsAsyncThunk, createVisitsReducer, lastVisitLoaderForLoader } from './common';
|
||||
@@ -26,10 +26,10 @@ const initialState: DomainVisits = {
|
||||
progress: 0,
|
||||
};
|
||||
|
||||
export const getDomainVisits = (buildShlinkApiClient: ShlinkApiClientBuilder) => createVisitsAsyncThunk({
|
||||
export const getDomainVisits = (apiClient: ShlinkApiClient) => createVisitsAsyncThunk({
|
||||
typePrefix: `${REDUCER_PREFIX}/getDomainVisits`,
|
||||
createLoaders: ({ domain, query = {}, doIntervalFallback = false }: LoadDomainVisits, getState) => {
|
||||
const { getDomainVisits: getVisits } = buildShlinkApiClient(getState);
|
||||
createLoaders: ({ domain, query = {}, doIntervalFallback = false }: LoadDomainVisits) => {
|
||||
const { getDomainVisits: getVisits } = apiClient;
|
||||
const visitsLoader = async (page: number, itemsPerPage: number) => getVisits(
|
||||
domain,
|
||||
{ ...query, page, itemsPerPage },
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { ShlinkApiClient } from '../../../api/services/ShlinkApiClient';
|
||||
import type { ShlinkApiClientBuilder } from '../../../api/services/ShlinkApiClientBuilder';
|
||||
import { isBetween } from '../../../utils/helpers/date';
|
||||
import { createVisitsAsyncThunk, createVisitsReducer, lastVisitLoaderForLoader } from './common';
|
||||
@@ -14,10 +15,10 @@ const initialState: VisitsInfo = {
|
||||
progress: 0,
|
||||
};
|
||||
|
||||
export const getNonOrphanVisits = (buildShlinkApiClient: ShlinkApiClientBuilder) => createVisitsAsyncThunk({
|
||||
export const getNonOrphanVisits = (apiClient: ShlinkApiClient) => createVisitsAsyncThunk({
|
||||
typePrefix: `${REDUCER_PREFIX}/getNonOrphanVisits`,
|
||||
createLoaders: ({ query = {}, doIntervalFallback = false }, getState) => {
|
||||
const { getNonOrphanVisits: shlinkGetNonOrphanVisits } = buildShlinkApiClient(getState);
|
||||
createLoaders: ({ query = {}, doIntervalFallback = false }) => {
|
||||
const { getNonOrphanVisits: shlinkGetNonOrphanVisits } = apiClient;
|
||||
const visitsLoader = async (page: number, itemsPerPage: number) =>
|
||||
shlinkGetNonOrphanVisits({ ...query, page, itemsPerPage });
|
||||
const lastVisitLoader = lastVisitLoaderForLoader(doIntervalFallback, shlinkGetNonOrphanVisits);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { ShlinkApiClient } from '../../../api/services/ShlinkApiClient';
|
||||
import type { ShlinkApiClientBuilder } from '../../../api/services/ShlinkApiClientBuilder';
|
||||
import { isBetween } from '../../../utils/helpers/date';
|
||||
import type { OrphanVisit, OrphanVisitType } from '../types';
|
||||
@@ -23,10 +24,10 @@ const initialState: VisitsInfo = {
|
||||
const matchesType = (visit: OrphanVisit, orphanVisitsType?: OrphanVisitType) =>
|
||||
!orphanVisitsType || orphanVisitsType === visit.type;
|
||||
|
||||
export const getOrphanVisits = (buildShlinkApiClient: ShlinkApiClientBuilder) => createVisitsAsyncThunk({
|
||||
export const getOrphanVisits = (apiClient: ShlinkApiClient) => createVisitsAsyncThunk({
|
||||
typePrefix: `${REDUCER_PREFIX}/getOrphanVisits`,
|
||||
createLoaders: ({ orphanVisitsType, query = {}, doIntervalFallback = false }: LoadOrphanVisits, getState) => {
|
||||
const { getOrphanVisits: getVisits } = buildShlinkApiClient(getState);
|
||||
createLoaders: ({ orphanVisitsType, query = {}, doIntervalFallback = false }: LoadOrphanVisits) => {
|
||||
const { getOrphanVisits: getVisits } = apiClient;
|
||||
const visitsLoader = async (page: number, itemsPerPage: number) => getVisits({ ...query, page, itemsPerPage })
|
||||
.then((result) => {
|
||||
const visits = result.data.filter((visit) => isOrphanVisit(visit) && matchesType(visit, orphanVisitsType));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ShlinkApiClientBuilder } from '../../../api/services/ShlinkApiClientBuilder';
|
||||
import type { ShlinkApiClient } from '../../../api/services/ShlinkApiClient';
|
||||
import { isBetween } from '../../../utils/helpers/date';
|
||||
import type { ShortUrlIdentifier } from '../../short-urls/data';
|
||||
import { shortUrlMatches } from '../../short-urls/helpers';
|
||||
@@ -24,10 +24,10 @@ const initialState: ShortUrlVisits = {
|
||||
progress: 0,
|
||||
};
|
||||
|
||||
export const getShortUrlVisits = (buildShlinkApiClient: ShlinkApiClientBuilder) => createVisitsAsyncThunk({
|
||||
export const getShortUrlVisits = (apiClient: ShlinkApiClient) => createVisitsAsyncThunk({
|
||||
typePrefix: `${REDUCER_PREFIX}/getShortUrlVisits`,
|
||||
createLoaders: ({ shortCode, query = {}, doIntervalFallback = false }: LoadShortUrlVisits, getState) => {
|
||||
const { getShortUrlVisits: shlinkGetShortUrlVisits } = buildShlinkApiClient(getState);
|
||||
createLoaders: ({ shortCode, query = {}, doIntervalFallback = false }: LoadShortUrlVisits) => {
|
||||
const { getShortUrlVisits: shlinkGetShortUrlVisits } = apiClient;
|
||||
const visitsLoader = async (page: number, itemsPerPage: number) => shlinkGetShortUrlVisits(
|
||||
shortCode,
|
||||
{ ...query, page, itemsPerPage },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ShlinkApiClientBuilder } from '../../../api/services/ShlinkApiClientBuilder';
|
||||
import type { ShlinkApiClient } from '../../../api/services/ShlinkApiClient';
|
||||
import { isBetween } from '../../../utils/helpers/date';
|
||||
import { createVisitsAsyncThunk, createVisitsReducer, lastVisitLoaderForLoader } from './common';
|
||||
import type { LoadVisits, VisitsInfo } from './types';
|
||||
@@ -23,10 +23,10 @@ const initialState: TagVisits = {
|
||||
progress: 0,
|
||||
};
|
||||
|
||||
export const getTagVisits = (buildShlinkApiClient: ShlinkApiClientBuilder) => createVisitsAsyncThunk({
|
||||
export const getTagVisits = (apiClient: ShlinkApiClient) => createVisitsAsyncThunk({
|
||||
typePrefix: `${REDUCER_PREFIX}/getTagVisits`,
|
||||
createLoaders: ({ tag, query = {}, doIntervalFallback = false }: LoadTagVisits, getState) => {
|
||||
const { getTagVisits: getVisits } = buildShlinkApiClient(getState);
|
||||
createLoaders: ({ tag, query = {}, doIntervalFallback = false }: LoadTagVisits) => {
|
||||
const { getTagVisits: getVisits } = apiClient;
|
||||
const visitsLoader = async (page: number, itemsPerPage: number) => getVisits(
|
||||
tag,
|
||||
{ ...query, page, itemsPerPage },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import type { ShlinkApiClientBuilder } from '../../../api/services/ShlinkApiClientBuilder';
|
||||
import type { ShlinkApiClient } from '../../../api/services/ShlinkApiClient';
|
||||
import type { ShlinkVisitsOverview } from '../../../api/types';
|
||||
import { createAsyncThunk } from '../../../utils/helpers/redux';
|
||||
import type { CreateVisit } from '../types';
|
||||
@@ -40,19 +40,19 @@ const initialState: VisitsOverview = {
|
||||
|
||||
const countBots = (visits: CreateVisit[]) => visits.filter(({ visit }) => visit.potentialBot).length;
|
||||
|
||||
export const loadVisitsOverview = (buildShlinkApiClient: ShlinkApiClientBuilder) => createAsyncThunk(
|
||||
export const loadVisitsOverview = (apiClient: ShlinkApiClient) => createAsyncThunk(
|
||||
`${REDUCER_PREFIX}/loadVisitsOverview`,
|
||||
(_: void, { getState }): Promise<ParsedVisitsOverview> => buildShlinkApiClient(getState).getVisitsOverview().then(
|
||||
(resp) => ({
|
||||
(): Promise<ParsedVisitsOverview> => apiClient.getVisitsOverview().then(
|
||||
({ nonOrphanVisits, visitsCount, orphanVisits, orphanVisitsCount }) => ({
|
||||
nonOrphanVisits: {
|
||||
total: resp.nonOrphanVisits?.total ?? resp.visitsCount,
|
||||
nonBots: resp.nonOrphanVisits?.nonBots,
|
||||
bots: resp.nonOrphanVisits?.bots,
|
||||
total: nonOrphanVisits?.total ?? visitsCount,
|
||||
nonBots: nonOrphanVisits?.nonBots,
|
||||
bots: nonOrphanVisits?.bots,
|
||||
},
|
||||
orphanVisits: {
|
||||
total: resp.orphanVisits?.total ?? resp.orphanVisitsCount,
|
||||
nonBots: resp.orphanVisits?.nonBots,
|
||||
bots: resp.orphanVisits?.bots,
|
||||
total: orphanVisits?.total ?? orphanVisitsCount,
|
||||
nonBots: orphanVisits?.nonBots,
|
||||
bots: orphanVisits?.bots,
|
||||
},
|
||||
}),
|
||||
),
|
||||
|
||||
@@ -54,23 +54,23 @@ export const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
|
||||
bottle.serviceFactory('VisitsParser', () => visitsParser);
|
||||
|
||||
// Actions
|
||||
bottle.serviceFactory('getShortUrlVisits', getShortUrlVisits, 'buildShlinkApiClient');
|
||||
bottle.serviceFactory('getShortUrlVisits', getShortUrlVisits, 'apiClient');
|
||||
bottle.serviceFactory('cancelGetShortUrlVisits', prop('cancelGetVisits'), 'shortUrlVisitsReducerCreator');
|
||||
|
||||
bottle.serviceFactory('getTagVisits', getTagVisits, 'buildShlinkApiClient');
|
||||
bottle.serviceFactory('getTagVisits', getTagVisits, 'apiClient');
|
||||
bottle.serviceFactory('cancelGetTagVisits', prop('cancelGetVisits'), 'tagVisitsReducerCreator');
|
||||
|
||||
bottle.serviceFactory('getDomainVisits', getDomainVisits, 'buildShlinkApiClient');
|
||||
bottle.serviceFactory('getDomainVisits', getDomainVisits, 'apiClient');
|
||||
bottle.serviceFactory('cancelGetDomainVisits', prop('cancelGetVisits'), 'domainVisitsReducerCreator');
|
||||
|
||||
bottle.serviceFactory('getOrphanVisits', getOrphanVisits, 'buildShlinkApiClient');
|
||||
bottle.serviceFactory('getOrphanVisits', getOrphanVisits, 'apiClient');
|
||||
bottle.serviceFactory('cancelGetOrphanVisits', prop('cancelGetVisits'), 'orphanVisitsReducerCreator');
|
||||
|
||||
bottle.serviceFactory('getNonOrphanVisits', getNonOrphanVisits, 'buildShlinkApiClient');
|
||||
bottle.serviceFactory('getNonOrphanVisits', getNonOrphanVisits, 'apiClient');
|
||||
bottle.serviceFactory('cancelGetNonOrphanVisits', prop('cancelGetVisits'), 'nonOrphanVisitsReducerCreator');
|
||||
|
||||
bottle.serviceFactory('createNewVisits', () => createNewVisits);
|
||||
bottle.serviceFactory('loadVisitsOverview', loadVisitsOverview, 'buildShlinkApiClient');
|
||||
bottle.serviceFactory('loadVisitsOverview', loadVisitsOverview, 'apiClient');
|
||||
|
||||
// Reducers
|
||||
bottle.serviceFactory('visitsOverviewReducerCreator', visitsOverviewReducerCreator, 'loadVisitsOverview');
|
||||
|
||||
Reference in New Issue
Block a user