mirror of
https://github.com/umami-software/umami.git
synced 2026-02-07 14:17:13 +01:00
Convert realtime components to TS.
This commit is contained in:
parent
e67282d7d8
commit
8d31f43f0f
12 changed files with 75 additions and 51 deletions
|
|
@ -6,7 +6,7 @@ import { EventDataMetricsBar } from './EventDataMetricsBar';
|
|||
import { useDateRange, useApi, useNavigation } from 'components/hooks';
|
||||
import styles from './WebsiteEventData.module.css';
|
||||
|
||||
function useData(websiteId, event) {
|
||||
function useData(websiteId: string, event: string) {
|
||||
const [dateRange] = useDateRange(websiteId);
|
||||
const { startDate, endDate } = dateRange;
|
||||
const { get, useQuery } = useApi();
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
'use client';
|
||||
import { useMemo, useState, useEffect } from 'react';
|
||||
import { subMinutes, startOfMinute } from 'date-fns';
|
||||
import firstBy from 'thenby';
|
||||
import thenby from 'thenby';
|
||||
import { Grid, GridRow } from 'components/layout/Grid';
|
||||
import Page from 'components/layout/Page';
|
||||
import RealtimeChart from 'components/metrics/RealtimeChart';
|
||||
|
|
@ -15,9 +15,10 @@ import useApi from 'components/hooks/useApi';
|
|||
import { percentFilter } from 'lib/filters';
|
||||
import { REALTIME_RANGE, REALTIME_INTERVAL } from 'lib/constants';
|
||||
import { useWebsite } from 'components/hooks';
|
||||
import { RealtimeData } from 'lib/types';
|
||||
import styles from './Realtime.module.css';
|
||||
|
||||
function mergeData(state = [], data = [], time) {
|
||||
function mergeData(state = [], data = [], time: number) {
|
||||
const ids = state.map(({ __id }) => __id);
|
||||
return state
|
||||
.concat(data.filter(({ __id }) => !ids.includes(__id)))
|
||||
|
|
@ -25,7 +26,7 @@ function mergeData(state = [], data = [], time) {
|
|||
}
|
||||
|
||||
export function Realtime({ websiteId }) {
|
||||
const [currentData, setCurrentData] = useState();
|
||||
const [currentData, setCurrentData] = useState<RealtimeData>();
|
||||
const { get, useQuery } = useApi();
|
||||
const { data: website } = useWebsite(websiteId);
|
||||
const { data, isLoading, error } = useQuery({
|
||||
|
|
@ -33,7 +34,6 @@ export function Realtime({ websiteId }) {
|
|||
queryFn: () => get(`/realtime/${websiteId}`, { startAt: currentData?.timestamp || 0 }),
|
||||
enabled: !!(websiteId && website),
|
||||
refetchInterval: REALTIME_INTERVAL,
|
||||
cache: false,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -50,9 +50,9 @@ export function Realtime({ websiteId }) {
|
|||
}
|
||||
}, [data]);
|
||||
|
||||
const realtimeData = useMemo(() => {
|
||||
const realtimeData: RealtimeData = useMemo(() => {
|
||||
if (!currentData) {
|
||||
return { pageviews: [], sessions: [], events: [], countries: [], visitors: [] };
|
||||
return { pageviews: [], sessions: [], events: [], countries: [], visitors: [], timestamp: 0 };
|
||||
}
|
||||
|
||||
currentData.countries = percentFilter(
|
||||
|
|
@ -75,7 +75,7 @@ export function Realtime({ websiteId }) {
|
|||
}
|
||||
return arr;
|
||||
}, [])
|
||||
.sort(firstBy('y', -1)),
|
||||
.sort(thenby.firstBy('y', -1)),
|
||||
);
|
||||
|
||||
currentData.visitors = currentData.sessions.reduce((arr, val) => {
|
||||
|
|
@ -89,18 +89,18 @@ export function Realtime({ websiteId }) {
|
|||
}, [currentData]);
|
||||
|
||||
if (isLoading || error) {
|
||||
return <Page loading={isLoading} error={error} />;
|
||||
return <Page isLoading={isLoading} error={error} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<WebsiteHeader websiteId={websiteId} />
|
||||
<RealtimeHeader websiteId={websiteId} data={currentData} />
|
||||
<RealtimeHeader data={currentData} />
|
||||
<RealtimeChart className={styles.chart} data={realtimeData} unit="minute" />
|
||||
<Grid>
|
||||
<GridRow columns="one-two">
|
||||
<RealtimeUrls websiteId={websiteId} websiteDomain={website?.domain} data={realtimeData} />
|
||||
<RealtimeLog websiteId={websiteId} websiteDomain={website?.domain} data={realtimeData} />
|
||||
<RealtimeUrls websiteDomain={website?.domain} data={realtimeData} />
|
||||
<RealtimeLog websiteDomain={website?.domain} data={realtimeData} />
|
||||
</GridRow>
|
||||
<GridRow columns="one-two">
|
||||
<RealtimeCountries data={realtimeData?.countries} />
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
import MetricCard from 'components/metrics/MetricCard';
|
||||
import useMessages from 'components/hooks/useMessages';
|
||||
import { RealtimeData } from 'lib/types';
|
||||
import styles from './RealtimeHeader.module.css';
|
||||
|
||||
export function RealtimeHeader({ data = {} }) {
|
||||
export function RealtimeHeader({ data }: { data: RealtimeData }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { pageviews, visitors, events, countries } = data;
|
||||
const { pageviews, visitors, events, countries } = data || {};
|
||||
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { useMemo, useState } from 'react';
|
||||
import { StatusLight, Icon, Text } from 'react-basics';
|
||||
import { FixedSizeList } from 'react-window';
|
||||
import firstBy from 'thenby';
|
||||
import thenby from 'thenby';
|
||||
import FilterButtons from 'components/common/FilterButtons';
|
||||
import Empty from 'components/common/Empty';
|
||||
import useLocale from 'components/hooks/useLocale';
|
||||
|
|
@ -130,7 +130,7 @@ export function RealtimeLog({ data, websiteDomain }) {
|
|||
}
|
||||
|
||||
const { pageviews, visitors, events } = data;
|
||||
const logs = [...pageviews, ...visitors, ...events].sort(firstBy('createdAt', -1));
|
||||
const logs = [...pageviews, ...visitors, ...events].sort(thenby.firstBy('createdAt', -1));
|
||||
|
||||
if (filter !== TYPE_ALL) {
|
||||
return logs.filter(({ __type }) => __type === filter);
|
||||
|
|
@ -1,15 +1,22 @@
|
|||
import { useMemo, useState } from 'react';
|
||||
import { Key, useMemo, useState } from 'react';
|
||||
import { ButtonGroup, Button, Flexbox } from 'react-basics';
|
||||
import firstBy from 'thenby';
|
||||
import thenby from 'thenby';
|
||||
import { percentFilter } from 'lib/filters';
|
||||
import ListTable from 'components/metrics/ListTable';
|
||||
import { FILTER_PAGES, FILTER_REFERRERS } from 'lib/constants';
|
||||
import useMessages from 'components/hooks/useMessages';
|
||||
import { RealtimeData } from 'lib/types';
|
||||
|
||||
export function RealtimeUrls({ websiteDomain, data = {} }) {
|
||||
export function RealtimeUrls({
|
||||
websiteDomain,
|
||||
data,
|
||||
}: {
|
||||
websiteDomain: string;
|
||||
data: RealtimeData;
|
||||
}) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { pageviews } = data;
|
||||
const [filter, setFilter] = useState(FILTER_REFERRERS);
|
||||
const { pageviews } = data || {};
|
||||
const [filter, setFilter] = useState<Key>(FILTER_REFERRERS);
|
||||
const limit = 15;
|
||||
|
||||
const buttons = [
|
||||
|
|
@ -48,7 +55,7 @@ export function RealtimeUrls({ websiteDomain, data = {} }) {
|
|||
}
|
||||
return arr;
|
||||
}, [])
|
||||
.sort(firstBy('y', -1))
|
||||
.sort(thenby.firstBy('y', -1))
|
||||
.slice(0, limit),
|
||||
);
|
||||
|
||||
|
|
@ -64,7 +71,7 @@ export function RealtimeUrls({ websiteDomain, data = {} }) {
|
|||
}
|
||||
return arr;
|
||||
}, [])
|
||||
.sort(firstBy('y', -1))
|
||||
.sort(thenby.firstBy('y', -1))
|
||||
.slice(0, limit),
|
||||
);
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue