diff --git a/src/settings/reducers/settings.ts b/src/settings/reducers/settings.ts index e5c0d1f9..6e3e1e8c 100644 --- a/src/settings/reducers/settings.ts +++ b/src/settings/reducers/settings.ts @@ -3,6 +3,7 @@ import { dissoc, mergeDeepRight } from 'ramda'; import { buildReducer } from '../../utils/helpers/redux'; import { RecursivePartial } from '../../utils/utils'; import { Theme } from '../../utils/theme'; +import { DateInterval } from '../../utils/dates/types'; export const SET_SETTINGS = 'shlink/realTimeUpdates/SET_SETTINGS'; @@ -24,10 +25,15 @@ export interface UiSettings { theme: Theme; } +export interface VisitsSettings { + defaultInterval: DateInterval; +} + export interface Settings { realTimeUpdates: RealTimeUpdatesSettings; shortUrlCreation?: ShortUrlCreationSettings; ui?: UiSettings; + visits?: VisitsSettings; } const initialState: Settings = { @@ -40,6 +46,9 @@ const initialState: Settings = { ui: { theme: 'light', }, + visits: { + defaultInterval: 'last30Days', + }, }; type SettingsAction = Action & Settings; diff --git a/src/visits/OrphanVisits.tsx b/src/visits/OrphanVisits.tsx index cb959869..04d421eb 100644 --- a/src/visits/OrphanVisits.tsx +++ b/src/visits/OrphanVisits.tsx @@ -2,6 +2,7 @@ import { RouteComponentProps } from 'react-router'; import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub'; import { ShlinkVisitsParams } from '../api/types'; import { Topics } from '../mercure/helpers/Topics'; +import { Settings } from '../settings/reducers/settings'; import VisitsStats from './VisitsStats'; import { OrphanVisitsHeader } from './OrphanVisitsHeader'; import { VisitsInfo } from './types'; @@ -10,6 +11,7 @@ export interface OrphanVisitsProps extends RouteComponentProps { getOrphanVisits: (params: ShlinkVisitsParams) => void; orphanVisits: VisitsInfo; cancelGetOrphanVisits: () => void; + settings: Settings; } export const OrphanVisits = boundToMercureHub(({ @@ -18,12 +20,14 @@ export const OrphanVisits = boundToMercureHub(({ getOrphanVisits, orphanVisits, cancelGetOrphanVisits, + settings, }: OrphanVisitsProps) => ( diff --git a/src/visits/ShortUrlVisits.tsx b/src/visits/ShortUrlVisits.tsx index 509e34ae..d4894b0a 100644 --- a/src/visits/ShortUrlVisits.tsx +++ b/src/visits/ShortUrlVisits.tsx @@ -5,6 +5,7 @@ import { ShlinkVisitsParams } from '../api/types'; import { parseQuery } from '../utils/helpers/query'; import { Topics } from '../mercure/helpers/Topics'; import { ShortUrlDetail } from '../short-urls/reducers/shortUrlDetail'; +import { Settings } from '../settings/reducers/settings'; import { ShortUrlVisits as ShortUrlVisitsState } from './reducers/shortUrlVisits'; import ShortUrlVisitsHeader from './ShortUrlVisitsHeader'; import VisitsStats from './VisitsStats'; @@ -15,6 +16,7 @@ export interface ShortUrlVisitsProps extends RouteComponentProps<{ shortCode: st getShortUrlDetail: Function; shortUrlDetail: ShortUrlDetail; cancelGetShortUrlVisits: () => void; + settings: Settings; } const ShortUrlVisits = boundToMercureHub(({ @@ -26,6 +28,7 @@ const ShortUrlVisits = boundToMercureHub(({ getShortUrlVisits, getShortUrlDetail, cancelGetShortUrlVisits, + settings, }: ShortUrlVisitsProps) => { const { shortCode } = params; const { domain } = parseQuery<{ domain?: string }>(search); @@ -42,6 +45,7 @@ const ShortUrlVisits = boundToMercureHub(({ visitsInfo={shortUrlVisits} baseUrl={url} domain={domain} + settings={settings} > diff --git a/src/visits/TagVisits.tsx b/src/visits/TagVisits.tsx index d6772682..0f687382 100644 --- a/src/visits/TagVisits.tsx +++ b/src/visits/TagVisits.tsx @@ -3,6 +3,7 @@ import { boundToMercureHub } from '../mercure/helpers/boundToMercureHub'; import ColorGenerator from '../utils/services/ColorGenerator'; import { ShlinkVisitsParams } from '../api/types'; import { Topics } from '../mercure/helpers/Topics'; +import { Settings } from '../settings/reducers/settings'; import { TagVisits as TagVisitsState } from './reducers/tagVisits'; import TagVisitsHeader from './TagVisitsHeader'; import VisitsStats from './VisitsStats'; @@ -11,6 +12,7 @@ export interface TagVisitsProps extends RouteComponentProps<{ tag: string }> { getTagVisits: (tag: string, query: any) => void; tagVisits: TagVisitsState; cancelGetTagVisits: () => void; + settings: Settings; } const TagVisits = (colorGenerator: ColorGenerator) => boundToMercureHub(({ @@ -19,12 +21,19 @@ const TagVisits = (colorGenerator: ColorGenerator) => boundToMercureHub(({ getTagVisits, tagVisits, cancelGetTagVisits, + settings, }: TagVisitsProps) => { const { tag } = params; const loadVisits = (params: ShlinkVisitsParams) => getTagVisits(tag, params); return ( - + ); diff --git a/src/visits/VisitsStats.tsx b/src/visits/VisitsStats.tsx index 0d391717..c8d80918 100644 --- a/src/visits/VisitsStats.tsx +++ b/src/visits/VisitsStats.tsx @@ -13,6 +13,7 @@ import { ShlinkVisitsParams } from '../api/types'; import { DateInterval, DateRange, intervalToDateRange } from '../utils/dates/types'; import { Result } from '../utils/Result'; import { ShlinkApiError } from '../api/ShlinkApiError'; +import { Settings } from '../settings/reducers/settings'; import SortableBarGraph from './helpers/SortableBarGraph'; import GraphCard from './helpers/GraphCard'; import LineChartCard from './helpers/LineChartCard'; @@ -25,6 +26,7 @@ import './VisitsStats.scss'; export interface VisitsStatsProps { getVisits: (params: Partial) => void; visitsInfo: VisitsInfo; + settings: Settings; cancelGetVisits: () => void; baseUrl: string; domain?: string; @@ -59,7 +61,6 @@ const highlightedVisitsToStats = ( return acc; }, {}); let selectedBar: string | undefined; -const initialInterval: DateInterval = 'last30Days'; const VisitsNavLink: FC = ({ subPath, title, icon, to }) => ( = ({ subPath, title ); -const VisitsStats: FC = ({ children, visitsInfo, getVisits, cancelGetVisits, baseUrl, domain }) => { +const VisitsStats: FC = ( + { children, visitsInfo, getVisits, cancelGetVisits, baseUrl, domain, settings }, +) => { + const initialInterval: DateInterval = settings.visits?.defaultInterval ?? 'last30Days'; const [ dateRange, setDateRange ] = useState(intervalToDateRange(initialInterval)); const [ highlightedVisits, setHighlightedVisits ] = useState([]); const [ highlightedLabel, setHighlightedLabel ] = useState(); diff --git a/src/visits/services/provideServices.ts b/src/visits/services/provideServices.ts index 5e7775f5..3ebb8c08 100644 --- a/src/visits/services/provideServices.ts +++ b/src/visits/services/provideServices.ts @@ -18,19 +18,19 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator) => { bottle.serviceFactory('ShortUrlVisits', () => ShortUrlVisits); bottle.decorator('ShortUrlVisits', connect( - [ 'shortUrlVisits', 'shortUrlDetail', 'mercureInfo' ], + [ 'shortUrlVisits', 'shortUrlDetail', 'mercureInfo', 'settings' ], [ 'getShortUrlVisits', 'getShortUrlDetail', 'cancelGetShortUrlVisits', 'createNewVisits', 'loadMercureInfo' ], )); bottle.serviceFactory('TagVisits', TagVisits, 'ColorGenerator'); bottle.decorator('TagVisits', connect( - [ 'tagVisits', 'mercureInfo' ], + [ 'tagVisits', 'mercureInfo', 'settings' ], [ 'getTagVisits', 'cancelGetTagVisits', 'createNewVisits', 'loadMercureInfo' ], )); bottle.serviceFactory('OrphanVisits', () => OrphanVisits); bottle.decorator('OrphanVisits', connect( - [ 'orphanVisits', 'mercureInfo' ], + [ 'orphanVisits', 'mercureInfo', 'settings' ], [ 'getOrphanVisits', 'cancelGetOrphanVisits', 'createNewVisits', 'loadMercureInfo' ], )); diff --git a/test/settings/reducers/settings.test.ts b/test/settings/reducers/settings.test.ts index 57d22066..8dd423ae 100644 --- a/test/settings/reducers/settings.test.ts +++ b/test/settings/reducers/settings.test.ts @@ -10,7 +10,8 @@ describe('settingsReducer', () => { const realTimeUpdates = { enabled: true }; const shortUrlCreation = { validateUrls: false }; const ui = { theme: 'light' }; - const settings = { realTimeUpdates, shortUrlCreation, ui }; + const visits = { defaultInterval: 'last30Days' }; + const settings = { realTimeUpdates, shortUrlCreation, ui, visits }; describe('reducer', () => { it('returns realTimeUpdates when action is SET_SETTINGS', () => { diff --git a/test/visits/VisitsStats.test.tsx b/test/visits/VisitsStats.test.tsx index d878d2e8..d66255cb 100644 --- a/test/visits/VisitsStats.test.tsx +++ b/test/visits/VisitsStats.test.tsx @@ -9,6 +9,7 @@ import { Visit, VisitsInfo } from '../../src/visits/types'; import LineChartCard from '../../src/visits/helpers/LineChartCard'; import VisitsTable from '../../src/visits/VisitsTable'; import { Result } from '../../src/utils/Result'; +import { Settings } from '../../src/settings/reducers/settings'; describe('', () => { const visits = [ Mock.all(), Mock.all(), Mock.all() ]; @@ -23,6 +24,7 @@ describe('', () => { visitsInfo={Mock.of(visitsInfo)} cancelGetVisits={() => {}} baseUrl={''} + settings={Mock.all()} />, );