Merge branch 'dev' into os-names

This commit is contained in:
Mike Cao 2024-02-14 22:15:08 -08:00 committed by GitHub
commit 37e28bbf74
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
472 changed files with 5460 additions and 5026 deletions

View file

@ -1,7 +1,7 @@
import { useMemo } from 'react';
import { StatusLight } from 'react-basics';
import useApi from 'components/hooks/useApi';
import useMessages from 'components/hooks/useMessages';
import { useApi } from 'components/hooks';
import { useMessages } from 'components/hooks';
import styles from './ActiveUsers.module.css';
export function ActiveUsers({

View file

@ -4,8 +4,8 @@ import classNames from 'classnames';
import Chart from 'chart.js/auto';
import HoverTooltip from 'components/common/HoverTooltip';
import Legend from 'components/metrics/Legend';
import useLocale from 'components/hooks/useLocale';
import useTheme from 'components/hooks/useTheme';
import { useLocale } from 'components/hooks';
import { useTheme } from 'components/hooks';
import { DEFAULT_ANIMATION_DURATION } from 'lib/constants';
import { renderNumberLabels } from 'lib/charts';
import styles from './BarChart.module.css';

View file

@ -1,7 +1,7 @@
import FilterLink from 'components/common/FilterLink';
import MetricsTable, { MetricsTableProps } from 'components/metrics/MetricsTable';
import useMessages from 'components/hooks/useMessages';
import useFormat from 'components/hooks/useFormat';
import { useMessages } from 'components/hooks';
import { useFormat } from 'components/hooks';
export function BrowsersTable(props: MetricsTableProps) {
const { formatMessage, labels } = useMessages();

View file

@ -1,9 +1,9 @@
import MetricsTable, { MetricsTableProps } from './MetricsTable';
import { emptyFilter } from 'lib/filters';
import FilterLink from 'components/common/FilterLink';
import useLocale from 'components/hooks/useLocale';
import useMessages from 'components/hooks/useMessages';
import useCountryNames from 'components/hooks/useCountryNames';
import { useLocale } from 'components/hooks';
import { useMessages } from 'components/hooks';
import { useCountryNames } from 'components/hooks';
export function CitiesTable(props: MetricsTableProps) {
const { locale } = useLocale();

View file

@ -1,5 +1,5 @@
import FilterLink from 'components/common/FilterLink';
import useCountryNames from 'components/hooks/useCountryNames';
import { useCountryNames } from 'components/hooks';
import { useLocale, useMessages, useFormat } from 'components/hooks';
import MetricsTable, { MetricsTableProps } from './MetricsTable';

View file

@ -1,9 +1,9 @@
import { useState } from 'react';
import { Button, ButtonGroup, Calendar } from 'react-basics';
import { isAfter, isBefore, isSameDay, startOfDay, endOfDay } from 'date-fns';
import useLocale from 'components/hooks/useLocale';
import { useLocale } from 'components/hooks';
import { FILTER_DAY, FILTER_RANGE } from 'lib/constants';
import useMessages from 'components/hooks/useMessages';
import { useMessages } from 'components/hooks';
import styles from './DatePickerForm.module.css';
export function DatePickerForm({

View file

@ -1,6 +1,6 @@
import MetricsTable, { MetricsTableProps } from './MetricsTable';
import FilterLink from 'components/common/FilterLink';
import useMessages from 'components/hooks/useMessages';
import { useMessages } from 'components/hooks';
import { useFormat } from 'components/hooks';
export function DevicesTable(props: MetricsTableProps) {

View file

@ -3,7 +3,13 @@ import { Loading } from 'react-basics';
import { colord } from 'colord';
import BarChart from './BarChart';
import { getDateArray } from 'lib/date';
import { useApi, useLocale, useDateRange, useTimezone, useNavigation } from 'components/hooks';
import {
useLocale,
useDateRange,
useTimezone,
useNavigation,
useWebsiteEvents,
} from 'components/hooks';
import { EVENT_COLORS } from 'lib/constants';
import { renderDateLabels, renderStatusTooltipPopup } from 'lib/charts';
@ -14,34 +20,29 @@ export interface EventsChartProps {
}
export function EventsChart({ websiteId, className, token }: EventsChartProps) {
const { get, useQuery } = useApi();
const [{ startDate, endDate, unit, modified }] = useDateRange(websiteId);
const [{ startDate, endDate, unit, offset }] = useDateRange(websiteId);
const { locale } = useLocale();
const [timezone] = useTimezone();
const {
query: { url, event },
} = useNavigation();
const { data, isLoading } = useQuery({
queryKey: ['events', websiteId, modified, event],
queryFn: () =>
get(`/websites/${websiteId}/events`, {
startAt: +startDate,
endAt: +endDate,
unit,
timezone,
url,
event,
token,
}),
enabled: !!websiteId,
const { data, isLoading } = useWebsiteEvents(websiteId, {
startAt: +startDate,
endAt: +endDate,
unit,
timezone,
url,
event,
token,
offset,
});
const datasets = useMemo(() => {
if (!data) return [];
if (isLoading) return data;
const map = data.reduce((obj, { x, t, y }) => {
const map = (data as any[]).reduce((obj, { x, t, y }) => {
if (!obj[x]) {
obj[x] = [];
}
@ -75,12 +76,12 @@ export function EventsChart({ websiteId, className, token }: EventsChartProps) {
return (
<BarChart
className={className}
datasets={datasets}
datasets={datasets as any[]}
unit={unit}
loading={isLoading}
stacked
stacked={true}
renderXLabel={renderDateLabels(unit, locale)}
renderTooltipPopup={renderStatusTooltipPopup(unit, locale)}
isLoading={isLoading}
/>
);
}

View file

@ -1,5 +1,5 @@
import MetricsTable, { MetricsTableProps } from './MetricsTable';
import useMessages from 'components/hooks/useMessages';
import { useMessages } from 'components/hooks';
export function EventsTable(props: MetricsTableProps) {
const { formatMessage, labels } = useMessages();

View file

@ -1,8 +1,8 @@
import { safeDecodeURI } from 'next-basics';
import { Button, Icon, Icons, Text } from 'react-basics';
import useNavigation from 'components/hooks/useNavigation';
import useMessages from 'components/hooks/useMessages';
import useFormat from 'components/hooks/useFormat';
import { useNavigation } from 'components/hooks';
import { useMessages } from 'components/hooks';
import { useFormat } from 'components/hooks';
import styles from './FilterTags.module.css';
export function FilterTags({ params }) {
@ -10,7 +10,7 @@ export function FilterTags({ params }) {
const { formatValue } = useFormat();
const {
router,
makeUrl,
renderUrl,
query: { view },
} = useNavigation();
@ -19,11 +19,11 @@ export function FilterTags({ params }) {
}
function handleCloseFilter(param?: string) {
router.push(makeUrl({ [param]: undefined }));
router.push(renderUrl({ [param]: undefined }));
}
function handleResetFilter() {
router.push(makeUrl({ view }, true));
router.push(renderUrl({ view }, true));
}
return (

View file

@ -1,8 +1,8 @@
import MetricsTable, { MetricsTableProps } from './MetricsTable';
import { percentFilter } from 'lib/filters';
import useLanguageNames from 'components/hooks/useLanguageNames';
import useLocale from 'components/hooks/useLocale';
import useMessages from 'components/hooks/useMessages';
import { useLanguageNames } from 'components/hooks';
import { useLocale } from 'components/hooks';
import { useMessages } from 'components/hooks';
export function LanguagesTable({
onDataLoad,

View file

@ -2,15 +2,15 @@ import { useEffect } from 'react';
import { StatusLight } from 'react-basics';
import { colord } from 'colord';
import classNames from 'classnames';
import useLocale from 'components/hooks/useLocale';
import useForceUpdate from 'components/hooks/useForceUpdate';
import { useLocale } from 'components/hooks';
import { useForceUpdate } from 'components/hooks';
import styles from './Legend.module.css';
export function Legend({ chart }) {
const { locale } = useLocale();
const forceUpdate = useForceUpdate();
const handleClick = index => {
const handleClick = (index: string | number) => {
const meta = chart.getDatasetMeta(index);
meta.hidden = meta.hidden === null ? !chart.data.datasets[index].hidden : null;

View file

@ -3,7 +3,7 @@ import { useSpring, animated, config } from '@react-spring/web';
import classNames from 'classnames';
import Empty from 'components/common/Empty';
import { formatLongNumber } from 'lib/format';
import useMessages from 'components/hooks/useMessages';
import { useMessages } from 'components/hooks';
import styles from './ListTable.module.css';
import { ReactNode } from 'react';
@ -63,6 +63,7 @@ export function ListTable({
{data?.length === 0 && <Empty className={styles.empty} />}
{virtualize && data.length > 0 ? (
<FixedSizeList
width="100%"
height={itemCount * ITEM_SIZE}
itemCount={data.length}
itemSize={ITEM_SIZE}

View file

@ -1,18 +1,20 @@
import { ReactNode, useMemo, useState } from 'react';
import { Loading, Icon, Text, SearchField } from 'react-basics';
import classNames from 'classnames';
import useApi from 'components/hooks/useApi';
import { percentFilter } from 'lib/filters';
import useDateRange from 'components/hooks/useDateRange';
import useNavigation from 'components/hooks/useNavigation';
import ErrorMessage from 'components/common/ErrorMessage';
import LinkButton from 'components/common/LinkButton';
import ListTable, { ListTableProps } from './ListTable';
import { DEFAULT_ANIMATION_DURATION } from 'lib/constants';
import { percentFilter } from 'lib/filters';
import {
useDateRange,
useNavigation,
useWebsiteMetrics,
useMessages,
useLocale,
useFormat,
} from 'components/hooks';
import Icons from 'components/icons';
import useMessages from 'components/hooks/useMessages';
import useLocale from 'components/hooks/useLocale';
import useFormat from 'components//hooks/useFormat';
import ListTable, { ListTableProps } from './ListTable';
import styles from './MetricsTable.module.css';
export interface MetricsTableProps extends ListTableProps {
@ -43,55 +45,36 @@ export function MetricsTable({
}: MetricsTableProps) {
const [search, setSearch] = useState('');
const { formatValue } = useFormat();
const [{ startDate, endDate, modified }] = useDateRange(websiteId);
const [{ startDate, endDate }] = useDateRange(websiteId);
const {
makeUrl,
renderUrl,
query: { url, referrer, title, os, browser, device, country, region, city },
} = useNavigation();
const { formatMessage, labels } = useMessages();
const { get, useQuery } = useApi();
const { dir } = useLocale();
const { data, isLoading, isFetched, error } = useQuery({
queryKey: [
'websites:metrics',
{
websiteId,
type,
modified,
url,
referrer,
os,
title,
browser,
device,
country,
region,
city,
},
],
queryFn: async () => {
const filters = { url, title, referrer, os, browser, device, country, region, city };
filters[type] = undefined;
const data = await get(`/websites/${websiteId}/metrics`, {
type,
startAt: +startDate,
endAt: +endDate,
limit,
...filters,
});
onDataLoad?.(data);
return data;
const { data, isLoading, isFetched, error } = useWebsiteMetrics(
websiteId,
{
type,
startAt: +startDate,
endAt: +endDate,
url,
referrer,
os,
title,
browser,
device,
country,
region,
city,
},
retryDelay: delay || DEFAULT_ANIMATION_DURATION,
});
{ retryDelay: delay || DEFAULT_ANIMATION_DURATION, onDataLoad },
);
const filteredData = useMemo(() => {
if (data) {
let items: any[] = data;
let items = data as any[];
if (dataFilter) {
if (Array.isArray(dataFilter)) {
@ -142,7 +125,7 @@ export function MetricsTable({
{!data && isLoading && !isFetched && <Loading icon="dots" />}
<div className={styles.footer}>
{data && !error && limit && (
<LinkButton href={makeUrl({ view: type })} variant="quiet">
<LinkButton href={renderUrl({ view: type })} variant="quiet">
<Text>{formatMessage(labels.more)}</Text>
<Icon size="sm" rotate={dir === 'rtl' ? 180 : 0}>
<Icons.ArrowRight />

View file

@ -1,7 +1,6 @@
import MetricsTable, { MetricsTableProps } from './MetricsTable';
import FilterLink from 'components/common/FilterLink';
import useMessages from 'components/hooks/useMessages';
import useFormat from 'components/hooks/useFormat';
import { useMessages, useFormat } from 'components/hooks';
export function OSTable(props: MetricsTableProps) {
const { formatMessage, labels } = useMessages();

View file

@ -1,8 +1,8 @@
import FilterLink from 'components/common/FilterLink';
import FilterButtons from 'components/common/FilterButtons';
import MetricsTable, { MetricsTableProps } from './MetricsTable';
import useMessages from 'components/hooks/useMessages';
import useNavigation from 'components/hooks/useNavigation';
import { useMessages } from 'components/hooks';
import { useNavigation } from 'components/hooks';
import { emptyFilter } from 'lib/filters';
export interface PagesTableProps extends MetricsTableProps {
@ -12,13 +12,13 @@ export interface PagesTableProps extends MetricsTableProps {
export function PagesTable({ allowFilter, domainName, ...props }: PagesTableProps) {
const {
router,
makeUrl,
renderUrl,
query: { view = 'url' },
} = useNavigation();
const { formatMessage, labels } = useMessages();
const handleSelect = (key: any) => {
router.push(makeUrl({ view: key }), { scroll: true });
router.push(renderUrl({ view: key }), { scroll: true });
};
const buttons = [

View file

@ -4,7 +4,7 @@ import FilterButtons from 'components/common/FilterButtons';
import { emptyFilter, paramFilter } from 'lib/filters';
import { FILTER_RAW, FILTER_COMBINED } from 'lib/constants';
import MetricsTable, { MetricsTableProps } from './MetricsTable';
import useMessages from 'components/hooks/useMessages';
import { useMessages } from 'components/hooks';
import styles from './QueryParametersTable.module.css';
const filters = {

View file

@ -1,6 +1,6 @@
import MetricsTable, { MetricsTableProps } from './MetricsTable';
import FilterLink from 'components/common/FilterLink';
import useMessages from 'components/hooks/useMessages';
import { useMessages } from 'components/hooks';
export function ReferrersTable(props: MetricsTableProps) {
const { formatMessage, labels } = useMessages();

View file

@ -1,10 +1,10 @@
import FilterLink from 'components/common/FilterLink';
import { emptyFilter } from 'lib/filters';
import useLocale from 'components/hooks/useLocale';
import useMessages from 'components/hooks/useMessages';
import useCountryNames from 'components/hooks/useCountryNames';
import { useLocale } from 'components/hooks';
import { useMessages } from 'components/hooks';
import { useCountryNames } from 'components/hooks';
import MetricsTable, { MetricsTableProps } from './MetricsTable';
import regions from 'public/iso-3166-2.json';
import regions from '../../../public/iso-3166-2.json';
export function RegionsTable(props: MetricsTableProps) {
const { locale } = useLocale();

View file

@ -1,5 +1,5 @@
import MetricsTable, { MetricsTableProps } from './MetricsTable';
import useMessages from 'components/hooks/useMessages';
import { useMessages } from 'components/hooks';
export function ScreenTable(props: MetricsTableProps) {
const { formatMessage, labels } = useMessages();

View file

@ -4,10 +4,10 @@ import classNames from 'classnames';
import { colord } from 'colord';
import HoverTooltip from 'components/common/HoverTooltip';
import { ISO_COUNTRIES, MAP_FILE } from 'lib/constants';
import useTheme from 'components/hooks/useTheme';
import useCountryNames from 'components/hooks/useCountryNames';
import useLocale from 'components/hooks/useLocale';
import useMessages from 'components/hooks/useMessages';
import { useTheme } from 'components/hooks';
import { useCountryNames } from 'components/hooks';
import { useLocale } from 'components/hooks';
import { useMessages } from 'components/hooks';
import { formatLongNumber } from 'lib/format';
import { percentFilter } from 'lib/filters';
import styles from './WorldMap.module.css';