mirror of
https://github.com/umami-software/umami.git
synced 2026-02-12 08:37:13 +01:00
URL filter functionality.
This commit is contained in:
parent
6bc371352c
commit
4fded49b03
27 changed files with 251 additions and 117 deletions
|
|
@ -6,11 +6,13 @@ import useFetch from 'hooks/useFetch';
|
|||
import useDateRange from 'hooks/useDateRange';
|
||||
import useTimezone from 'hooks/useTimezone';
|
||||
import { EVENT_COLORS } from 'lib/constants';
|
||||
import usePageQuery from '../../hooks/usePageQuery';
|
||||
|
||||
export default function EventsChart({ websiteId, token }) {
|
||||
const [dateRange] = useDateRange(websiteId);
|
||||
const { startDate, endDate, unit, modified } = dateRange;
|
||||
const [timezone] = useTimezone();
|
||||
const { query } = usePageQuery();
|
||||
|
||||
const { data } = useFetch(
|
||||
`/api/website/${websiteId}/events`,
|
||||
|
|
@ -19,6 +21,7 @@ export default function EventsChart({ websiteId, token }) {
|
|||
end_at: +endDate,
|
||||
unit,
|
||||
tz: timezone,
|
||||
url: query.url,
|
||||
token,
|
||||
},
|
||||
{ update: [modified] },
|
||||
|
|
|
|||
|
|
@ -5,24 +5,30 @@ import Loading from 'components/common/Loading';
|
|||
import useFetch from 'hooks/useFetch';
|
||||
import useDateRange from 'hooks/useDateRange';
|
||||
import { formatShortTime, formatNumber, formatLongNumber } from 'lib/format';
|
||||
import usePageQuery from 'hooks/usePageQuery';
|
||||
import MetricCard from './MetricCard';
|
||||
import styles from './MetricsBar.module.css';
|
||||
|
||||
export default function MetricsBar({ websiteId, token, className }) {
|
||||
const [dateRange] = useDateRange(websiteId);
|
||||
const { startDate, endDate, modified } = dateRange;
|
||||
const [format, setFormat] = useState(true);
|
||||
const {
|
||||
query: { url },
|
||||
} = usePageQuery();
|
||||
|
||||
const { data } = useFetch(
|
||||
`/api/website/${websiteId}/metrics`,
|
||||
{
|
||||
start_at: +startDate,
|
||||
end_at: +endDate,
|
||||
url,
|
||||
token,
|
||||
},
|
||||
{
|
||||
update: [modified],
|
||||
},
|
||||
);
|
||||
const [format, setFormat] = useState(true);
|
||||
|
||||
const formatFunc = format ? formatLongNumber : formatNumber;
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { percentFilter } from 'lib/filters';
|
|||
import { formatNumber, formatLongNumber } from 'lib/format';
|
||||
import useDateRange from 'hooks/useDateRange';
|
||||
import styles from './MetricsTable.module.css';
|
||||
import usePageQuery from '../../hooks/usePageQuery';
|
||||
|
||||
export default function MetricsTable({
|
||||
websiteId,
|
||||
|
|
@ -30,6 +31,10 @@ export default function MetricsTable({
|
|||
}) {
|
||||
const [dateRange] = useDateRange(websiteId);
|
||||
const { startDate, endDate, modified } = dateRange;
|
||||
const {
|
||||
query: { url },
|
||||
} = usePageQuery();
|
||||
|
||||
const { data } = useFetch(
|
||||
`/api/website/${websiteId}/rankings`,
|
||||
{
|
||||
|
|
@ -37,6 +42,7 @@ export default function MetricsTable({
|
|||
start_at: +startDate,
|
||||
end_at: +endDate,
|
||||
domain: websiteDomain,
|
||||
url,
|
||||
token,
|
||||
},
|
||||
{ onDataLoad, delay: 300, update: [modified] },
|
||||
|
|
@ -101,9 +107,7 @@ export default function MetricsTable({
|
|||
<div className={styles.footer}>
|
||||
{limit && (
|
||||
<Button icon={<Arrow />} size="xsmall" onClick={() => onExpand(type)}>
|
||||
<div>
|
||||
<FormattedMessage id="button.more" defaultMessage="More" />
|
||||
</div>
|
||||
<FormattedMessage id="button.more" defaultMessage="More" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,23 @@
|
|||
import React, { useState } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import Link from 'next/link';
|
||||
import ButtonGroup from 'components/common/ButtonGroup';
|
||||
import ButtonLayout from 'components/layout/ButtonLayout';
|
||||
import { urlFilter } from 'lib/filters';
|
||||
import { FILTER_COMBINED, FILTER_RAW } from 'lib/constants';
|
||||
import usePageQuery from 'hooks/usePageQuery';
|
||||
import MetricsTable from './MetricsTable';
|
||||
import ButtonLayout from '../layout/ButtonLayout';
|
||||
|
||||
export default function PagesTable({ websiteId, token, websiteDomain, limit, onExpand }) {
|
||||
export default function PagesTable({
|
||||
websiteId,
|
||||
token,
|
||||
websiteDomain,
|
||||
limit,
|
||||
showFilters,
|
||||
onExpand,
|
||||
}) {
|
||||
const [filter, setFilter] = useState(FILTER_COMBINED);
|
||||
const { resolve } = usePageQuery();
|
||||
|
||||
const buttons = [
|
||||
{
|
||||
|
|
@ -17,9 +27,17 @@ export default function PagesTable({ websiteId, token, websiteDomain, limit, onE
|
|||
{ label: <FormattedMessage id="metrics.filter.raw" defaultMessage="Raw" />, value: FILTER_RAW },
|
||||
];
|
||||
|
||||
const renderLink = ({ x }) => {
|
||||
return (
|
||||
<Link href={resolve({ url: x })} replace={true}>
|
||||
<a>{decodeURI(x)}</a>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{!limit && <FilterButtons buttons={buttons} selected={filter} onClick={setFilter} />}
|
||||
{showFilters && <FilterButtons buttons={buttons} selected={filter} onClick={setFilter} />}
|
||||
<MetricsTable
|
||||
title={<FormattedMessage id="metrics.pages" defaultMessage="Pages" />}
|
||||
type="url"
|
||||
|
|
@ -29,7 +47,7 @@ export default function PagesTable({ websiteId, token, websiteDomain, limit, onE
|
|||
limit={limit}
|
||||
dataFilter={urlFilter}
|
||||
filterOptions={{ domain: websiteDomain, raw: filter === FILTER_RAW }}
|
||||
renderLabel={({ x }) => decodeURI(x)}
|
||||
renderLabel={renderLink}
|
||||
onExpand={onExpand}
|
||||
/>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export default function ReferrersTable({
|
|||
websiteDomain,
|
||||
token,
|
||||
limit,
|
||||
showFilters,
|
||||
onExpand = () => {},
|
||||
}) {
|
||||
const [filter, setFilter] = useState(FILTER_COMBINED);
|
||||
|
|
@ -39,7 +40,7 @@ export default function ReferrersTable({
|
|||
|
||||
return (
|
||||
<>
|
||||
{!limit && <FilterButtons buttons={buttons} selected={filter} onClick={setFilter} />}
|
||||
{showFilters && <FilterButtons buttons={buttons} selected={filter} onClick={setFilter} />}
|
||||
<MetricsTable
|
||||
title={<FormattedMessage id="metrics.referrers" defaultMessage="Referrers" />}
|
||||
type="referrer"
|
||||
|
|
|
|||
|
|
@ -5,10 +5,13 @@ import MetricsBar from './MetricsBar';
|
|||
import WebsiteHeader from './WebsiteHeader';
|
||||
import DateFilter from 'components/common/DateFilter';
|
||||
import StickyHeader from 'components/helpers/StickyHeader';
|
||||
import Button from 'components/common/Button';
|
||||
import useFetch from 'hooks/useFetch';
|
||||
import useDateRange from 'hooks/useDateRange';
|
||||
import useTimezone from 'hooks/useTimezone';
|
||||
import usePageQuery from 'hooks/usePageQuery';
|
||||
import { getDateArray, getDateLength } from 'lib/date';
|
||||
import Times from 'assets/times.svg';
|
||||
import styles from './WebsiteChart.module.css';
|
||||
|
||||
export default function WebsiteChart({
|
||||
|
|
@ -22,6 +25,11 @@ export default function WebsiteChart({
|
|||
const [dateRange, setDateRange] = useDateRange(websiteId);
|
||||
const { startDate, endDate, unit, value, modified } = dateRange;
|
||||
const [timezone] = useTimezone();
|
||||
const {
|
||||
router,
|
||||
resolve,
|
||||
query: { url },
|
||||
} = usePageQuery();
|
||||
|
||||
const { data, loading } = useFetch(
|
||||
`/api/website/${websiteId}/pageviews`,
|
||||
|
|
@ -30,6 +38,7 @@ export default function WebsiteChart({
|
|||
end_at: +endDate,
|
||||
unit,
|
||||
tz: timezone,
|
||||
url,
|
||||
token,
|
||||
},
|
||||
{ onDataLoad, update: [modified] },
|
||||
|
|
@ -45,6 +54,10 @@ export default function WebsiteChart({
|
|||
return [[], []];
|
||||
}, [data]);
|
||||
|
||||
function handleCloseFilter() {
|
||||
router.push(resolve({ url: undefined }));
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<WebsiteHeader websiteId={websiteId} token={token} title={title} showLink={showLink} />
|
||||
|
|
@ -54,6 +67,7 @@ export default function WebsiteChart({
|
|||
stickyClassName={styles.sticky}
|
||||
enabled={stickyHeader}
|
||||
>
|
||||
{url && <PageFilter url={url} onClick={handleCloseFilter} />}
|
||||
<div className="col-12 col-lg-9">
|
||||
<MetricsBar websiteId={websiteId} token={token} />
|
||||
</div>
|
||||
|
|
@ -81,3 +95,13 @@ export default function WebsiteChart({
|
|||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const PageFilter = ({ url, onClick }) => {
|
||||
return (
|
||||
<div className={classNames(styles.url, 'col-12')}>
|
||||
<Button icon={<Times />} onClick={onClick} variant="action" iconRight={true}>
|
||||
{url}
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
.url {
|
||||
text-align: center;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 992px) {
|
||||
.filter {
|
||||
display: block;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue