Merge pull request #1332 from umami-software/dev

v1.36.0
pull/1337/head v1.36.0
Mike Cao 2022-07-23 14:07:54 -07:00 committed by GitHub
commit bcabc25300
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
124 changed files with 3034 additions and 247 deletions

View File

@ -22,6 +22,7 @@ export default function MetricsTable({
filterOptions, filterOptions,
limit, limit,
onDataLoad, onDataLoad,
delay = null,
...props ...props
}) { }) {
const [{ startDate, endDate, modified }] = useDateRange(websiteId); const [{ startDate, endDate, modified }] = useDateRange(websiteId);
@ -46,9 +47,9 @@ export default function MetricsTable({
country, country,
}, },
onDataLoad, onDataLoad,
delay: DEFAULT_ANIMATION_DURATION, delay: delay || DEFAULT_ANIMATION_DURATION,
}, },
[modified, url, referrer, os, browser, device, country], [type, modified, url, referrer, os, browser, device, country],
); );
const filteredData = useMemo(() => { const filteredData = useMemo(() => {

View File

@ -0,0 +1,47 @@
import React, { useState } from 'react';
import { useIntl, defineMessages } from 'react-intl';
import MetricsTable from './MetricsTable';
import FilterButtons from 'components/common/FilterButtons';
export const UTM_SOURCE = 'utm_source';
export const UTM_MEDIUM = 'utm_medium';
export const UTM_CAMPAIGN = 'utm_campaign';
export const UTM_CONTENT = 'utm_content';
export const UTM_TERM = 'utm_term';
const messages = defineMessages({
utm_source: { id: 'metrics.utm_source', defaultMessage: 'UTM Source' },
utm_medium: { id: 'metrics.utm_medium', defaultMessage: 'UTM Medium' },
utm_campaign: { id: 'metrics.utm_campaign', defaultMessage: 'UTM Campaign' },
utm_content: { id: 'metrics.utm_content', defaultMessage: 'UTM Content' },
utm_term: { id: 'metrics.utm_term', defaultMessage: 'UTM Term' },
views: { id: 'metrics.views', defaultMessage: 'Views' },
none: { id: 'label.none', defaultMessage: 'None' },
});
export default function UTMTable({ websiteId, showFilters, ...props }) {
const [type, setType] = useState(UTM_SOURCE);
const { formatMessage } = useIntl();
const buttons = [
{ label: formatMessage(messages.utm_source), value: UTM_SOURCE },
{ label: formatMessage(messages.utm_medium), value: UTM_MEDIUM },
{ label: formatMessage(messages.utm_campaign), value: UTM_CAMPAIGN },
{ label: formatMessage(messages.utm_content), value: UTM_CONTENT },
{ label: formatMessage(messages.utm_term), value: UTM_TERM },
];
return (
<>
{showFilters && <FilterButtons buttons={buttons} selected={type} onClick={setType} />}
<MetricsTable
{...props}
title={formatMessage(messages[type])}
type={type}
metric={formatMessage(messages.views)}
websiteId={websiteId}
delay={0}
/>
</>
);
}

View File

@ -23,6 +23,7 @@ import usePageQuery from 'hooks/usePageQuery';
import { DEFAULT_ANIMATION_DURATION } from 'lib/constants'; import { DEFAULT_ANIMATION_DURATION } from 'lib/constants';
import styles from './WebsiteDetails.module.css'; import styles from './WebsiteDetails.module.css';
import ScreenTable from 'components/metrics/ScreenTable'; import ScreenTable from 'components/metrics/ScreenTable';
import UTMTable from 'components/metrics/UTMTable';
const views = { const views = {
url: PagesTable, url: PagesTable,
@ -34,6 +35,7 @@ const views = {
country: CountriesTable, country: CountriesTable,
language: LanguagesTable, language: LanguagesTable,
event: EventsTable, event: EventsTable,
utm: UTMTable,
}; };
export default function WebsiteDetails({ websiteId }) { export default function WebsiteDetails({ websiteId }) {
@ -94,6 +96,10 @@ export default function WebsiteDetails({ websiteId }) {
label: <FormattedMessage id="metrics.events" defaultMessage="Events" />, label: <FormattedMessage id="metrics.events" defaultMessage="Events" />,
value: resolve({ view: 'event' }), value: resolve({ view: 'event' }),
}, },
{
label: <FormattedMessage id="metrics.utm" defaultMessage="UTM" />,
value: resolve({ view: 'utm' }),
},
]; ];
const tableProps = { const tableProps = {

View File

@ -106,6 +106,12 @@
"metrics.referrers": "التحويلات", "metrics.referrers": "التحويلات",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "زائرون فريدون", "metrics.unique-visitors": "زائرون فريدون",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "مشاهدات", "metrics.views": "مشاهدات",
"metrics.visitors": "زوار" "metrics.visitors": "زوار"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Referents", "metrics.referrers": "Referents",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Visitants únics", "metrics.unique-visitors": "Visitants únics",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Vistes", "metrics.views": "Vistes",
"metrics.visitors": "Visitants" "metrics.visitors": "Visitants"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Odkazy", "metrics.referrers": "Odkazy",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Jedinečné návštěvy", "metrics.unique-visitors": "Jedinečné návštěvy",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Zobrazení", "metrics.views": "Zobrazení",
"metrics.visitors": "Návštěvy" "metrics.visitors": "Návštěvy"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Henvisninger", "metrics.referrers": "Henvisninger",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unikke besøgende", "metrics.unique-visitors": "Unikke besøgende",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visninger", "metrics.views": "Visninger",
"metrics.visitors": "Besøgende" "metrics.visitors": "Besøgende"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Referrer", "metrics.referrers": "Referrer",
"metrics.screens": "Bildschirmauflösungen", "metrics.screens": "Bildschirmauflösungen",
"metrics.unique-visitors": "Eindeutige Besucher", "metrics.unique-visitors": "Eindeutige Besucher",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Aufrufe", "metrics.views": "Aufrufe",
"metrics.visitors": "Besucher" "metrics.visitors": "Besucher"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Παραπομπές", "metrics.referrers": "Παραπομπές",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Μοναδικοί επισκέπτες", "metrics.unique-visitors": "Μοναδικοί επισκέπτες",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Προβολές", "metrics.views": "Προβολές",
"metrics.visitors": "Επισκέπτες" "metrics.visitors": "Επισκέπτες"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Referrers", "metrics.referrers": "Referrers",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unique visitors", "metrics.unique-visitors": "Unique visitors",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Views", "metrics.views": "Views",
"metrics.visitors": "Visitors" "metrics.visitors": "Visitors"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Referrers", "metrics.referrers": "Referrers",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unique visitors", "metrics.unique-visitors": "Unique visitors",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Views", "metrics.views": "Views",
"metrics.visitors": "Visitors" "metrics.visitors": "Visitors"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Referentes", "metrics.referrers": "Referentes",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Visitantes únicos", "metrics.unique-visitors": "Visitantes únicos",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Vistas", "metrics.views": "Vistas",
"metrics.visitors": "Visitantes" "metrics.visitors": "Visitantes"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "ارجاع دهندگان", "metrics.referrers": "ارجاع دهندگان",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "بازدیدکننده‌های یکتا", "metrics.unique-visitors": "بازدیدکننده‌های یکتا",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "بازدید", "metrics.views": "بازدید",
"metrics.visitors": "بازدیدکننده" "metrics.visitors": "بازدیدکننده"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Viittaajat", "metrics.referrers": "Viittaajat",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Yksittäiset kävijät", "metrics.unique-visitors": "Yksittäiset kävijät",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Näyttökerrat", "metrics.views": "Näyttökerrat",
"metrics.visitors": "Vierailijat" "metrics.visitors": "Vierailijat"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Framsendingar", "metrics.referrers": "Framsendingar",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Einsýna vitjanir", "metrics.unique-visitors": "Einsýna vitjanir",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Sýningar", "metrics.views": "Sýningar",
"metrics.visitors": "Vitjandi" "metrics.visitors": "Vitjandi"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Sources", "metrics.referrers": "Sources",
"metrics.screens": "Tailles d'écran", "metrics.screens": "Tailles d'écran",
"metrics.unique-visitors": "Visiteurs uniques", "metrics.unique-visitors": "Visiteurs uniques",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Vues", "metrics.views": "Vues",
"metrics.visitors": "Visiteurs" "metrics.visitors": "Visiteurs"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Orixes", "metrics.referrers": "Orixes",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Visitas únicas", "metrics.unique-visitors": "Visitas únicas",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visualizacións", "metrics.views": "Visualizacións",
"metrics.visitors": "Visitantes" "metrics.visitors": "Visitantes"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "מפנים", "metrics.referrers": "מפנים",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "מבקרים ייחודיים", "metrics.unique-visitors": "מבקרים ייחודיים",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "צפיות", "metrics.views": "צפיות",
"metrics.visitors": "מבקרים" "metrics.visitors": "מבקרים"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "सन्दर्भदाता", "metrics.referrers": "सन्दर्भदाता",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "अद्वितीय आगंतुकों", "metrics.unique-visitors": "अद्वितीय आगंतुकों",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "दृश्य", "metrics.views": "दृश्य",
"metrics.visitors": "आगंतुकों" "metrics.visitors": "आगंतुकों"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Hivatkozók", "metrics.referrers": "Hivatkozók",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Egyedi látogatók", "metrics.unique-visitors": "Egyedi látogatók",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Megtekintések", "metrics.views": "Megtekintések",
"metrics.visitors": "Látogatók" "metrics.visitors": "Látogatók"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Perujuk", "metrics.referrers": "Perujuk",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Pengunjung unik", "metrics.unique-visitors": "Pengunjung unik",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Tampilan", "metrics.views": "Tampilan",
"metrics.visitors": "Pengunjung" "metrics.visitors": "Pengunjung"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Referrers", "metrics.referrers": "Referrers",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Visitatori unici", "metrics.unique-visitors": "Visitatori unici",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visualizzazioni", "metrics.views": "Visualizzazioni",
"metrics.visitors": "Visitatori" "metrics.visitors": "Visitatori"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "リファラー", "metrics.referrers": "リファラー",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "ユニーク訪問者数", "metrics.unique-visitors": "ユニーク訪問者数",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "閲覧数", "metrics.views": "閲覧数",
"metrics.visitors": "訪問者数" "metrics.visitors": "訪問者数"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "리퍼러", "metrics.referrers": "리퍼러",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "순방문자(UV)", "metrics.unique-visitors": "순방문자(UV)",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "조회수", "metrics.views": "조회수",
"metrics.visitors": "방문객" "metrics.visitors": "방문객"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Referrers", "metrics.referrers": "Referrers",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unikalūs lankytojai", "metrics.unique-visitors": "Unikalūs lankytojai",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Peržiūros", "metrics.views": "Peržiūros",
"metrics.visitors": "Lankytojai" "metrics.visitors": "Lankytojai"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Чиглүүлэгч", "metrics.referrers": "Чиглүүлэгч",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Зочин", "metrics.unique-visitors": "Зочин",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Үзсэн", "metrics.views": "Үзсэн",
"metrics.visitors": "Зочин" "metrics.visitors": "Зочин"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Perujuk", "metrics.referrers": "Perujuk",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Pelawat unik", "metrics.unique-visitors": "Pelawat unik",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Lawatan", "metrics.views": "Lawatan",
"metrics.visitors": "Pelawat" "metrics.visitors": "Pelawat"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Referanser", "metrics.referrers": "Referanser",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unike besøkende", "metrics.unique-visitors": "Unike besøkende",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visninger", "metrics.views": "Visninger",
"metrics.visitors": "Besøkende" "metrics.visitors": "Besøkende"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Verwijzers", "metrics.referrers": "Verwijzers",
"metrics.screens": "Schermen", "metrics.screens": "Schermen",
"metrics.unique-visitors": "Unieke bezoekers", "metrics.unique-visitors": "Unieke bezoekers",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Weergaven", "metrics.views": "Weergaven",
"metrics.visitors": "Bezoekers" "metrics.visitors": "Bezoekers"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Źródła odsyłające", "metrics.referrers": "Źródła odsyłające",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unikalni odwiedzający", "metrics.unique-visitors": "Unikalni odwiedzający",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Wyświetlenia", "metrics.views": "Wyświetlenia",
"metrics.visitors": "Odwiedzający" "metrics.visitors": "Odwiedzający"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Referências", "metrics.referrers": "Referências",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Visitantes únicos", "metrics.unique-visitors": "Visitantes únicos",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visualizações", "metrics.views": "Visualizações",
"metrics.visitors": "Visitantes" "metrics.visitors": "Visitantes"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Referenciadores", "metrics.referrers": "Referenciadores",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Visitantes únicos", "metrics.unique-visitors": "Visitantes únicos",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visualizações", "metrics.views": "Visualizações",
"metrics.visitors": "Visitantes" "metrics.visitors": "Visitantes"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Site-uri de proveniență", "metrics.referrers": "Site-uri de proveniență",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Vizitatori unici", "metrics.unique-visitors": "Vizitatori unici",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Vizualizări", "metrics.views": "Vizualizări",
"metrics.visitors": "Vizitatori" "metrics.visitors": "Vizitatori"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Источники", "metrics.referrers": "Источники",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Уникальные посетители", "metrics.unique-visitors": "Уникальные посетители",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Просмотры", "metrics.views": "Просмотры",
"metrics.visitors": "Посетители" "metrics.visitors": "Посетители"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Odkazy", "metrics.referrers": "Odkazy",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Jedinečné návštevy", "metrics.unique-visitors": "Jedinečné návštevy",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Zobrazení", "metrics.views": "Zobrazení",
"metrics.visitors": "Návštevy" "metrics.visitors": "Návštevy"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Viri", "metrics.referrers": "Viri",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unikatni obiskovalci", "metrics.unique-visitors": "Unikatni obiskovalci",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Ogledi", "metrics.views": "Ogledi",
"metrics.visitors": "Obiskovalci" "metrics.visitors": "Obiskovalci"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Hänvisare", "metrics.referrers": "Hänvisare",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Unika besökare", "metrics.unique-visitors": "Unika besökare",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Visningar", "metrics.views": "Visningar",
"metrics.visitors": "Besökare" "metrics.visitors": "Besökare"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "குறிப்பிடுவோர்", "metrics.referrers": "குறிப்பிடுவோர்",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "தனிப்பட்ட பார்வையாளர்கள்", "metrics.unique-visitors": "தனிப்பட்ட பார்வையாளர்கள்",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "பார்வைகள்", "metrics.views": "பார்வைகள்",
"metrics.visitors": "பார்வையாளர்கள்" "metrics.visitors": "பார்வையாளர்கள்"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Yönlendirenler", "metrics.referrers": "Yönlendirenler",
"metrics.screens": "Ekranlar", "metrics.screens": "Ekranlar",
"metrics.unique-visitors": "Tekil kullanıcı", "metrics.unique-visitors": "Tekil kullanıcı",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Görüntüleme", "metrics.views": "Görüntüleme",
"metrics.visitors": "Ziyaretçi" "metrics.visitors": "Ziyaretçi"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Джерела", "metrics.referrers": "Джерела",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Унікальні відвідувачі", "metrics.unique-visitors": "Унікальні відвідувачі",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Перегляди", "metrics.views": "Перегляди",
"metrics.visitors": "Відвідувачі" "metrics.visitors": "Відвідувачі"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "بھیجنے والے", "metrics.referrers": "بھیجنے والے",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "منفرد زائرین", "metrics.unique-visitors": "منفرد زائرین",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "مناظر", "metrics.views": "مناظر",
"metrics.visitors": "زائرین" "metrics.visitors": "زائرین"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "Liên kết giới thiệu", "metrics.referrers": "Liên kết giới thiệu",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "Khách truy cập một lần", "metrics.unique-visitors": "Khách truy cập một lần",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "Xem", "metrics.views": "Xem",
"metrics.visitors": "Khách" "metrics.visitors": "Khách"
} }

View File

@ -37,7 +37,7 @@
"label.more": "更多", "label.more": "更多",
"label.name": "名字", "label.name": "名字",
"label.new-password": "新密码", "label.new-password": "新密码",
"label.none": "None", "label.none": "",
"label.owner": "所有者", "label.owner": "所有者",
"label.password": "密码", "label.password": "密码",
"label.passwords-dont-match": "密码不一致", "label.passwords-dont-match": "密码不一致",
@ -104,8 +104,14 @@
"metrics.page-views": "页面浏览量", "metrics.page-views": "页面浏览量",
"metrics.pages": "网页", "metrics.pages": "网页",
"metrics.referrers": "来源域名", "metrics.referrers": "来源域名",
"metrics.screens": "Screens", "metrics.screens": "屏幕尺寸",
"metrics.unique-visitors": "独立访客", "metrics.unique-visitors": "独立访客",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "浏览量", "metrics.views": "浏览量",
"metrics.visitors": "访客" "metrics.visitors": "访客"
} }

View File

@ -106,6 +106,12 @@
"metrics.referrers": "指入域名", "metrics.referrers": "指入域名",
"metrics.screens": "Screens", "metrics.screens": "Screens",
"metrics.unique-visitors": "獨立訪客", "metrics.unique-visitors": "獨立訪客",
"metrics.utm": "UTM",
"metrics.utm_campaign": "UTM Campaign",
"metrics.utm_content": "UTM Content",
"metrics.utm_medium": "UTM Medium",
"metrics.utm_source": "UTM Source",
"metrics.utm_term": "UTM Term",
"metrics.views": "頁面流量", "metrics.views": "頁面流量",
"metrics.visitors": "獨立訪客" "metrics.visitors": "獨立訪客"
} }

View File

@ -65,8 +65,10 @@ export const EVENT_COLORS = [
'#ffec16', '#ffec16',
]; ];
export const RELATIONAL = 'relational';
export const POSTGRESQL = 'postgresql'; export const POSTGRESQL = 'postgresql';
export const MYSQL = 'mysql'; export const MYSQL = 'mysql';
export const CLICKHOUSE = 'clickhouse';
export const MYSQL_DATE_FORMATS = { export const MYSQL_DATE_FORMATS = {
minute: '%Y-%m-%d %H:%i:00', minute: '%Y-%m-%d %H:%i:00',
@ -84,6 +86,16 @@ export const POSTGRESQL_DATE_FORMATS = {
year: 'YYYY-01-01', year: 'YYYY-01-01',
}; };
export const CLICKHOUSE_DATE_FORMATS = {
minute: '%Y-%m-%d %H:%M:00',
hour: '%Y-%m-%d %H:00:00',
day: '%Y-%m-%d',
month: '%Y-%m-01',
year: '%Y-01-01',
};
export const FILTER_IGNORED = Symbol.for('filter-ignored');
export const DOMAIN_REGEX = export const DOMAIN_REGEX =
/^(localhost(:[1-9]\d{0,4})?|((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63})$/; /^(localhost(:[1-9]\d{0,4})?|((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63})$/;

259
lib/db.js
View File

@ -1,5 +1,17 @@
import { PrismaClient } from '@prisma/client'; import { PrismaClient } from '@prisma/client';
import { ClickHouse } from 'clickhouse';
import chalk from 'chalk'; import chalk from 'chalk';
import {
MYSQL,
MYSQL_DATE_FORMATS,
POSTGRESQL,
POSTGRESQL_DATE_FORMATS,
CLICKHOUSE,
RELATIONAL,
FILTER_IGNORED,
} from 'lib/constants';
import moment from 'moment-timezone';
import { CLICKHOUSE_DATE_FORMATS } from './constants';
BigInt.prototype.toJSON = function () { BigInt.prototype.toJSON = function () {
return Number(this); return Number(this);
@ -18,7 +30,7 @@ function logQuery(e) {
console.log(chalk.yellow(e.params), '->', e.query, chalk.greenBright(`${e.duration}ms`)); console.log(chalk.yellow(e.params), '->', e.query, chalk.greenBright(`${e.duration}ms`));
} }
function getClient(options) { function getPrismaClient(options) {
const prisma = new PrismaClient(options); const prisma = new PrismaClient(options);
if (process.env.LOG_QUERY) { if (process.env.LOG_QUERY) {
@ -28,10 +40,251 @@ function getClient(options) {
return prisma; return prisma;
} }
const prisma = global.prisma || getClient(options); function getClickhouseClient() {
if (!process.env.ANALYTICS_URL) {
return null;
}
const url = new URL(process.env.ANALYTICS_URL);
const database = url.pathname.replace('/', '');
return new ClickHouse({
url: url.hostname,
port: Number(url.port),
basicAuth: url.password
? {
username: url.username || 'default',
password: url.password,
}
: null,
format: 'json',
config: {
database,
},
});
}
const prisma = global.prisma || getPrismaClient(options);
const clickhouse = global.clickhouse || getClickhouseClient();
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production') {
global.prisma = prisma; global.prisma = prisma;
global.clickhouse = clickhouse;
} }
export default prisma; export { prisma, clickhouse };
export function getDatabase() {
const type =
process.env.DATABASE_TYPE ||
(process.env.DATABASE_URL && process.env.DATABASE_URL.split(':')[0]);
if (type === 'postgres') {
return POSTGRESQL;
}
return type;
}
export function getAnalyticsDatabase() {
const type =
process.env.ANALYTICS_TYPE ||
(process.env.ANALYTICS_URL && process.env.ANALYTICS_URL.split(':')[0]);
if (type === 'postgres') {
return POSTGRESQL;
}
if (!type) {
return getDatabase();
}
return type;
}
export function getDateStringQueryClickhouse(data, unit) {
return `formatDateTime(${data}, '${CLICKHOUSE_DATE_FORMATS[unit]}')`;
}
export function getDateQuery(field, unit, timezone) {
const db = getDatabase();
if (db === POSTGRESQL) {
if (timezone) {
return `to_char(date_trunc('${unit}', ${field} at time zone '${timezone}'), '${POSTGRESQL_DATE_FORMATS[unit]}')`;
}
return `to_char(date_trunc('${unit}', ${field}), '${POSTGRESQL_DATE_FORMATS[unit]}')`;
}
if (db === MYSQL) {
if (timezone) {
const tz = moment.tz(timezone).format('Z');
return `date_format(convert_tz(${field},'+00:00','${tz}'), '${MYSQL_DATE_FORMATS[unit]}')`;
}
return `date_format(${field}, '${MYSQL_DATE_FORMATS[unit]}')`;
}
}
export function getDateQueryClickhouse(field, unit, timezone) {
if (timezone) {
return `date_trunc('${unit}', ${field},'${timezone}')`;
}
return `date_trunc('${unit}', ${field})`;
}
export function getDateFormatClickhouse(date) {
return `parseDateTimeBestEffort('${date.toUTCString()}')`;
}
export function getBetweenDatesClickhouse(field, start_at, end_at) {
return `${field} between ${getDateFormatClickhouse(start_at)}
and ${getDateFormatClickhouse(end_at)}`;
}
export function getTimestampInterval(field) {
const db = getDatabase();
if (db === POSTGRESQL) {
return `floor(extract(epoch from max(${field}) - min(${field})))`;
}
if (db === MYSQL) {
return `floor(unix_timestamp(max(${field})) - unix_timestamp(min(${field})))`;
}
}
export function getFilterQuery(table, column, filters = {}, params = []) {
const query = Object.keys(filters).reduce((arr, key) => {
const filter = filters[key];
if (filter === undefined || filter === FILTER_IGNORED) {
return arr;
}
switch (key) {
case 'url':
if (table === 'pageview' || table === 'event') {
arr.push(`and ${table}.${key}=$${params.length + 1}`);
params.push(decodeURIComponent(filter));
console.log(params);
}
break;
case 'os':
case 'browser':
case 'device':
case 'country':
if (table === 'session') {
arr.push(`and ${table}.${key}=$${params.length + 1}`);
params.push(decodeURIComponent(filter));
}
break;
case 'event_type':
if (table === 'event') {
arr.push(`and ${table}.${key}=$${params.length + 1}`);
params.push(decodeURIComponent(filter));
}
break;
case 'referrer':
if (table === 'pageview' || table === 'event') {
arr.push(`and ${table}.referrer like $${params.length + 1}`);
params.push(`%${decodeURIComponent(filter)}%`);
}
break;
case 'domain':
if (table === 'pageview') {
arr.push(`and ${table}.referrer not like $${params.length + 1}`);
arr.push(`and ${table}.referrer not like '/%'`);
params.push(`%://${filter}/%`);
}
break;
}
return arr;
}, []);
return query.join('\n');
}
export function parseFilters(table, column, filters = {}, params = [], sessionKey = 'session_id') {
const { domain, url, event_url, referrer, os, browser, device, country, event_type } = filters;
const pageviewFilters = { domain, url, referrer };
const sessionFilters = { os, browser, device, country };
const eventFilters = { url: event_url, event_type };
return {
pageviewFilters,
sessionFilters,
eventFilters,
event: { event_type },
joinSession:
os || browser || device || country
? `inner join session on ${table}.${sessionKey} = session.${sessionKey}`
: '',
pageviewQuery: getFilterQuery('pageview', column, pageviewFilters, params),
sessionQuery: getFilterQuery('session', column, sessionFilters, params),
eventQuery: getFilterQuery('event', column, eventFilters, params),
};
}
export function replaceQueryClickhouse(string, params = []) {
let formattedString = string;
params.forEach((a, i) => {
let replace = a;
if (typeof a === 'string' || a instanceof String) {
replace = `'${replace}'`;
}
formattedString = formattedString.replace(`$${i + 1}`, replace);
});
return formattedString;
}
export async function runQuery(query) {
return query.catch(e => {
throw e;
});
}
export async function rawQuery(query, params = []) {
const db = getDatabase();
if (db !== POSTGRESQL && db !== MYSQL) {
return Promise.reject(new Error('Unknown database.'));
}
const sql = db === MYSQL ? query.replace(/\$[0-9]+/g, '?') : query;
return runQuery(prisma.$queryRawUnsafe.apply(prisma, [sql, ...params]));
}
export async function rawQueryClickhouse(query, params = [], debug = false) {
let formattedQuery = replaceQueryClickhouse(query, params);
if (debug || process.env.LOG_QUERY) {
console.log(formattedQuery);
}
return clickhouse.query(formattedQuery).toPromise();
}
export async function runAnalyticsQuery(queries) {
const db = getAnalyticsDatabase();
if (db === POSTGRESQL || db === MYSQL) {
return queries[`${RELATIONAL}`]();
}
if (db === CLICKHOUSE) {
return queries[`${CLICKHOUSE}`]();
}
}

View File

@ -1,144 +0,0 @@
import { MYSQL, MYSQL_DATE_FORMATS, POSTGRESQL, POSTGRESQL_DATE_FORMATS } from 'lib/constants';
import prisma from 'lib/db';
import moment from 'moment-timezone';
export function getDatabase() {
const type =
process.env.DATABASE_TYPE ||
(process.env.DATABASE_URL && process.env.DATABASE_URL.split(':')[0]);
if (type === 'postgres') {
return 'postgresql';
}
return type;
}
export function getDateQuery(field, unit, timezone) {
const db = getDatabase();
if (db === POSTGRESQL) {
if (timezone) {
return `to_char(date_trunc('${unit}', ${field} at time zone '${timezone}'), '${POSTGRESQL_DATE_FORMATS[unit]}')`;
}
return `date_trunc('${unit}', ${field})`;
}
if (db === MYSQL) {
if (timezone) {
const tz = moment.tz(timezone).format('Z');
return `date_format(convert_tz(${field},'+00:00','${tz}'), '${MYSQL_DATE_FORMATS[unit]}')`;
}
return `${field}`;
}
}
export function getTimestampInterval(field) {
const db = getDatabase();
if (db === POSTGRESQL) {
return `floor(extract(epoch from max(${field}) - min(${field})))`;
}
if (db === MYSQL) {
return `floor(unix_timestamp(max(${field})) - unix_timestamp(min(${field})))`;
}
}
export function getFilterQuery(table, column, filters = {}, params = []) {
const query = Object.keys(filters).reduce((arr, key) => {
const value = filters[key];
if (!value || value === true) {
return arr;
}
switch (key) {
case 'url':
if (table === 'pageview' || table === 'event') {
arr.push(`and ${table}.${key}=$${params.length + 1}`);
params.push(decodeURIComponent(value));
}
break;
case 'os':
case 'browser':
case 'device':
case 'country':
if (table === 'session') {
arr.push(`and ${table}.${key}=$${params.length + 1}`);
params.push(decodeURIComponent(value));
}
break;
case 'event_type':
if (table === 'event') {
arr.push(`and ${table}.${key}=$${params.length + 1}`);
params.push(decodeURIComponent(value));
}
break;
case 'referrer':
if (table === 'pageview') {
arr.push(`and ${table}.referrer like $${params.length + 1} `);
arr.push(`and ${table}.referrer not like '/%'`);
params.push(`%${decodeURIComponent(value)}%`);
}
break;
case 'domain':
if (table === 'pageview') {
arr.push(`and ${table}.referrer not like $${params.length + 1}`);
arr.push(`and ${table}.referrer not like '/%'`);
params.push(`%://${value}/%`);
}
break;
}
return arr;
}, []);
return query.join('\n');
}
export function parseFilters(table, column, filters = {}, params = []) {
const { domain, url, event_url, referrer, os, browser, device, country, event_type } = filters;
const pageviewFilters = { domain, url, referrer };
const sessionFilters = { os, browser, device, country };
const eventFilters = { url: event_url, event_type };
return {
pageviewFilters,
sessionFilters,
eventFilters,
event: { event_type },
joinSession:
os || browser || device || country
? `inner join session on ${table}.session_id = session.session_id`
: '',
pageviewQuery: getFilterQuery('pageview', column, pageviewFilters, params),
sessionQuery: getFilterQuery('session', column, sessionFilters, params),
eventQuery: getFilterQuery('event', column, eventFilters, params),
};
}
export async function runQuery(query) {
return query.catch(e => {
throw e;
});
}
export async function rawQuery(query, params = []) {
const db = getDatabase();
if (db !== POSTGRESQL && db !== MYSQL) {
return Promise.reject(new Error('Unknown database.'));
}
const sql = db === MYSQL ? query.replace(/\$[0-9]+/g, '?') : query;
return runQuery(prisma.$queryRawUnsafe.apply(prisma, [sql, ...params]));
}

View File

@ -37,6 +37,8 @@ export async function getSession(req) {
let session = await getSessionByUuid(session_uuid); let session = await getSessionByUuid(session_uuid);
session = Array.isArray(session) && session[0] ? session[0] : null;
if (!session) { if (!session) {
try { try {
session = await createSession(website_id, { session = await createSession(website_id, {
@ -65,5 +67,6 @@ export async function getSession(req) {
return { return {
website_id, website_id,
session_id, session_id,
session_uuid,
}; };
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "umami", "name": "umami",
"version": "1.35.0", "version": "1.36.0",
"description": "A simple, fast, privacy-focused alternative to Google Analytics.", "description": "A simple, fast, privacy-focused alternative to Google Analytics.",
"author": "Mike Cao <mike@mikecao.com>", "author": "Mike Cao <mike@mikecao.com>",
"license": "MIT", "license": "MIT",
@ -60,6 +60,7 @@
"chalk": "^4.1.1", "chalk": "^4.1.1",
"chart.js": "^2.9.4", "chart.js": "^2.9.4",
"classnames": "^2.3.1", "classnames": "^2.3.1",
"clickhouse": "^2.5.0",
"colord": "^2.9.2", "colord": "^2.9.2",
"cors": "^2.8.5", "cors": "^2.8.5",
"cross-spawn": "^7.0.3", "cross-spawn": "^7.0.3",

View File

@ -60,7 +60,7 @@ export default async (req, res) => {
await useSession(req, res); await useSession(req, res);
const { const {
session: { website_id, session_id }, session: { website_id, session_id, session_uuid },
} = req; } = req;
const { type, payload } = getJsonBody(req); const { type, payload } = getJsonBody(req);
@ -72,9 +72,9 @@ export default async (req, res) => {
} }
if (type === 'pageview') { if (type === 'pageview') {
await savePageView(website_id, session_id, url, referrer); await savePageView(website_id, { session_id, session_uuid, url, referrer });
} else if (type === 'event') { } else if (type === 'event') {
await saveEvent(website_id, session_id, url, event_type, event_value); await saveEvent(website_id, { session_id, session_uuid, url, event_type, event_value });
} else { } else {
return badRequest(res); return badRequest(res);
} }

View File

@ -1,10 +1,12 @@
import { getPageviewMetrics, getSessionMetrics, getWebsiteById } from 'queries'; import { getPageviewMetrics, getSessionMetrics, getWebsiteById, getPageviewParams } from 'queries';
import { ok, methodNotAllowed, unauthorized, badRequest } from 'lib/response'; import { ok, methodNotAllowed, unauthorized, badRequest } from 'lib/response';
import { allowQuery } from 'lib/auth'; import { allowQuery } from 'lib/auth';
import { useCors } from 'lib/middleware'; import { useCors } from 'lib/middleware';
import { FILTER_IGNORED } from 'lib/constants';
const sessionColumns = ['browser', 'os', 'device', 'screen', 'country', 'language']; const sessionColumns = ['browser', 'os', 'device', 'screen', 'country', 'language'];
const pageviewColumns = ['url', 'referrer']; const pageviewColumns = ['url', 'referrer'];
const paramTypes = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term', 'ref'];
function getTable(type) { function getTable(type) {
if (type === 'event') { if (type === 'event') {
@ -39,6 +41,52 @@ export default async (req, res) => {
const startDate = new Date(+start_at); const startDate = new Date(+start_at);
const endDate = new Date(+end_at); const endDate = new Date(+end_at);
if (paramTypes.includes(type)) {
const column = 'url';
const table = getTable(type);
let domain;
if (type === 'referrer') {
const website = await getWebsiteById(websiteId);
if (!website) {
return badRequest(res);
}
domain = website.domain;
}
const filters = {
domain,
url: type !== 'url' && table !== 'event' ? url : undefined,
referrer: type !== 'referrer' ? referrer : true,
os: type !== 'os' ? os : undefined,
browser: type !== 'browser' ? browser : undefined,
device: type !== 'device' ? device : undefined,
country: type !== 'country' ? country : undefined,
event_url: type !== 'url' && table === 'event' ? url : undefined,
};
let data = await getPageviewParams(
type,
websiteId,
startDate,
endDate,
column,
table,
filters,
);
let terms = {};
new Set(data.map(i => i.param)).forEach(term => (terms[term] = null));
for (let { param } of data) terms[param] += 1;
return ok(
res,
Object.keys(terms).map(i => ({ x: i, y: terms[i] })),
);
}
if (sessionColumns.includes(type)) { if (sessionColumns.includes(type)) {
let data = await getSessionMetrics(websiteId, startDate, endDate, type, { let data = await getSessionMetrics(websiteId, startDate, endDate, type, {
os, os,
@ -83,7 +131,7 @@ export default async (req, res) => {
const filters = { const filters = {
domain, domain,
url: type !== 'url' && table !== 'event' ? url : undefined, url: type !== 'url' && table !== 'event' ? url : undefined,
referrer: type !== 'referrer' ? referrer : true, referrer: type !== 'referrer' && table !== 'event' ? referrer : FILTER_IGNORED,
os: type !== 'os' ? os : undefined, os: type !== 'os' ? os : undefined,
browser: type !== 'browser' ? browser : undefined, browser: type !== 'browser' ? browser : undefined,
device: type !== 'device' ? device : undefined, device: type !== 'device' ? device : undefined,

View File

@ -34,7 +34,7 @@ export default async (req, res) => {
device, device,
country, country,
}), }),
getPageviewStats(websiteId, startDate, endDate, tz, unit, 'distinct pageview.session_id', { getPageviewStats(websiteId, startDate, endDate, tz, unit, 'distinct pageview.', {
url, url,
os, os,
browser, browser,

View File

@ -785,6 +785,42 @@
"value": "زائرون فريدون" "value": "زائرون فريدون"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Visitants únics" "value": "Visitants únics"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Jedinečné návštěvy" "value": "Jedinečné návštěvy"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Unikke besøgende" "value": "Unikke besøgende"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Eindeutige Besucher" "value": "Eindeutige Besucher"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Μοναδικοί επισκέπτες" "value": "Μοναδικοί επισκέπτες"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Unique visitors" "value": "Unique visitors"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Unique visitors" "value": "Unique visitors"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Visitantes únicos" "value": "Visitantes únicos"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -769,6 +769,42 @@
"value": "بازدیدکننده‌های یکتا" "value": "بازدیدکننده‌های یکتا"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Yksittäiset kävijät" "value": "Yksittäiset kävijät"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Einsýna vitjanir" "value": "Einsýna vitjanir"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -781,6 +781,42 @@
"value": "Visiteurs uniques" "value": "Visiteurs uniques"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Visitas únicas" "value": "Visitas únicas"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -765,6 +765,42 @@
"value": "מבקרים ייחודיים" "value": "מבקרים ייחודיים"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -773,6 +773,42 @@
"value": "अद्वितीय आगंतुकों" "value": "अद्वितीय आगंतुकों"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Egyedi látogatók" "value": "Egyedi látogatók"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -753,6 +753,42 @@
"value": "Pengunjung unik" "value": "Pengunjung unik"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -789,6 +789,42 @@
"value": "Visitatori unici" "value": "Visitatori unici"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -757,6 +757,42 @@
"value": "ユニーク訪問者数" "value": "ユニーク訪問者数"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -757,6 +757,42 @@
"value": "순방문자(UV)" "value": "순방문자(UV)"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -910,6 +910,42 @@
"value": "Unikalūs lankytojai" "value": "Unikalūs lankytojai"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Зочин" "value": "Зочин"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -777,6 +777,42 @@
"value": "Pelawat unik" "value": "Pelawat unik"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -789,6 +789,42 @@
"value": "Unike besøkende" "value": "Unike besøkende"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Unieke bezoekers" "value": "Unieke bezoekers"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Unikalni odwiedzający" "value": "Unikalni odwiedzający"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -789,6 +789,42 @@
"value": "Visitantes únicos" "value": "Visitantes únicos"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -789,6 +789,42 @@
"value": "Visitantes únicos" "value": "Visitantes únicos"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Vizitatori unici" "value": "Vizitatori unici"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -757,6 +757,42 @@
"value": "Уникальные посетители" "value": "Уникальные посетители"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Jedinečné návštevy" "value": "Jedinečné návštevy"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "Unikatni obiskovalci" "value": "Unikatni obiskovalci"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -789,6 +789,42 @@
"value": "Unika besökare" "value": "Unika besökare"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -777,6 +777,42 @@
"value": "தனிப்பட்ட பார்வையாளர்கள்" "value": "தனிப்பட்ட பார்வையாளர்கள்"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -749,6 +749,42 @@
"value": "Tekil kullanıcı" "value": "Tekil kullanıcı"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -761,6 +761,42 @@
"value": "Унікальні відвідувачі" "value": "Унікальні відвідувачі"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -785,6 +785,42 @@
"value": "منفرد زائرین" "value": "منفرد زائرین"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -769,6 +769,42 @@
"value": "Khách truy cập một lần" "value": "Khách truy cập một lần"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -250,7 +250,7 @@
"label.none": [ "label.none": [
{ {
"type": 0, "type": 0,
"value": "None" "value": ""
} }
], ],
"label.owner": [ "label.owner": [
@ -764,7 +764,7 @@
"metrics.screens": [ "metrics.screens": [
{ {
"type": 0, "type": 0,
"value": "Screens" "value": "屏幕尺寸"
} }
], ],
"metrics.unique-visitors": [ "metrics.unique-visitors": [
@ -773,6 +773,42 @@
"value": "独立访客" "value": "独立访客"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -769,6 +769,42 @@
"value": "獨立訪客" "value": "獨立訪客"
} }
], ],
"metrics.utm": [
{
"type": 0,
"value": "UTM"
}
],
"metrics.utm_campaign": [
{
"type": 0,
"value": "UTM Campaign"
}
],
"metrics.utm_content": [
{
"type": 0,
"value": "UTM Content"
}
],
"metrics.utm_medium": [
{
"type": 0,
"value": "UTM Medium"
}
],
"metrics.utm_source": [
{
"type": 0,
"value": "UTM Source"
}
],
"metrics.utm_term": [
{
"type": 0,
"value": "UTM Term"
}
],
"metrics.views": [ "metrics.views": [
{ {
"type": 0, "type": 0,

View File

@ -1,5 +1,4 @@
import { runQuery } from 'lib/queries'; import { prisma, runQuery } from 'lib/db';
import prisma from 'lib/db';
export async function createAccount(data) { export async function createAccount(data) {
return runQuery( return runQuery(

View File

@ -1,5 +1,4 @@
import { runQuery } from 'lib/queries'; import { prisma, runQuery } from 'lib/db';
import prisma from 'lib/db';
export async function deleteAccount(user_id) { export async function deleteAccount(user_id) {
return runQuery( return runQuery(

View File

@ -1,5 +1,4 @@
import { runQuery } from 'lib/queries'; import { prisma, runQuery } from 'lib/db';
import prisma from 'lib/db';
export async function getAccountById(user_id) { export async function getAccountById(user_id) {
return runQuery( return runQuery(

View File

@ -1,5 +1,4 @@
import { runQuery } from 'lib/queries'; import { prisma, runQuery } from 'lib/db';
import prisma from 'lib/db';
export async function getAccountByUsername(username) { export async function getAccountByUsername(username) {
return runQuery( return runQuery(

View File

@ -1,5 +1,4 @@
import { runQuery } from 'lib/queries'; import { prisma, runQuery } from 'lib/db';
import prisma from 'lib/db';
export async function getAccounts() { export async function getAccounts() {
return runQuery( return runQuery(

View File

@ -1,5 +1,4 @@
import { runQuery } from 'lib/queries'; import { prisma, runQuery } from 'lib/db';
import prisma from 'lib/db';
export async function updateAccount(user_id, data) { export async function updateAccount(user_id, data) {
return runQuery( return runQuery(

View File

@ -1,5 +1,4 @@
import { runQuery } from 'lib/queries'; import { prisma, runQuery } from 'lib/db';
import prisma from 'lib/db';
export async function createWebsite(user_id, data) { export async function createWebsite(user_id, data) {
return runQuery( return runQuery(

Some files were not shown because too many files have changed in this diff Show More