mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 12:47:13 +01:00
Merge branch 'dev' of https://github.com/umami-software/umami into feat/um-366-event-data-migration
This commit is contained in:
commit
3aa7565bf4
17 changed files with 639 additions and 699 deletions
|
|
@ -1,13 +1,27 @@
|
|||
import { Loading } from 'react-basics';
|
||||
import { useState } from 'react';
|
||||
import { Loading, cloneChildren } from 'react-basics';
|
||||
import ErrorMessage from 'components/common/ErrorMessage';
|
||||
import styles from './MetricsBar.module.css';
|
||||
import { formatLongNumber, formatNumber } from 'lib/format';
|
||||
|
||||
export function MetricsBar({ children, isLoading, isFetched, error }) {
|
||||
const [format, setFormat] = useState(true);
|
||||
|
||||
const formatFunc = format
|
||||
? n => (n >= 0 ? formatLongNumber(n) : `-${formatLongNumber(Math.abs(n))}`)
|
||||
: formatNumber;
|
||||
|
||||
const handleSetFormat = () => {
|
||||
setFormat(state => !state);
|
||||
};
|
||||
|
||||
export function MetricsBar({ children, onClick, isLoading, isFetched, error }) {
|
||||
return (
|
||||
<div className={styles.bar} onClick={onClick}>
|
||||
<div className={styles.bar} onClick={handleSetFormat}>
|
||||
{isLoading && !isFetched && <Loading icon="dots" />}
|
||||
{error && <ErrorMessage />}
|
||||
{children}
|
||||
{cloneChildren(children, child => {
|
||||
return { format: child.props.format || formatFunc };
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ export function EventDataMetricsBar({ websiteId }) {
|
|||
const { startDate, endDate, modified } = dateRange;
|
||||
|
||||
const { data, error, isLoading, isFetched } = useQuery(
|
||||
['event-data:fields', { websiteId, startDate, endDate, modified }],
|
||||
['event-data:stats', { websiteId, startDate, endDate, modified }],
|
||||
() =>
|
||||
get(`/event-data/fields`, {
|
||||
get(`/event-data/stats`, {
|
||||
websiteId,
|
||||
startAt: +startDate,
|
||||
endAt: +endDate,
|
||||
|
|
@ -27,11 +27,18 @@ export function EventDataMetricsBar({ websiteId }) {
|
|||
<Column defaultSize={12} xl={8}>
|
||||
<MetricsBar isLoading={isLoading} isFetched={isFetched} error={error}>
|
||||
{!error && isFetched && (
|
||||
<MetricCard
|
||||
className={styles.card}
|
||||
label={formatMessage(labels.fields)}
|
||||
value={data?.length}
|
||||
/>
|
||||
<>
|
||||
<MetricCard
|
||||
className={styles.card}
|
||||
label={formatMessage(labels.fields)}
|
||||
value={data?.fields}
|
||||
/>
|
||||
<MetricCard
|
||||
className={styles.card}
|
||||
label={formatMessage(labels.totalRecords)}
|
||||
value={data?.records}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</MetricsBar>
|
||||
</Column>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { GridTable, GridColumn } from 'react-basics';
|
|||
import { useMessages, usePageQuery } from 'hooks';
|
||||
import Empty from 'components/common/Empty';
|
||||
|
||||
export function EventDataTable({ data = [], showValue }) {
|
||||
export function EventDataTable({ data = [] }) {
|
||||
const { formatMessage, labels } = useMessages();
|
||||
const { resolveUrl } = usePageQuery();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import EventDataTable from 'components/pages/event-data/EventDataTable';
|
|||
import EventDataValueTable from 'components/pages/event-data/EventDataValueTable';
|
||||
import { EventDataMetricsBar } from 'components/pages/event-data/EventDataMetricsBar';
|
||||
import { useDateRange, useApi, usePageQuery } from 'hooks';
|
||||
import styles from './WebsiteEventData.module.css';
|
||||
|
||||
function useFields(websiteId, field) {
|
||||
const [dateRange] = useDateRange(websiteId);
|
||||
|
|
@ -11,7 +12,7 @@ function useFields(websiteId, field) {
|
|||
const { data, error, isLoading } = useQuery(
|
||||
['event-data:fields', { websiteId, startDate, endDate, field }],
|
||||
() =>
|
||||
get('/event-data', {
|
||||
get('/event-data/fields', {
|
||||
websiteId,
|
||||
startAt: +startDate,
|
||||
endAt: +endDate,
|
||||
|
|
@ -30,7 +31,7 @@ export default function WebsiteEventData({ websiteId }) {
|
|||
const { data } = useFields(websiteId, view);
|
||||
|
||||
return (
|
||||
<Flexbox direction="column" gap={20}>
|
||||
<Flexbox className={styles.container} direction="column" gap={20}>
|
||||
<EventDataMetricsBar websiteId={websiteId} />
|
||||
{!view && <EventDataTable data={data} />}
|
||||
{view && <EventDataValueTable field={view} data={data} />}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.container a {
|
||||
color: var(--font-color100);
|
||||
}
|
||||
|
||||
.container a:hover {
|
||||
color: var(--primary400);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,10 +48,7 @@ export function WebsiteHeader({ websiteId, showLinks = true, children }) {
|
|||
{showLinks && (
|
||||
<Flexbox alignItems="center">
|
||||
{links.map(({ label, icon, path }) => {
|
||||
const query = path.indexOf('?');
|
||||
const selected = path
|
||||
? asPath.endsWith(query >= 0 ? path.substring(0, query) : path)
|
||||
: pathname === '/websites/[id]';
|
||||
const selected = path ? pathname.endsWith(path) : pathname === '/websites/[id]';
|
||||
|
||||
return (
|
||||
<Link key={label} href={`/websites/${websiteId}${path}`} shallow={true}>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ export function WebsiteMetricsBar({ websiteId, sticky }) {
|
|||
const { get, useQuery } = useApi();
|
||||
const [dateRange] = useDateRange(websiteId);
|
||||
const { startDate, endDate, modified } = dateRange;
|
||||
const [format, setFormat] = useState(true);
|
||||
const { ref, isSticky } = useSticky({ enabled: sticky });
|
||||
const {
|
||||
query: { url, referrer, title, os, browser, device, country, region, city },
|
||||
|
|
@ -41,14 +40,6 @@ export function WebsiteMetricsBar({ websiteId, sticky }) {
|
|||
}),
|
||||
);
|
||||
|
||||
const formatFunc = format
|
||||
? n => (n >= 0 ? formatLongNumber(n) : `-${formatLongNumber(Math.abs(n))}`)
|
||||
: formatNumber;
|
||||
|
||||
function handleSetFormat() {
|
||||
setFormat(state => !state);
|
||||
}
|
||||
|
||||
const { pageviews, uniques, bounces, totaltime } = data || {};
|
||||
const num = Math.min(data && uniques.value, data && bounces.value);
|
||||
const diffs = data && {
|
||||
|
|
@ -67,12 +58,7 @@ export function WebsiteMetricsBar({ websiteId, sticky }) {
|
|||
})}
|
||||
>
|
||||
<Column defaultSize={12} xl={8}>
|
||||
<MetricsBar
|
||||
isLoading={isLoading}
|
||||
isFetched={isFetched}
|
||||
error={error}
|
||||
onClick={handleSetFormat}
|
||||
>
|
||||
<MetricsBar isLoading={isLoading} isFetched={isFetched} error={error}>
|
||||
{!error && isFetched && (
|
||||
<>
|
||||
<MetricCard
|
||||
|
|
@ -80,14 +66,12 @@ export function WebsiteMetricsBar({ websiteId, sticky }) {
|
|||
label={formatMessage(labels.views)}
|
||||
value={pageviews.value}
|
||||
change={pageviews.change}
|
||||
format={formatFunc}
|
||||
/>
|
||||
<MetricCard
|
||||
className={styles.card}
|
||||
label={formatMessage(labels.visitors)}
|
||||
value={uniques.value}
|
||||
change={uniques.change}
|
||||
format={formatFunc}
|
||||
/>
|
||||
<MetricCard
|
||||
className={styles.card}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue