Merge pull request #1043 from Kdecherf/fix/referrer

Fix regression on referrer filter and filter view based on referrer
This commit is contained in:
Mike Cao 2022-03-25 07:44:39 -07:00 committed by GitHub
commit deca4e925c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 43 additions and 28 deletions

View File

@ -30,7 +30,7 @@ export default function MetricsTable({
const { const {
resolve, resolve,
router, router,
query: { url }, query: { url, referrer },
} = usePageQuery(); } = usePageQuery();
const { data, loading, error } = useFetch( const { data, loading, error } = useFetch(
@ -41,12 +41,13 @@ export default function MetricsTable({
start_at: +startDate, start_at: +startDate,
end_at: +endDate, end_at: +endDate,
url, url,
referrer,
}, },
onDataLoad, onDataLoad,
delay: DEFAULT_ANIMATION_DURATION, delay: DEFAULT_ANIMATION_DURATION,
headers: { [TOKEN_HEADER]: shareToken?.token }, headers: { [TOKEN_HEADER]: shareToken?.token },
}, },
[modified], [modified, url, referrer],
); );
const filteredData = useMemo(() => { const filteredData = useMemo(() => {

View File

@ -19,7 +19,7 @@ export default function ReferrersTable({ websiteId, websiteDomain, showFilters,
const [filter, setFilter] = useState(FILTER_COMBINED); const [filter, setFilter] = useState(FILTER_COMBINED);
const { const {
resolve, resolve,
query: { ref: currentRef }, query: { referrer: currentRef },
} = usePageQuery(); } = usePageQuery();
const buttons = [ const buttons = [
@ -37,7 +37,7 @@ export default function ReferrersTable({ websiteId, websiteDomain, showFilters,
const renderLink = ({ w: link, x: label }) => { const renderLink = ({ w: link, x: label }) => {
return ( return (
<div className={styles.row}> <div className={styles.row}>
<Link href={resolve({ ref: label })} replace={true}> <Link href={resolve({ referrer: label })} replace={true}>
<a <a
className={classNames(styles.label, { className={classNames(styles.label, {
[styles.inactive]: currentRef && label !== currentRef, [styles.inactive]: currentRef && label !== currentRef,

View File

@ -33,7 +33,7 @@ export default function WebsiteChart({
const { const {
router, router,
resolve, resolve,
query: { url, ref }, query: { url, referrer },
} = usePageQuery(); } = usePageQuery();
const { get } = useApi(); const { get } = useApi();
@ -46,12 +46,12 @@ export default function WebsiteChart({
unit, unit,
tz: timezone, tz: timezone,
url, url,
ref, referrer,
}, },
onDataLoad, onDataLoad,
headers: { [TOKEN_HEADER]: shareToken?.token }, headers: { [TOKEN_HEADER]: shareToken?.token },
}, },
[modified, url, ref], [modified, url, referrer],
); );
const chartData = useMemo(() => { const chartData = useMemo(() => {
@ -88,7 +88,7 @@ export default function WebsiteChart({
stickyClassName={styles.sticky} stickyClassName={styles.sticky}
enabled={stickyHeader} enabled={stickyHeader}
> >
<FilterTags params={{ url, ref }} onClick={handleCloseFilter} /> <FilterTags params={{ url, referrer }} onClick={handleCloseFilter} />
<div className="col-12 col-lg-9"> <div className="col-12 col-lg-9">
<MetricsBar websiteId={websiteId} /> <MetricsBar websiteId={websiteId} />
</div> </div>

View File

@ -1,5 +1,5 @@
import { BROWSERS } from './constants'; import { BROWSERS } from './constants';
import { removeTrailingSlash, removeWWW } from './url'; import { removeTrailingSlash, removeWWW, getDomainName } from './url';
export const urlFilter = (data, { raw }) => { export const urlFilter = (data, { raw }) => {
const isValidUrl = url => { const isValidUrl = url => {
@ -46,11 +46,14 @@ export const urlFilter = (data, { raw }) => {
}; };
export const refFilter = (data, { domain, domainOnly, raw }) => { export const refFilter = (data, { domain, domainOnly, raw }) => {
const regex = new RegExp(`http[s]?://([a-z0-9-]+\\.)*${domain}`); const domainName = getDomainName(domain);
const regex = new RegExp(`http[s]?://([a-z0-9-]+\\.)*${domainName}`);
const links = {}; const links = {};
const isValidRef = ref => { const isValidRef = referrer => {
return ref !== '' && ref !== null && !ref.startsWith('/') && !ref.startsWith('#'); return (
referrer !== '' && referrer !== null && !referrer.startsWith('/') && !referrer.startsWith('#')
);
}; };
const cleanUrl = url => { const cleanUrl = url => {
@ -71,8 +74,8 @@ export const refFilter = (data, { domain, domainOnly, raw }) => {
if (protocol.startsWith('http')) { if (protocol.startsWith('http')) {
const path = removeTrailingSlash(pathname); const path = removeTrailingSlash(pathname);
const ref = searchParams.get('ref'); const referrer = searchParams.get('referrer');
const query = ref ? `?ref=${ref}` : ''; const query = referrer ? `?referrer=${referrer}` : '';
return removeTrailingSlash(`${removeWWW(hostname)}${path}`) + query; return removeTrailingSlash(`${removeWWW(hostname)}${path}`) + query;
} }

View File

@ -335,7 +335,7 @@ export async function getEvents(websites, start_at) {
export function getWebsiteStats(website_id, start_at, end_at, filters = {}) { export function getWebsiteStats(website_id, start_at, end_at, filters = {}) {
const params = [website_id, start_at, end_at]; const params = [website_id, start_at, end_at];
const { url, ref } = filters; const { url, referrer } = filters;
let urlFilter = ''; let urlFilter = '';
let refFilter = ''; let refFilter = '';
@ -344,9 +344,9 @@ export function getWebsiteStats(website_id, start_at, end_at, filters = {}) {
params.push(decodeURIComponent(url)); params.push(decodeURIComponent(url));
} }
if (ref) { if (referrer) {
refFilter = `and referrer like $${params.length + 1}`; refFilter = `and referrer like $${params.length + 1}`;
params.push(`%${decodeURIComponent(ref)}%`); params.push(`%${decodeURIComponent(referrer)}%`);
} }
return rawQuery( return rawQuery(
@ -382,7 +382,7 @@ export function getPageviewStats(
filters = {}, filters = {},
) { ) {
const params = [website_id, start_at, end_at]; const params = [website_id, start_at, end_at];
const { url, ref } = filters; const { url, referrer } = filters;
let urlFilter = ''; let urlFilter = '';
let refFilter = ''; let refFilter = '';
@ -392,9 +392,9 @@ export function getPageviewStats(
params.push(decodeURIComponent(url)); params.push(decodeURIComponent(url));
} }
if (ref) { if (referrer) {
refFilter = `and referrer like $${params.length + 1}`; refFilter = `and referrer like $${params.length + 1}`;
params.push(`%${decodeURIComponent(ref)}%`); params.push(`%${decodeURIComponent(referrer)}%`);
} }
return rawQuery( return rawQuery(
@ -444,10 +444,11 @@ export function getSessionMetrics(website_id, start_at, end_at, field, filters =
export function getPageviewMetrics(website_id, start_at, end_at, field, table, filters = {}) { export function getPageviewMetrics(website_id, start_at, end_at, field, table, filters = {}) {
const params = [website_id, start_at, end_at]; const params = [website_id, start_at, end_at];
const { domain, url } = filters; const { domain, url, referrer } = filters;
let domainFilter = ''; let domainFilter = '';
let urlFilter = ''; let urlFilter = '';
let refFilter = '';
if (domain) { if (domain) {
domainFilter = `and referrer not like $${params.length + 1} and referrer not like '/%'`; domainFilter = `and referrer not like $${params.length + 1} and referrer not like '/%'`;
@ -459,6 +460,11 @@ export function getPageviewMetrics(website_id, start_at, end_at, field, table, f
params.push(decodeURIComponent(url)); params.push(decodeURIComponent(url));
} }
if (referrer) {
refFilter = `and referrer like $${params.length + 1}`;
params.push(`%${decodeURIComponent(referrer)}%`);
}
return rawQuery( return rawQuery(
` `
select ${field} x, count(*) y select ${field} x, count(*) y
@ -467,6 +473,7 @@ export function getPageviewMetrics(website_id, start_at, end_at, field, table, f
and created_at between $2 and $3 and created_at between $2 and $3
${domainFilter} ${domainFilter}
${urlFilter} ${urlFilter}
${refFilter}
group by 1 group by 1
order by 2 desc order by 2 desc
`, `,

View File

@ -30,7 +30,7 @@ export default async (req, res) => {
return unauthorized(res); return unauthorized(res);
} }
const { id, type, start_at, end_at, url } = req.query; const { id, type, start_at, end_at, url, referrer } = req.query;
const websiteId = +id; const websiteId = +id;
const startDate = new Date(+start_at); const startDate = new Date(+start_at);
@ -75,6 +75,7 @@ export default async (req, res) => {
{ {
domain, domain,
url: type !== 'url' && url, url: type !== 'url' && url,
referrer,
}, },
); );

View File

@ -11,7 +11,7 @@ export default async (req, res) => {
return unauthorized(res); return unauthorized(res);
} }
const { id, start_at, end_at, unit, tz, url, ref } = req.query; const { id, start_at, end_at, unit, tz, url, referrer } = req.query;
const websiteId = +id; const websiteId = +id;
const startDate = new Date(+start_at); const startDate = new Date(+start_at);
@ -22,10 +22,10 @@ export default async (req, res) => {
} }
const [pageviews, sessions] = await Promise.all([ const [pageviews, sessions] = await Promise.all([
getPageviewStats(websiteId, startDate, endDate, tz, unit, '*', { url, ref }), getPageviewStats(websiteId, startDate, endDate, tz, unit, '*', { url, referrer }),
getPageviewStats(websiteId, startDate, endDate, tz, unit, 'distinct session_id', { getPageviewStats(websiteId, startDate, endDate, tz, unit, 'distinct session_id', {
url, url,
ref, referrer,
}), }),
]); ]);

View File

@ -8,7 +8,7 @@ export default async (req, res) => {
return unauthorized(res); return unauthorized(res);
} }
const { id, start_at, end_at, url, ref } = req.query; const { id, start_at, end_at, url, referrer } = req.query;
const websiteId = +id; const websiteId = +id;
const startDate = new Date(+start_at); const startDate = new Date(+start_at);
@ -18,8 +18,11 @@ export default async (req, res) => {
const prevStartDate = new Date(+start_at - distance); const prevStartDate = new Date(+start_at - distance);
const prevEndDate = new Date(+end_at - distance); const prevEndDate = new Date(+end_at - distance);
const metrics = await getWebsiteStats(websiteId, startDate, endDate, { url, ref }); const metrics = await getWebsiteStats(websiteId, startDate, endDate, { url, referrer });
const prevPeriod = await getWebsiteStats(websiteId, prevStartDate, prevEndDate, { url, ref }); const prevPeriod = await getWebsiteStats(websiteId, prevStartDate, prevEndDate, {
url,
referrer,
});
const stats = Object.keys(metrics[0]).reduce((obj, key) => { const stats = Object.keys(metrics[0]).reduce((obj, key) => {
obj[key] = { obj[key] = {