Merge branch 'dev' into develop

This commit is contained in:
Mike Cao 2023-04-19 17:09:21 -07:00 committed by GitHub
commit 06d19e8594
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 498 additions and 370 deletions

View File

@ -12,6 +12,7 @@ RUN yarn install --frozen-lockfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY docker/middleware.js .
COPY . .
ARG DATABASE_TYPE

View File

@ -6,7 +6,7 @@ import Icons from 'components/icons';
import styles from './LanguageButton.module.css';
export default function LanguageButton() {
const { locale, saveLocale } = useLocale();
const { locale, saveLocale, dir } = useLocale();
const items = Object.keys(languages).map(key => ({ ...languages[key], value: key }));
function handleSelect(value) {
@ -20,7 +20,7 @@ export default function LanguageButton() {
<Icons.Globe />
</Icon>
</Button>
<Popup position="bottom" alignment="end">
<Popup position="bottom" alignment={dir === 'rtl' ? 'start' : 'end'}>
<div className={styles.menu}>
{items.map(({ value, label }) => {
return (

View File

@ -5,12 +5,14 @@ import useMessages from 'hooks/useMessages';
import useUser from 'hooks/useUser';
import useConfig from 'hooks/useConfig';
import styles from './ProfileButton.module.css';
import useLocale from 'hooks/useLocale';
export default function ProfileButton() {
const { formatMessage, labels } = useMessages();
const { user } = useUser();
const { cloudMode } = useConfig();
const router = useRouter();
const { dir } = useLocale();
const handleSelect = key => {
if (key === 'profile') {
@ -31,7 +33,7 @@ export default function ProfileButton() {
<Icons.ChevronDown />
</Icon>
</Button>
<Popup position="bottom" alignment="end">
<Popup position="bottom" alignment={dir === 'rtl' ? 'start' : 'end'}>
<Menu variant="popup" onSelect={handleSelect} className={styles.menu}>
<Item key="user" className={styles.item}>
<Text>{user.username}</Text>

View File

@ -1,5 +1,5 @@
import { useState, useRef, useEffect, useMemo, useCallback } from 'react';
import { StatusLight } from 'react-basics';
import { StatusLight, Loading } from 'react-basics';
import classNames from 'classnames';
import Chart from 'chart.js/auto';
import HoverTooltip from 'components/common/HoverTooltip';
@ -39,6 +39,26 @@ export default function BarChart({
return +label > 1000 ? formatLongNumber(label) : label;
};
const renderXLabel = useCallback(
(label, index, values) => {
const d = new Date(values[index].value);
switch (unit) {
case 'minute':
return dateFormat(d, 'H:mm', locale);
case 'hour':
return dateFormat(d, 'p', locale);
case 'day':
return dateFormat(d, 'MMM d', locale);
case 'month':
return dateFormat(d, 'MMM', locale);
default:
return label;
}
},
[locale, unit],
);
const renderTooltip = useCallback(
model => {
const { opacity, labelColors, dataPoints } = model.tooltip;
@ -115,6 +135,7 @@ export default function BarChart({
color: colors.text,
autoSkip: false,
maxRotation: 0,
callback: renderXLabel,
},
},
y: {
@ -135,7 +156,7 @@ export default function BarChart({
},
},
};
}, [animationDuration, renderTooltip, stacked, colors, unit]);
}, [animationDuration, renderTooltip, renderXLabel, stacked, colors, unit, locale]);
const createChart = () => {
Chart.defaults.font.family = 'Inter';
@ -158,7 +179,9 @@ export default function BarChart({
chart.current.options = getOptions();
chart.current.data.datasets = datasets;
if (datasets.length) {
chart.current.data.datasets = datasets;
}
chart.current.update();
@ -173,11 +196,12 @@ export default function BarChart({
updateChart();
}
}
}, [datasets, unit, theme, animationDuration, locale, loading]);
}, [datasets, unit, theme, animationDuration, locale]);
return (
<>
<div className={classNames(styles.chart, className)}>
{loading && <Loading position="page" icon="dots" />}
<canvas ref={canvas} />
</div>
<Legend chart={chart.current} />

View File

@ -1,3 +1,4 @@
import { useEffect } from 'react';
import { StatusLight } from 'react-basics';
import { colord } from 'colord';
import classNames from 'classnames';
@ -9,7 +10,7 @@ export default function Legend({ chart }) {
const { locale } = useLocale();
const forceUpdate = useForceUpdate();
function handleClick(index) {
const handleClick = index => {
const meta = chart.getDatasetMeta(index);
meta.hidden = meta.hidden === null ? !chart.data.datasets[index].hidden : null;
@ -17,7 +18,11 @@ export default function Legend({ chart }) {
chart.update();
forceUpdate();
}
};
useEffect(() => {
forceUpdate();
}, [locale]);
if (!chart?.legend?.legendItems.find(({ text }) => text)) {
return null;

View File

@ -13,6 +13,7 @@ import { DEFAULT_ANIMATION_DURATION } from 'lib/constants';
import Icons from 'components/icons';
import useMessages from 'hooks/useMessages';
import styles from './MetricsTable.module.css';
import useLocale from 'hooks/useLocale';
export default function MetricsTable({
websiteId,
@ -69,6 +70,7 @@ export default function MetricsTable({
}
return [];
}, [data, error, dataFilter, filterOptions]);
const { dir } = useLocale();
return (
<div className={classNames(styles.container, className)}>
@ -80,7 +82,7 @@ export default function MetricsTable({
<Link href={router.pathname} as={resolveUrl({ view: type })}>
<Button variant="quiet">
<Text>{formatMessage(labels.more)}</Text>
<Icon size="sm">
<Icon size="sm" rotate={dir === 'rtl' ? 180 : 0}>
<Icons.ArrowRight />
</Icon>
</Button>

View File

@ -4,6 +4,7 @@ import BarChart from './BarChart';
import { THEME_COLORS } from 'lib/constants';
import useTheme from 'hooks/useTheme';
import useMessages from 'hooks/useMessages';
import useLocale from 'hooks/useLocale';
export default function PageviewsChart({
websiteId,
@ -16,6 +17,7 @@ export default function PageviewsChart({
}) {
const { formatMessage, labels } = useMessages();
const [theme] = useTheme();
const { locale } = useLocale();
const colors = useMemo(() => {
const primaryColor = colord(THEME_COLORS[theme].primary);
@ -52,7 +54,7 @@ export default function PageviewsChart({
...colors.views,
},
];
}, [data]);
}, [data, locale, colors]);
return (
<BarChart

View File

@ -18,6 +18,7 @@ import Icons from 'components/icons';
import useSticky from 'hooks/useSticky';
import useMessages from 'hooks/useMessages';
import styles from './WebsiteChart.module.css';
import useLocale from 'hooks/useLocale';
export default function WebsiteChart({
websiteId,
@ -72,6 +73,7 @@ export default function WebsiteChart({
return { pageviews: [], sessions: [] };
}, [data, modified]);
const { dir } = useLocale();
return (
<>
<WebsiteHeader websiteId={websiteId} name={name} domain={domain}>
@ -80,7 +82,9 @@ export default function WebsiteChart({
<Button variant="primary">
<Text>{formatMessage(labels.viewDetails)}</Text>
<Icon>
<Icons.ArrowRight />
<Icon rotate={dir === 'rtl' ? 180 : 0}>
<Icons.ArrowRight />
</Icon>
</Icon>
</Button>
</Link>

View File

@ -9,14 +9,26 @@ export default function RealtimeHeader({ data = {} }) {
return (
<div className={styles.header}>
<div className={styles.metrics}>
<MetricCard label={formatMessage(labels.views)} value={pageviews?.length} hideComparison />
<MetricCard
className={styles.card}
label={formatMessage(labels.views)}
value={pageviews?.length}
hideComparison
/>
<MetricCard
className={styles.card}
label={formatMessage(labels.visitors)}
value={visitors?.length}
hideComparison
/>
<MetricCard label={formatMessage(labels.events)} value={events?.length} hideComparison />
<MetricCard
className={styles.card}
label={formatMessage(labels.events)}
value={events?.length}
hideComparison
/>
<MetricCard
className={styles.card}
label={formatMessage(labels.countries)}
value={countries?.length}
hideComparison

View File

@ -7,4 +7,15 @@
.metrics {
display: flex;
flex-wrap: wrap;
}
.card {
justify-self: flex-start;
}
@media only screen and (max-width: 992px) {
.card {
flex-basis: calc(50% - 20px);
}
}

View File

@ -37,7 +37,7 @@ export default function PasswordEditForm({ onSave, onClose }) {
name="newPassword"
rules={{
required: 'Required',
minLength: { value: 8, message: formatMessage(messages.minPasswordLength) },
minLength: { value: 8, message: formatMessage(messages.minPasswordLength, { n: 8 }) },
}}
>
<PasswordField autoComplete="new-password" />
@ -48,7 +48,7 @@ export default function PasswordEditForm({ onSave, onClose }) {
name="confirmPassword"
rules={{
required: formatMessage(labels.required),
minLength: { value: 8, message: formatMessage(messages.minPasswordLength) },
minLength: { value: 8, message: formatMessage(messages.minPasswordLength, { n: 8 }) },
validate: samePassword,
}}
>

View File

@ -49,7 +49,7 @@ export default function TeamSettings({ teamId }) {
title={
<Breadcrumbs>
<Item>
<Link href="/settings/teams">Teams</Link>
<Link href="/settings/teams">{formatMessage(labels.teams)}</Link>
</Item>
<Item>{values?.name}</Item>
</Breadcrumbs>

View File

@ -48,7 +48,7 @@ export default function UserEditForm({ userId, data, onSave }) {
<FormInput
name="newPassword"
rules={{
minLength: { value: 8, message: formatMessage(messages.minPasswordLength) },
minLength: { value: 8, message: formatMessage(messages.minPasswordLength, { n: 8 }) },
}}
>
<PasswordField autoComplete="new-password" />

View File

@ -6,10 +6,12 @@ import UserDeleteForm from './UserDeleteForm';
import { ROLES } from 'lib/constants';
import useMessages from 'hooks/useMessages';
import SettingsTable from 'components/common/SettingsTable';
import useLocale from 'hooks/useLocale';
export default function UsersTable({ data = [], onDelete }) {
const { formatMessage, labels } = useMessages();
const { user } = useUser();
const { dateLocale } = useLocale();
const columns = [
{ name: 'username', label: formatMessage(labels.username), style: { flex: 1.5 } },
@ -22,6 +24,7 @@ export default function UsersTable({ data = [], onDelete }) {
if (key === 'created') {
return formatDistance(new Date(row.createdAt), new Date(), {
addSuffix: true,
locale: dateLocale,
});
}
if (key === 'role') {

View File

@ -34,7 +34,7 @@ export default function WebsiteData({ websiteId, onSave }) {
description={formatMessage(messages.deleteWebsiteWarning)}
>
<ModalTrigger>
<Button variant="danger">Delete</Button>
<Button variant="danger">{formatMessage(labels.delete)}</Button>
<Modal title={formatMessage(labels.deleteWebsite)}>
{close => (
<WebsiteDeleteForm websiteId={websiteId} onSave={handleDelete} onClose={close} />

46
docker/middleware.js Normal file
View File

@ -0,0 +1,46 @@
import { NextResponse } from 'next/server';
export const config = {
matcher: '/:path*',
};
function customCollectEndpoint(req) {
const collectEndpoint = process.env.COLLECT_API_ENDPOINT;
if (collectEndpoint) {
const url = req.nextUrl.clone();
const { pathname } = url;
if (pathname.endsWith(collectEndpoint)) {
url.pathname = '/api/send';
return NextResponse.rewrite(url);
}
}
}
function customScriptName(req) {
const scriptName = process.env.TRACKER_SCRIPT_NAME;
if (scriptName) {
const url = req.nextUrl.clone();
const { pathname } = url;
if (pathname.endsWith(scriptName)) {
url.pathname = '/script.js';
return NextResponse.rewrite(url);
}
}
}
export default function middleware(req) {
const fns = [customCollectEndpoint, customScriptName];
for (const fn of fns) {
const res = fn(req);
if (res) {
return res;
}
}
return NextResponse.next();
}

View File

@ -1,145 +1,145 @@
{
"label.access-code": "Access code",
"label.actions": "اجراءات",
"label.activity-log": "Activity log",
"label.activity-log": "سجل الأحداث",
"label.add-website": "إضافة موقع",
"label.admin": "مدير عام؟",
"label.admin": "مدير",
"label.all": "الكل",
"label.all-time": "All time",
"label.analytics": "Analytics",
"label.all-time": "كل الوقت",
"label.analytics": "تحليلات",
"label.average-visit-time": "متوسط وقت الزيارة",
"label.back": "للخلف",
"label.bounce-rate": "معدل الارتداد",
"label.browsers": "المتصفحات",
"label.cancel": "إلغاء",
"label.change-password": "تغيير كلمة المرور",
"label.cities": "Cities",
"label.clear-all": "Clear all",
"label.confirm": "Confirm",
"label.cities": "المدن",
"label.clear-all": "مسح الكل",
"label.confirm": "تأكيد",
"label.confirm-password": "تأكيد كلمة المرور",
"label.continue": "Continue",
"label.continue": "متابعة",
"label.countries": "الدول",
"label.create-team": "Create team",
"label.create-user": "Create user",
"label.created": "Created",
"label.create-team": "انشاء مجموعة",
"label.create-user": "انشاء مستخدم",
"label.created": "تم الانشاء",
"label.current-password": "كلمة المرور الحالية",
"label.custom-range": "فترة مخصصة",
"label.dashboard": "الشاشة الرئيسية",
"label.data": "Data",
"label.data": "البيانات",
"label.date-range": "فترة مخصصة",
"label.default-date-range": "الفترة المخصصة الافتراضية",
"label.delete": "حذف",
"label.delete-team": "Delete team",
"label.delete-user": "Delete user",
"label.delete-team": "حذف مجموعة",
"label.delete-user": "جذف مستخدم",
"label.delete-website": "حذف الموقع",
"label.desktop": "كمبيوتر",
"label.details": "Details",
"label.details": "تفاصيل",
"label.devices": "الأجهزة",
"label.dismiss": "اخفاء",
"label.domain": "نطاق",
"label.domain": "النطاق",
"label.edit": "تعديل",
"label.edit-dashboard": "Edit dashboard",
"label.edit-dashboard": "تعديل لوحة التحكم",
"label.enable-share-url": "تفعيل مشاركة الرابط",
"label.events": "الأحداث",
"label.filter-combined": "مجمعة",
"label.filter-raw": "مفصلة",
"label.join": "Join",
"label.join-team": "Join team",
"label.language": "Language",
"label.languages": "Languages",
"label.join": "انضمام",
"label.join-team": "الانضمام للمجموعة",
"label.language": "اللغة",
"label.languages": "اللغات",
"label.laptop": "لابتوب",
"label.last-days": "اخر {x} يوم/ايام",
"label.last-hours": "اخر {x} ساعة/ساعات",
"label.leave": "Leave",
"label.leave-team": "Leave team",
"label.leave": "مغادرة",
"label.leave-team": "مغادرة المجموعة",
"label.logout": "تسجيل الخروج",
"label.members": "Members",
"label.members": "الأعضاء",
"label.mobile": "جوال",
"label.more": "المزيد",
"label.name": "الإسم",
"label.new-password": "كلمة مرور جديدة",
"label.none": "None",
"label.none": "لا شيء",
"label.operating-systems": "نظام التشغيل",
"label.owner": "Owner",
"label.owner": "المالك",
"label.page-views": "مشاهدات الصفحة",
"label.pages": "الصفحات",
"label.password": "كلمة المرور",
"label.powered-by": "مشغل بواسطة {name}",
"label.profile": "الملف الشخصي",
"label.queries": "Queries",
"label.query-parameters": "Query parameters",
"label.queries": "استعلامات",
"label.query-parameters": "متغيرات الرابط",
"label.realtime": "الوقت الفعلي",
"label.referrers": "التحويلات",
"label.refresh": "تحديث",
"label.regenerate": "Regenerate",
"label.regions": "Regions",
"label.remove": "Remove",
"label.regenerate": "اعادة انشاء",
"label.regions": "المناطق",
"label.remove": "إزالة",
"label.required": "اجباري",
"label.reset": "اعادة تعيين",
"label.reset-website": "اعادة تعيين الإحصائيات",
"label.role": "Role",
"label.role": "الصلاحية",
"label.save": "حفظ",
"label.screens": "Screens",
"label.select-website": "Select website",
"label.sessions": "Sessions",
"label.screens": "الشاشات",
"label.select-website": "اختيار موقع",
"label.sessions": "الزيارات",
"label.settings": "اعدادات",
"label.share-url": "مشاركة الرابط",
"label.single-day": "يوم واحد",
"label.tablet": "تابلت",
"label.team": "Team",
"label.team-guest": "Team guest",
"label.team-id": "Team ID",
"label.team-member": "Team member",
"label.team-owner": "Team owner",
"label.teams": "Teams",
"label.theme": "Theme",
"label.team": "مجموعة",
"label.team-guest": "زائر للمجموعة",
"label.team-id": "معرف المجموعة",
"label.team-member": "عضو المجموعة",
"label.team-owner": "مدير المجموعة",
"label.teams": "المجموعات",
"label.theme": "المظهر",
"label.this-month": "الشهر الحالي",
"label.this-week": "الاسبوع الحالي",
"label.this-year": "السنة الحالية",
"label.timezone": "المنطقة الزمنية",
"label.title": "Title",
"label.title": "العنوان",
"label.today": "اليوم",
"label.toggle-charts": "Toggle charts",
"label.toggle-charts": "تغيير الإحصائيات",
"label.tracking-code": "كود التتبع",
"label.unique-visitors": "زائرون فريدون",
"label.unknown": "غير معروف",
"label.user": "User",
"label.user": "مستخدم",
"label.username": "اسم المستخدم",
"label.users": "Users",
"label.view": "View",
"label.users": "المستخدمين",
"label.view": "عرض",
"label.view-details": "عرض التفاصيل",
"label.views": "مشاهدات",
"label.visitors": "زوار",
"label.website-id": "Website ID",
"label.website-id": "معرف الموقع",
"label.websites": "المواقع",
"label.yesterday": "Yesterday",
"label.yesterday": "الأمس",
"message.active-users": "{x} حاليا {x, plural, one {زائر واحد} other {زوار}}",
"message.confirm-delete": "هل أنت متأكد من حذف {target}?",
"message.confirm-leave": "Are you sure you want to leave {target}?",
"message.confirm-leave": "هل أنت متأكد من مغادرة {target}?",
"message.confirm-reset": "هل أنت متأكد من اعادة تعيين الإحصائيات لـ {target}؟",
"message.delete-website": "حذف الموقع",
"message.delete-website-warning": "كافة البيانات المرتبطة سيم حذفها ايضا.",
"message.error": "حدث خطأ ما.",
"message.event-log": "{event} on {url}",
"message.event-log": "{event} في {url}",
"message.go-to-settings": "الذهاب إلى الإعدادات",
"message.incorrect-username-password": "اسم المستخدم او كلمة المرور غير صحيحة.",
"message.invalid-domain": "النطاق غير صحيح",
"message.min-password-length": "Minimum length of {n} characters",
"message.min-password-length": "اقل عدد مسموح به {n} حرف/أحرف",
"message.no-data-available": "لا توجد بيانات متاحة.",
"message.no-match-password": "كلمة المرور غير متطابقة",
"message.no-teams": "You have not created any teams.",
"message.no-users": "There are no users.",
"message.no-teams": "لم تقم بإنشاء اي مجموعة.",
"message.no-users": "لا يوجد مستخدمين.",
"message.page-not-found": "الصفحة غير موجودة.",
"message.reset-website": "اعادة تعيين الإحصائيات",
"message.reset-website-warning": "سيتم اعادة تعيين كافة الإحصائيات لهذا الموقع، لكن لن يتم تعيير كود التتبع",
"message.saved": "تم الحفظ بنجاح.",
"message.share-url": "هذا الرابط الذي تم مشاركته بشكل عام لـ {target}.",
"message.team-already-member": "You are already a member of the team.",
"message.team-not-found": "Team not found.",
"message.team-already-member": "أنت عضو في المجموعة",
"message.team-not-found": "لم يتم العثور على المجموعة found.",
"message.tracking-code": "كود التتبع",
"message.user-deleted": "User deleted.",
"message.user-deleted": "تم حذف المستخدم.",
"message.visitor-log": "زائر من {country} يستخدم {browser} على {os} {device}",
"messages.no-team-websites": "This team does not have any websites.",
"messages.no-team-websites": "هذه المجموعة ليس لديه اي موقع.",
"messages.no-websites-configured": "لم تقم بإعداد اي موقع.",
"messages.team-websites-info": "Websites can be viewed by anyone on the team."
"messages.team-websites-info": "يمكن مشاهدة الموقع من اي عضو في المجموعة."
}

View File

@ -1,7 +1,7 @@
{
"label.access-code": "Access code",
"label.access-code": "Code d'accès",
"label.actions": "Actions",
"label.activity-log": "Activity log",
"label.activity-log": "Journal d'activité",
"label.add-website": "Ajouter un site",
"label.admin": "Administrateur",
"label.all": "Tout",
@ -13,27 +13,27 @@
"label.browsers": "Navigateurs",
"label.cancel": "Annuler",
"label.change-password": "Changer le mot de passe",
"label.cities": "Cities",
"label.clear-all": "Clear all",
"label.confirm": "Confirm",
"label.cities": "Villes",
"label.clear-all": "Réinitialiser",
"label.confirm": "Confirmer",
"label.confirm-password": "Confirmation du mot de passe",
"label.continue": "Continue",
"label.continue": "Continuer",
"label.countries": "Pays",
"label.create-team": "Create team",
"label.create-user": "Create user",
"label.created": "Created",
"label.create-team": "Créer une équipe",
"label.create-user": "Créer un utilisateur",
"label.created": "Créé",
"label.current-password": "Mot de passe actuel",
"label.custom-range": "Période personnalisée",
"label.dashboard": "Tableau de bord",
"label.data": "Data",
"label.data": "Données",
"label.date-range": "Période",
"label.default-date-range": "Période par défaut",
"label.delete": "Supprimer",
"label.delete-team": "Delete team",
"label.delete-user": "Delete user",
"label.delete-team": "Supprimer l'équipe",
"label.delete-user": "Supprimer l'utilisateur",
"label.delete-website": "Supprimer le site",
"label.desktop": "Ordinateur",
"label.details": "Details",
"label.details": "Détails",
"label.devices": "Appareils",
"label.dismiss": "Ignorer",
"label.domain": "Domaine",
@ -43,17 +43,17 @@
"label.events": "Événements",
"label.filter-combined": "Combiné",
"label.filter-raw": "Brut",
"label.join": "Join",
"label.join-team": "Join team",
"label.join": "Rejoindre",
"label.join-team": "Rejoindre une équipe",
"label.language": "Langue",
"label.languages": "Langues",
"label.laptop": "Portable",
"label.last-days": "{x} derniers jours",
"label.last-hours": "{x} dernières heures",
"label.leave": "Leave",
"label.leave-team": "Leave team",
"label.leave": "Quitter",
"label.leave-team": "Quitter l'équipe",
"label.logout": "Déconnexion",
"label.members": "Members",
"label.members": "Membres",
"label.mobile": "Téléphone",
"label.more": "Plus",
"label.name": "Nom",
@ -71,75 +71,75 @@
"label.realtime": "Temps réel",
"label.referrers": "Sources",
"label.refresh": "Rafraîchir",
"label.regenerate": "Regenerate",
"label.regions": "Regions",
"label.remove": "Remove",
"label.regenerate": "Régénérer",
"label.regions": "Régions",
"label.remove": "Retirer",
"label.required": "Requis",
"label.reset": "Réinitialiser",
"label.reset-website": "Réinitialiser les statistiques",
"label.role": "Role",
"label.save": "Sauvegarder",
"label.role": "Rôle",
"label.save": "Enregistrer",
"label.screens": "Résolutions d'écran",
"label.select-website": "Select website",
"label.select-website": "Choisir un site",
"label.sessions": "Sessions",
"label.settings": "Paramètres",
"label.share-url": "Partager l'URL",
"label.share-url": "URL de partage",
"label.single-day": "Journée",
"label.tablet": "Tablette",
"label.team": "Team",
"label.team-guest": "Team guest",
"label.team-id": "Team ID",
"label.team-member": "Team member",
"label.team-owner": "Team owner",
"label.teams": "Teams",
"label.team": "Équipe",
"label.team-guest": "Invité dans l'équipe",
"label.team-id": "ID d'équipe",
"label.team-member": "Membre de l'équipe",
"label.team-owner": "Propriétaire de l'équipe",
"label.teams": "Équipes",
"label.theme": "Thème",
"label.this-month": "Ce mois",
"label.this-week": "Cette semaine",
"label.this-year": "Cette année",
"label.timezone": "Fuseau horaire",
"label.title": "Title",
"label.title": "Titre",
"label.today": "Aujourd'hui",
"label.toggle-charts": "Afficher/Masquer les graphiques",
"label.tracking-code": "Code de suivi",
"label.unique-visitors": "Visiteurs uniques",
"label.unknown": "Inconnu",
"label.user": "User",
"label.user": "Utilisateur",
"label.username": "Nom d'utilisateur",
"label.users": "Users",
"label.view": "View",
"label.view-details": "Voir les details",
"label.users": "Utilisateurs",
"label.view": "Voir",
"label.view-details": "Voir les détails",
"label.views": "Vues",
"label.visitors": "Visiteurs",
"label.website-id": "Website ID",
"label.website-id": "ID de site",
"label.websites": "Sites",
"label.yesterday": "Hier",
"message.active-users": "{x} {x, plural, one {visiteur} other {visiteurs}} actuellement",
"message.confirm-delete": "Êtes-vous sûr de vouloir supprimer {target} ?",
"message.confirm-leave": "Are you sure you want to leave {target}?",
"message.confirm-leave": "Êtes-vous sûr de vouloir quitter {target} ?",
"message.confirm-reset": "Êtes-vous sûr de vouloir réinitialiser les statistiques de {target} ?",
"message.delete-website": "Supprimer le site",
"message.delete-website-warning": "Toutes les données associées seront également supprimées.",
"message.delete-website": "Pour supprimer ce site, taper {confirmation} ci-dessous pour confirmer.",
"message.delete-website-warning": "Toutes les données associées seront supprimées.",
"message.error": "Un problème est survenu.",
"message.event-log": "{event} on {url}",
"message.event-log": "{event} sur {url}",
"message.go-to-settings": "Aller aux paramètres",
"message.incorrect-username-password": "Nom d'utilisateur/Mot de passe incorrect.",
"message.invalid-domain": "Domaine invalide",
"message.min-password-length": "Minimum length of {n} characters",
"message.no-data-available": "Pas de données disponibles.",
"message.min-password-length": "Taille minimale de {n} caractères",
"message.no-data-available": "Aucune donnée disponible.",
"message.no-match-password": "Les mots de passe ne correspondent pas",
"message.no-teams": "You have not created any teams.",
"message.no-users": "There are no users.",
"message.no-teams": "Vous n'avez créé aucune équipe.",
"message.no-users": "Il n'y aucun utilisateur.",
"message.page-not-found": "Page non trouvée.",
"message.reset-website": "Réinitialiser les statistiques",
"message.reset-website-warning": "Toutes les statistiques pour ce site seront supprimées, mais votre code de suivi restera intact.",
"message.saved": "Enregistré avec succès.",
"message.share-url": "Ceci est l'URL partagée pour {target}.",
"message.team-already-member": "You are already a member of the team.",
"message.team-not-found": "Team not found.",
"message.share-url": "Les statistiques de votre site sont accessibles publiquement sur cette URL :",
"message.team-already-member": "Vous êtes déjà membre de cette équipe.",
"message.team-not-found": "Équipe non trouvée.",
"message.tracking-code": "Code de suivi",
"message.user-deleted": "User deleted.",
"message.user-deleted": "Utilisateur supprimé.",
"message.visitor-log": "Visiteur de {country} utilisant {browser} sur {os} {device}",
"messages.no-team-websites": "This team does not have any websites.",
"messages.no-team-websites": "Cette équipe n'a aucun site.",
"messages.no-websites-configured": "Vous n'avez configuré aucun site.",
"messages.team-websites-info": "Websites can be viewed by anyone on the team."
"messages.team-websites-info": "Les sites peuvent être vus par tout utilisateur dans l'équipe."
}

View File

@ -1,39 +1,39 @@
{
"label.access-code": "Access code",
"label.access-code": "访问代码",
"label.actions": "用户行为",
"label.activity-log": "Activity log",
"label.add-website": "添加网站",
"label.admin": "管理员",
"label.all": "所有",
"label.all-time": "所有时间段",
"label.analytics": "Analytics",
"label.analytics": "分析",
"label.average-visit-time": "平均访问时间",
"label.back": "返回",
"label.bounce-rate": "跳出率",
"label.browsers": "浏览器",
"label.cancel": "取消",
"label.change-password": "更新密码",
"label.cities": "Cities",
"label.clear-all": "Clear all",
"label.confirm": "Confirm",
"label.cities": "城市",
"label.clear-all": "清除全部",
"label.confirm": "确认",
"label.confirm-password": "确认密码",
"label.continue": "Continue",
"label.continue": "继续",
"label.countries": "国家/地区",
"label.create-team": "Create team",
"label.create-user": "Create user",
"label.created": "Created",
"label.create-team": "创建团队",
"label.create-user": "创建用户",
"label.created": "已创建",
"label.current-password": "目前密码",
"label.custom-range": "自定义时间段",
"label.dashboard": "仪表板",
"label.data": "Data",
"label.data": "统计数据",
"label.date-range": "时间段",
"label.default-date-range": "默认时间段",
"label.delete": "删除",
"label.delete-team": "Delete team",
"label.delete-user": "Delete user",
"label.delete-team": "删除团队",
"label.delete-user": "删除用户",
"label.delete-website": "删除网站",
"label.desktop": "桌面电脑",
"label.details": "Details",
"label.details": "详细信息",
"label.devices": "设备",
"label.dismiss": "关闭",
"label.domain": "域名",
@ -43,17 +43,17 @@
"label.events": "行为类别",
"label.filter-combined": "总和",
"label.filter-raw": "原始",
"label.join": "Join",
"label.join-team": "Join team",
"label.join": "加入",
"label.join-team": "加入团队",
"label.language": "语言",
"label.languages": "语言",
"label.laptop": "笔记本",
"label.last-days": "最近 {x} 天",
"label.last-hours": "最近 {x} 小时",
"label.leave": "Leave",
"label.leave-team": "Leave team",
"label.leave": "离开",
"label.leave-team": "离开团队",
"label.logout": "退出",
"label.members": "Members",
"label.members": "成员",
"label.mobile": "手机",
"label.more": "更多",
"label.name": "名字",
@ -66,56 +66,56 @@
"label.password": "密码",
"label.powered-by": "由 {name} 提供支持",
"label.profile": "个人资料",
"label.queries": "Queries",
"label.queries": "查询",
"label.query-parameters": "查询参数",
"label.realtime": "实时",
"label.referrers": "来源域名",
"label.refresh": "刷新",
"label.regenerate": "Regenerate",
"label.regions": "Regions",
"label.remove": "Remove",
"label.regenerate": "重新生成",
"label.regions": "地区",
"label.remove": "移除",
"label.required": "必填",
"label.reset": "重置",
"label.reset-website": "重置统计数据",
"label.role": "Role",
"label.role": "角色",
"label.save": "保存",
"label.screens": "屏幕尺寸",
"label.select-website": "Select website",
"label.sessions": "Sessions",
"label.select-website": "选择网站",
"label.sessions": "会话",
"label.settings": "设置",
"label.share-url": "共享链接",
"label.single-day": "单日",
"label.tablet": "平板",
"label.team": "Team",
"label.team-guest": "Team guest",
"label.team-id": "Team ID",
"label.team-member": "Team member",
"label.team-owner": "Team owner",
"label.teams": "Teams",
"label.team": "团队",
"label.team-guest": "团队访客",
"label.team-id": "团队 ID",
"label.team-member": "团队成员",
"label.team-owner": "团队所有者",
"label.teams": "团队",
"label.theme": "主题",
"label.this-month": "本月",
"label.this-week": "本周",
"label.this-year": "今年",
"label.timezone": "时区",
"label.title": "Title",
"label.title": "标题",
"label.today": "今天",
"label.toggle-charts": "切换图表",
"label.tracking-code": "跟踪代码",
"label.unique-visitors": "独立访客",
"label.unknown": "未知",
"label.user": "User",
"label.user": "用户",
"label.username": "用户名",
"label.users": "Users",
"label.view": "View",
"label.users": "用户",
"label.view": "查看",
"label.view-details": "查看更多",
"label.views": "浏览量",
"label.visitors": "访客",
"label.website-id": "Website ID",
"label.website-id": "网站 ID",
"label.websites": "网站",
"label.yesterday": "昨天",
"message.active-users": "当前在线 {x} 人",
"message.confirm-delete": "你确定要删除 {target} 吗?",
"message.confirm-leave": "Are you sure you want to leave {target}?",
"message.confirm-leave": "你确定要离开 {target} 吗?",
"message.confirm-reset": "您确定要重置 {target} 的数据吗?",
"message.delete-website": "删除网站",
"message.delete-website-warning": "所有相关数据将会被删除。",
@ -124,22 +124,22 @@
"message.go-to-settings": "去设置",
"message.incorrect-username-password": "用户名或密码不正确。",
"message.invalid-domain": "无效域名",
"message.min-password-length": "Minimum length of {n} characters",
"message.min-password-length": "密码最短长度为 {n} 个字符",
"message.no-data-available": "无可用数据。",
"message.no-match-password": "密码不一致",
"message.no-teams": "You have not created any teams.",
"message.no-users": "There are no users.",
"message.no-teams": "你还没有创建任何团队。",
"message.no-users": "没有任何用户。",
"message.page-not-found": "网页未找到。",
"message.reset-website": "重置统计数据",
"message.reset-website-warning": "本网站的所有统计数据将被删除,但您的跟踪代码将保持不变。",
"message.saved": "保存成功。",
"message.share-url": "这是 {target} 的共享链接。",
"message.team-already-member": "You are already a member of the team.",
"message.team-not-found": "Team not found.",
"message.team-already-member": "你已经是该团队的成员。",
"message.team-not-found": "未找到团队。",
"message.tracking-code": "跟踪代码",
"message.user-deleted": "User deleted.",
"message.user-deleted": "User detected.",
"message.visitor-log": "来自{country}的访客在搭载 {os} 的{device}上使用 {browser} 浏览器进行访问。",
"messages.no-team-websites": "This team does not have any websites.",
"messages.no-team-websites": "这个团队没有任何网站。",
"messages.no-websites-configured": "你还没有设置任何网站。",
"messages.team-websites-info": "Websites can be viewed by anyone on the team."
"messages.team-websites-info": "团队中的任何人都可查看网站。"
}

View File

@ -50,17 +50,20 @@ export const languages = {
'ca-ES': { label: 'Català', dateLocale: ca },
'cs-CZ': { label: 'Čeština', dateLocale: cs },
'da-DK': { label: 'Dansk', dateLocale: da },
'de-CH': { label: 'Schwiizerdütsch', dateLocale: de },
'de-DE': { label: 'Deutsch', dateLocale: de },
'el-GR': { label: 'Ελληνικά', dateLocale: el },
'en-US': { label: 'English (US)', dateLocale: enUS },
'en-GB': { label: 'English (UK)', dateLocale: enGB },
'en-US': { label: 'English (US)', dateLocale: enUS },
'es-MX': { label: 'Español', dateLocale: es },
'fa-IR': { label: 'فارسی', dateLocale: faIR, dir: 'rtl' },
'fi-FI': { label: 'Suomi', dateLocale: fi },
'fo-FO': { label: 'Føroyskt' },
'fr-FR': { label: 'Français', dateLocale: fr },
'ga-ES': { label: 'Galacian (Spain)', dateLocale: es },
'he-IL': { label: 'עברית', dateLocale: he },
'hi-IN': { label: 'हिन्दी', dateLocale: hi },
'hr-HR': { label: 'Hrvatski', dateLocale: hr },
'hu-HU': { label: 'Hungarian', dateLocale: hu },
'id-ID': { label: 'Bahasa Indonesia', dateLocale: id },
'it-IT': { label: 'Italiano', dateLocale: it },
@ -75,11 +78,11 @@ export const languages = {
'pl-PL': { label: 'Polski', dateLocale: pl },
'pt-BR': { label: 'Português do Brasil', dateLocale: ptBR },
'pt-PT': { label: 'Português', dateLocale: pt },
'ru-RU': { label: 'Русский', dateLocale: ru },
'ro-RO': { label: 'Română', dateLocale: ro },
'ru-RU': { label: 'Русский', dateLocale: ru },
'si-LK': { label: 'සිංහල', dateLocale: si },
'sk-SK': { label: 'Slovenčina', dateLocale: sk },
'sl-SI': { label: 'Slovenščina', dateLocale: sl },
'fi-FI': { label: 'Suomi', dateLocale: fi },
'sv-SE': { label: 'Svenska', dateLocale: sv },
'de-CH': { label: 'Schwiizerdütsch', dateLocale: de },
'ta-IN': { label: 'தமிழ்', dateLocale: ta },

View File

@ -44,6 +44,17 @@ if (process.env.COLLECT_API_ENDPOINT) {
});
}
if (process.env.TRACKER_SCRIPT_NAME) {
const match = process.env.TRACKER_SCRIPT_NAME?.match(/\/?(\w+)(\.js)?/);
if (match) {
rewrites.push({
source: `/${match[0]}.js`,
destination: '/script.js',
});
}
}
const redirects = [];
if (process.env.CLOUD_MODE) {

View File

@ -1,6 +1,6 @@
{
"name": "umami",
"version": "2.0.0",
"version": "2.0.1",
"description": "A simple, fast, privacy-focused alternative to Google Analytics.",
"author": "Mike Cao <mike@mikecao.com>",
"license": "MIT",
@ -59,7 +59,7 @@
],
"dependencies": {
"@fontsource/inter": "^4.5.15",
"@prisma/client": "4.11.0",
"@prisma/client": "4.13.0",
"@tanstack/react-query": "^4.16.1",
"@umami/prisma-client": "^0.2.0",
"@umami/redis-client": "^0.2.0",
@ -134,7 +134,7 @@
"postcss-preset-env": "7.8.3",
"postcss-rtlcss": "^4.0.1",
"prettier": "^2.6.2",
"prisma": "4.11.0",
"prisma": "4.13.0",
"prompts": "2.4.2",
"rollup": "^2.70.1",
"rollup-plugin-terser": "^7.0.2",

View File

@ -52,6 +52,7 @@ export default function App({ Component, pageProps }) {
<meta name="theme-color" content="#fafafa" media="(prefers-color-scheme: light)" />
<meta name="theme-color" content="#2f2f2f" media="(prefers-color-scheme: dark)" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex,nofollow" />
</Head>
<Component {...pageProps} />
{!pathname.includes('/share/') && <Script src={`${basePath}/telemetry.js`} />}

View File

@ -14,7 +14,7 @@
"label.activity-log": [
{
"type": 0,
"value": "Activity log"
"value": "سجل الأحداث"
}
],
"label.add-website": [
@ -26,7 +26,7 @@
"label.admin": [
{
"type": 0,
"value": "مدير عام؟"
"value": "مدير"
}
],
"label.all": [
@ -38,13 +38,13 @@
"label.all-time": [
{
"type": 0,
"value": "All time"
"value": "كل الوقت"
}
],
"label.analytics": [
{
"type": 0,
"value": "Analytics"
"value": "تحليلات"
}
],
"label.average-visit-time": [
@ -86,19 +86,19 @@
"label.cities": [
{
"type": 0,
"value": "Cities"
"value": "المدن"
}
],
"label.clear-all": [
{
"type": 0,
"value": "Clear all"
"value": "مسح الكل"
}
],
"label.confirm": [
{
"type": 0,
"value": "Confirm"
"value": "تأكيد"
}
],
"label.confirm-password": [
@ -110,7 +110,7 @@
"label.continue": [
{
"type": 0,
"value": "Continue"
"value": "متابعة"
}
],
"label.countries": [
@ -122,19 +122,19 @@
"label.create-team": [
{
"type": 0,
"value": "Create team"
"value": "انشاء مجموعة"
}
],
"label.create-user": [
{
"type": 0,
"value": "Create user"
"value": "انشاء مستخدم"
}
],
"label.created": [
{
"type": 0,
"value": "Created"
"value": "تم الانشاء"
}
],
"label.current-password": [
@ -158,7 +158,7 @@
"label.data": [
{
"type": 0,
"value": "Data"
"value": "البيانات"
}
],
"label.date-range": [
@ -182,13 +182,13 @@
"label.delete-team": [
{
"type": 0,
"value": "Delete team"
"value": "حذف مجموعة"
}
],
"label.delete-user": [
{
"type": 0,
"value": "Delete user"
"value": "جذف مستخدم"
}
],
"label.delete-website": [
@ -206,7 +206,7 @@
"label.details": [
{
"type": 0,
"value": "Details"
"value": "تفاصيل"
}
],
"label.devices": [
@ -224,7 +224,7 @@
"label.domain": [
{
"type": 0,
"value": "نطاق"
"value": "النطاق"
}
],
"label.edit": [
@ -236,7 +236,7 @@
"label.edit-dashboard": [
{
"type": 0,
"value": "Edit dashboard"
"value": "تعديل لوحة التحكم"
}
],
"label.enable-share-url": [
@ -266,25 +266,25 @@
"label.join": [
{
"type": 0,
"value": "Join"
"value": "انضمام"
}
],
"label.join-team": [
{
"type": 0,
"value": "Join team"
"value": "الانضمام للمجموعة"
}
],
"label.language": [
{
"type": 0,
"value": "Language"
"value": "اللغة"
}
],
"label.languages": [
{
"type": 0,
"value": "Languages"
"value": "اللغات"
}
],
"label.laptop": [
@ -324,13 +324,13 @@
"label.leave": [
{
"type": 0,
"value": "Leave"
"value": "مغادرة"
}
],
"label.leave-team": [
{
"type": 0,
"value": "Leave team"
"value": "مغادرة المجموعة"
}
],
"label.logout": [
@ -342,7 +342,7 @@
"label.members": [
{
"type": 0,
"value": "Members"
"value": "الأعضاء"
}
],
"label.mobile": [
@ -372,7 +372,7 @@
"label.none": [
{
"type": 0,
"value": "None"
"value": "لا شيء"
}
],
"label.operating-systems": [
@ -384,7 +384,7 @@
"label.owner": [
{
"type": 0,
"value": "Owner"
"value": "المالك"
}
],
"label.page-views": [
@ -424,13 +424,13 @@
"label.queries": [
{
"type": 0,
"value": "Queries"
"value": "استعلامات"
}
],
"label.query-parameters": [
{
"type": 0,
"value": "Query parameters"
"value": "متغيرات الرابط"
}
],
"label.realtime": [
@ -454,19 +454,19 @@
"label.regenerate": [
{
"type": 0,
"value": "Regenerate"
"value": "اعادة انشاء"
}
],
"label.regions": [
{
"type": 0,
"value": "Regions"
"value": "المناطق"
}
],
"label.remove": [
{
"type": 0,
"value": "Remove"
"value": "إزالة"
}
],
"label.required": [
@ -490,7 +490,7 @@
"label.role": [
{
"type": 0,
"value": "Role"
"value": "الصلاحية"
}
],
"label.save": [
@ -502,19 +502,19 @@
"label.screens": [
{
"type": 0,
"value": "Screens"
"value": "الشاشات"
}
],
"label.select-website": [
{
"type": 0,
"value": "Select website"
"value": "اختيار موقع"
}
],
"label.sessions": [
{
"type": 0,
"value": "Sessions"
"value": "الزيارات"
}
],
"label.settings": [
@ -544,43 +544,43 @@
"label.team": [
{
"type": 0,
"value": "Team"
"value": "مجموعة"
}
],
"label.team-guest": [
{
"type": 0,
"value": "Team guest"
"value": "زائر للمجموعة"
}
],
"label.team-id": [
{
"type": 0,
"value": "Team ID"
"value": "معرف المجموعة"
}
],
"label.team-member": [
{
"type": 0,
"value": "Team member"
"value": "عضو المجموعة"
}
],
"label.team-owner": [
{
"type": 0,
"value": "Team owner"
"value": "مدير المجموعة"
}
],
"label.teams": [
{
"type": 0,
"value": "Teams"
"value": "المجموعات"
}
],
"label.theme": [
{
"type": 0,
"value": "Theme"
"value": "المظهر"
}
],
"label.this-month": [
@ -610,7 +610,7 @@
"label.title": [
{
"type": 0,
"value": "Title"
"value": "العنوان"
}
],
"label.today": [
@ -622,7 +622,7 @@
"label.toggle-charts": [
{
"type": 0,
"value": "Toggle charts"
"value": "تغيير الإحصائيات"
}
],
"label.tracking-code": [
@ -646,7 +646,7 @@
"label.user": [
{
"type": 0,
"value": "User"
"value": "مستخدم"
}
],
"label.username": [
@ -658,13 +658,13 @@
"label.users": [
{
"type": 0,
"value": "Users"
"value": "المستخدمين"
}
],
"label.view": [
{
"type": 0,
"value": "View"
"value": "عرض"
}
],
"label.view-details": [
@ -688,7 +688,7 @@
"label.website-id": [
{
"type": 0,
"value": "Website ID"
"value": "معرف الموقع"
}
],
"label.websites": [
@ -700,7 +700,7 @@
"label.yesterday": [
{
"type": 0,
"value": "Yesterday"
"value": "الأمس"
}
],
"message.active-users": [
@ -754,7 +754,7 @@
"message.confirm-leave": [
{
"type": 0,
"value": "Are you sure you want to leave "
"value": "هل أنت متأكد من مغادرة "
},
{
"type": 1,
@ -804,7 +804,7 @@
},
{
"type": 0,
"value": " on "
"value": " في "
},
{
"type": 1,
@ -832,7 +832,7 @@
"message.min-password-length": [
{
"type": 0,
"value": "Minimum length of "
"value": "اقل عدد مسموح به "
},
{
"type": 1,
@ -840,7 +840,7 @@
},
{
"type": 0,
"value": " characters"
"value": " حرف/أحرف"
}
],
"message.no-data-available": [
@ -858,13 +858,13 @@
"message.no-teams": [
{
"type": 0,
"value": "You have not created any teams."
"value": "لم تقم بإنشاء اي مجموعة."
}
],
"message.no-users": [
{
"type": 0,
"value": "There are no users."
"value": "لا يوجد مستخدمين."
}
],
"message.page-not-found": [
@ -908,13 +908,13 @@
"message.team-already-member": [
{
"type": 0,
"value": "You are already a member of the team."
"value": "أنت عضو في المجموعة"
}
],
"message.team-not-found": [
{
"type": 0,
"value": "Team not found."
"value": "لم يتم العثور على المجموعة found."
}
],
"message.tracking-code": [
@ -926,7 +926,7 @@
"message.user-deleted": [
{
"type": 0,
"value": "User deleted."
"value": "تم حذف المستخدم."
}
],
"message.visitor-log": [
@ -966,7 +966,7 @@
"messages.no-team-websites": [
{
"type": 0,
"value": "This team does not have any websites."
"value": "هذه المجموعة ليس لديه اي موقع."
}
],
"messages.no-websites-configured": [
@ -978,7 +978,7 @@
"messages.team-websites-info": [
{
"type": 0,
"value": "Websites can be viewed by anyone on the team."
"value": "يمكن مشاهدة الموقع من اي عضو في المجموعة."
}
]
}

View File

@ -2,7 +2,7 @@
"label.access-code": [
{
"type": 0,
"value": "Access code"
"value": "Code d'accès"
}
],
"label.actions": [
@ -14,7 +14,7 @@
"label.activity-log": [
{
"type": 0,
"value": "Activity log"
"value": "Journal d'activité"
}
],
"label.add-website": [
@ -86,19 +86,19 @@
"label.cities": [
{
"type": 0,
"value": "Cities"
"value": "Villes"
}
],
"label.clear-all": [
{
"type": 0,
"value": "Clear all"
"value": "Réinitialiser"
}
],
"label.confirm": [
{
"type": 0,
"value": "Confirm"
"value": "Confirmer"
}
],
"label.confirm-password": [
@ -110,7 +110,7 @@
"label.continue": [
{
"type": 0,
"value": "Continue"
"value": "Continuer"
}
],
"label.countries": [
@ -122,19 +122,19 @@
"label.create-team": [
{
"type": 0,
"value": "Create team"
"value": "Créer une équipe"
}
],
"label.create-user": [
{
"type": 0,
"value": "Create user"
"value": "Créer un utilisateur"
}
],
"label.created": [
{
"type": 0,
"value": "Created"
"value": "Créé"
}
],
"label.current-password": [
@ -158,7 +158,7 @@
"label.data": [
{
"type": 0,
"value": "Data"
"value": "Données"
}
],
"label.date-range": [
@ -182,13 +182,13 @@
"label.delete-team": [
{
"type": 0,
"value": "Delete team"
"value": "Supprimer l'équipe"
}
],
"label.delete-user": [
{
"type": 0,
"value": "Delete user"
"value": "Supprimer l'utilisateur"
}
],
"label.delete-website": [
@ -206,7 +206,7 @@
"label.details": [
{
"type": 0,
"value": "Details"
"value": "Détails"
}
],
"label.devices": [
@ -266,13 +266,13 @@
"label.join": [
{
"type": 0,
"value": "Join"
"value": "Rejoindre"
}
],
"label.join-team": [
{
"type": 0,
"value": "Join team"
"value": "Rejoindre une équipe"
}
],
"label.language": [
@ -316,13 +316,13 @@
"label.leave": [
{
"type": 0,
"value": "Leave"
"value": "Quitter"
}
],
"label.leave-team": [
{
"type": 0,
"value": "Leave team"
"value": "Quitter l'équipe"
}
],
"label.logout": [
@ -334,7 +334,7 @@
"label.members": [
{
"type": 0,
"value": "Members"
"value": "Membres"
}
],
"label.mobile": [
@ -446,19 +446,19 @@
"label.regenerate": [
{
"type": 0,
"value": "Regenerate"
"value": "Régénérer"
}
],
"label.regions": [
{
"type": 0,
"value": "Regions"
"value": "Régions"
}
],
"label.remove": [
{
"type": 0,
"value": "Remove"
"value": "Retirer"
}
],
"label.required": [
@ -482,13 +482,13 @@
"label.role": [
{
"type": 0,
"value": "Role"
"value": "Rôle"
}
],
"label.save": [
{
"type": 0,
"value": "Sauvegarder"
"value": "Enregistrer"
}
],
"label.screens": [
@ -500,7 +500,7 @@
"label.select-website": [
{
"type": 0,
"value": "Select website"
"value": "Choisir un site"
}
],
"label.sessions": [
@ -518,7 +518,7 @@
"label.share-url": [
{
"type": 0,
"value": "Partager l'URL"
"value": "URL de partage"
}
],
"label.single-day": [
@ -536,37 +536,37 @@
"label.team": [
{
"type": 0,
"value": "Team"
"value": "Équipe"
}
],
"label.team-guest": [
{
"type": 0,
"value": "Team guest"
"value": "Invité dans l'équipe"
}
],
"label.team-id": [
{
"type": 0,
"value": "Team ID"
"value": "ID d'équipe"
}
],
"label.team-member": [
{
"type": 0,
"value": "Team member"
"value": "Membre de l'équipe"
}
],
"label.team-owner": [
{
"type": 0,
"value": "Team owner"
"value": "Propriétaire de l'équipe"
}
],
"label.teams": [
{
"type": 0,
"value": "Teams"
"value": "Équipes"
}
],
"label.theme": [
@ -602,7 +602,7 @@
"label.title": [
{
"type": 0,
"value": "Title"
"value": "Titre"
}
],
"label.today": [
@ -638,7 +638,7 @@
"label.user": [
{
"type": 0,
"value": "User"
"value": "Utilisateur"
}
],
"label.username": [
@ -650,19 +650,19 @@
"label.users": [
{
"type": 0,
"value": "Users"
"value": "Utilisateurs"
}
],
"label.view": [
{
"type": 0,
"value": "View"
"value": "Voir"
}
],
"label.view-details": [
{
"type": 0,
"value": "Voir les details"
"value": "Voir les détails"
}
],
"label.views": [
@ -680,7 +680,7 @@
"label.website-id": [
{
"type": 0,
"value": "Website ID"
"value": "ID de site"
}
],
"label.websites": [
@ -750,7 +750,7 @@
"message.confirm-leave": [
{
"type": 0,
"value": "Are you sure you want to leave "
"value": "Êtes-vous sûr de vouloir quitter "
},
{
"type": 1,
@ -758,7 +758,7 @@
},
{
"type": 0,
"value": "?"
"value": " ?"
}
],
"message.confirm-reset": [
@ -778,13 +778,21 @@
"message.delete-website": [
{
"type": 0,
"value": "Supprimer le site"
"value": "Pour supprimer ce site, taper "
},
{
"type": 1,
"value": "confirmation"
},
{
"type": 0,
"value": " ci-dessous pour confirmer."
}
],
"message.delete-website-warning": [
{
"type": 0,
"value": "Toutes les données associées seront également supprimées."
"value": "Toutes les données associées seront supprimées."
}
],
"message.error": [
@ -800,7 +808,7 @@
},
{
"type": 0,
"value": " on "
"value": " sur "
},
{
"type": 1,
@ -828,7 +836,7 @@
"message.min-password-length": [
{
"type": 0,
"value": "Minimum length of "
"value": "Taille minimale de "
},
{
"type": 1,
@ -836,13 +844,13 @@
},
{
"type": 0,
"value": " characters"
"value": " caractères"
}
],
"message.no-data-available": [
{
"type": 0,
"value": "Pas de données disponibles."
"value": "Aucune donnée disponible."
}
],
"message.no-match-password": [
@ -854,13 +862,13 @@
"message.no-teams": [
{
"type": 0,
"value": "You have not created any teams."
"value": "Vous n'avez créé aucune équipe."
}
],
"message.no-users": [
{
"type": 0,
"value": "There are no users."
"value": "Il n'y aucun utilisateur."
}
],
"message.page-not-found": [
@ -890,27 +898,19 @@
"message.share-url": [
{
"type": 0,
"value": "Ceci est l'URL partagée pour "
},
{
"type": 1,
"value": "target"
},
{
"type": 0,
"value": "."
"value": "Les statistiques de votre site sont accessibles publiquement sur cette URL :"
}
],
"message.team-already-member": [
{
"type": 0,
"value": "You are already a member of the team."
"value": "Vous êtes déjà membre de cette équipe."
}
],
"message.team-not-found": [
{
"type": 0,
"value": "Team not found."
"value": "Équipe non trouvée."
}
],
"message.tracking-code": [
@ -922,7 +922,7 @@
"message.user-deleted": [
{
"type": 0,
"value": "User deleted."
"value": "Utilisateur supprimé."
}
],
"message.visitor-log": [
@ -962,7 +962,7 @@
"messages.no-team-websites": [
{
"type": 0,
"value": "This team does not have any websites."
"value": "Cette équipe n'a aucun site."
}
],
"messages.no-websites-configured": [
@ -974,7 +974,7 @@
"messages.team-websites-info": [
{
"type": 0,
"value": "Websites can be viewed by anyone on the team."
"value": "Les sites peuvent être vus par tout utilisateur dans l'équipe."
}
]
}

View File

@ -2,7 +2,7 @@
"label.access-code": [
{
"type": 0,
"value": "Access code"
"value": "访问代码"
}
],
"label.actions": [
@ -44,7 +44,7 @@
"label.analytics": [
{
"type": 0,
"value": "Analytics"
"value": "分析"
}
],
"label.average-visit-time": [
@ -86,19 +86,19 @@
"label.cities": [
{
"type": 0,
"value": "Cities"
"value": "城市"
}
],
"label.clear-all": [
{
"type": 0,
"value": "Clear all"
"value": "清除全部"
}
],
"label.confirm": [
{
"type": 0,
"value": "Confirm"
"value": "确认"
}
],
"label.confirm-password": [
@ -110,7 +110,7 @@
"label.continue": [
{
"type": 0,
"value": "Continue"
"value": "继续"
}
],
"label.countries": [
@ -122,19 +122,19 @@
"label.create-team": [
{
"type": 0,
"value": "Create team"
"value": "创建团队"
}
],
"label.create-user": [
{
"type": 0,
"value": "Create user"
"value": "创建用户"
}
],
"label.created": [
{
"type": 0,
"value": "Created"
"value": "已创建"
}
],
"label.current-password": [
@ -158,7 +158,7 @@
"label.data": [
{
"type": 0,
"value": "Data"
"value": "统计数据"
}
],
"label.date-range": [
@ -182,13 +182,13 @@
"label.delete-team": [
{
"type": 0,
"value": "Delete team"
"value": "删除团队"
}
],
"label.delete-user": [
{
"type": 0,
"value": "Delete user"
"value": "删除用户"
}
],
"label.delete-website": [
@ -206,7 +206,7 @@
"label.details": [
{
"type": 0,
"value": "Details"
"value": "详细信息"
}
],
"label.devices": [
@ -266,13 +266,13 @@
"label.join": [
{
"type": 0,
"value": "Join"
"value": "加入"
}
],
"label.join-team": [
{
"type": 0,
"value": "Join team"
"value": "加入团队"
}
],
"label.language": [
@ -324,13 +324,13 @@
"label.leave": [
{
"type": 0,
"value": "Leave"
"value": "离开"
}
],
"label.leave-team": [
{
"type": 0,
"value": "Leave team"
"value": "离开团队"
}
],
"label.logout": [
@ -342,7 +342,7 @@
"label.members": [
{
"type": 0,
"value": "Members"
"value": "成员"
}
],
"label.mobile": [
@ -428,7 +428,7 @@
"label.queries": [
{
"type": 0,
"value": "Queries"
"value": "查询"
}
],
"label.query-parameters": [
@ -458,19 +458,19 @@
"label.regenerate": [
{
"type": 0,
"value": "Regenerate"
"value": "重新生成"
}
],
"label.regions": [
{
"type": 0,
"value": "Regions"
"value": "地区"
}
],
"label.remove": [
{
"type": 0,
"value": "Remove"
"value": "移除"
}
],
"label.required": [
@ -494,7 +494,7 @@
"label.role": [
{
"type": 0,
"value": "Role"
"value": "角色"
}
],
"label.save": [
@ -512,13 +512,13 @@
"label.select-website": [
{
"type": 0,
"value": "Select website"
"value": "选择网站"
}
],
"label.sessions": [
{
"type": 0,
"value": "Sessions"
"value": "会话"
}
],
"label.settings": [
@ -548,37 +548,37 @@
"label.team": [
{
"type": 0,
"value": "Team"
"value": "团队"
}
],
"label.team-guest": [
{
"type": 0,
"value": "Team guest"
"value": "团队访客"
}
],
"label.team-id": [
{
"type": 0,
"value": "Team ID"
"value": "团队 ID"
}
],
"label.team-member": [
{
"type": 0,
"value": "Team member"
"value": "团队成员"
}
],
"label.team-owner": [
{
"type": 0,
"value": "Team owner"
"value": "团队所有者"
}
],
"label.teams": [
{
"type": 0,
"value": "Teams"
"value": "团队"
}
],
"label.theme": [
@ -614,7 +614,7 @@
"label.title": [
{
"type": 0,
"value": "Title"
"value": "标题"
}
],
"label.today": [
@ -650,7 +650,7 @@
"label.user": [
{
"type": 0,
"value": "User"
"value": "用户"
}
],
"label.username": [
@ -662,13 +662,13 @@
"label.users": [
{
"type": 0,
"value": "Users"
"value": "用户"
}
],
"label.view": [
{
"type": 0,
"value": "View"
"value": "查看"
}
],
"label.view-details": [
@ -692,7 +692,7 @@
"label.website-id": [
{
"type": 0,
"value": "Website ID"
"value": "网站 ID"
}
],
"label.websites": [
@ -738,7 +738,7 @@
"message.confirm-leave": [
{
"type": 0,
"value": "Are you sure you want to leave "
"value": "你确定要离开 "
},
{
"type": 1,
@ -746,7 +746,7 @@
},
{
"type": 0,
"value": "?"
"value": " 吗?"
}
],
"message.confirm-reset": [
@ -816,7 +816,7 @@
"message.min-password-length": [
{
"type": 0,
"value": "Minimum length of "
"value": "密码最短长度为 "
},
{
"type": 1,
@ -824,7 +824,7 @@
},
{
"type": 0,
"value": " characters"
"value": " 个字符"
}
],
"message.no-data-available": [
@ -842,13 +842,13 @@
"message.no-teams": [
{
"type": 0,
"value": "You have not created any teams."
"value": "你还没有创建任何团队。"
}
],
"message.no-users": [
{
"type": 0,
"value": "There are no users."
"value": "没有任何用户。"
}
],
"message.page-not-found": [
@ -892,13 +892,13 @@
"message.team-already-member": [
{
"type": 0,
"value": "You are already a member of the team."
"value": "你已经是该团队的成员。"
}
],
"message.team-not-found": [
{
"type": 0,
"value": "Team not found."
"value": "未找到团队。"
}
],
"message.tracking-code": [
@ -910,7 +910,7 @@
"message.user-deleted": [
{
"type": 0,
"value": "User deleted."
"value": "User detected."
}
],
"message.visitor-log": [
@ -954,7 +954,7 @@
"messages.no-team-websites": [
{
"type": 0,
"value": "This team does not have any websites."
"value": "这个团队没有任何网站。"
}
],
"messages.no-websites-configured": [
@ -966,7 +966,7 @@
"messages.team-websites-info": [
{
"type": 0,
"value": "Websites can be viewed by anyone on the team."
"value": "团队中的任何人都可查看网站。"
}
]
}

View File

@ -41,7 +41,8 @@ async function relationalQuery(
join website
on website_event.website_id = website.website_id
${joinSession}
where website.website_id = $1${toUuid()}
where event_type = ${EVENT_TYPE.pageView}
and website.website_id = $1${toUuid()}
and website_event.created_at >= $2
and website_event.created_at between $3 and $4
${filterQuery}

View File

@ -50,10 +50,10 @@ async function checkConnection() {
}
async function checkDatabaseVersion(databaseType) {
const query = await prisma.$queryRaw`select version() version`;
const query = await prisma.$queryRaw`select version() as version`;
const version = semver.valid(semver.coerce(query[0].version));
const minVersion = databaseType === 'postgresql' ? '9.4.0' : '5.6.0';
const minVersion = databaseType === 'postgresql' ? '9.4.0' : '5.7.0';
if (semver.lt(version, minVersion)) {
throw new Error(

View File

@ -6,7 +6,7 @@ const path = require('path');
const endPoint = process.env.COLLECT_API_ENDPOINT;
if (endPoint) {
const file = path.resolve(__dirname, '../public/umami.js');
const file = path.resolve(__dirname, '../public/script.js');
const tracker = fs.readFileSync(file);

View File

@ -1773,22 +1773,22 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@prisma/client@4.11.0":
version "4.11.0"
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-4.11.0.tgz#41d5664dea4172c954190a432f70b86d3e2e629b"
integrity sha512-0INHYkQIqgAjrt7NzhYpeDQi8x3Nvylc2uDngKyFDDj1tTRQ4uV1HnVmd1sQEraeVAN63SOK0dgCKQHlvjL0KA==
"@prisma/client@4.13.0":
version "4.13.0"
resolved "https://registry.yarnpkg.com/@prisma/client/-/client-4.13.0.tgz#271d2b9756503ea17bbdb459c7995536cf2a6191"
integrity sha512-YaiiICcRB2hatxsbnfB66uWXjcRw3jsZdlAVxmx0cFcTc/Ad/sKdHCcWSnqyDX47vAewkjRFwiLwrOUjswVvmA==
dependencies:
"@prisma/engines-version" "4.11.0-57.8fde8fef4033376662cad983758335009d522acb"
"@prisma/engines-version" "4.13.0-50.1e7af066ee9cb95cf3a403c78d9aab3e6b04f37a"
"@prisma/engines-version@4.11.0-57.8fde8fef4033376662cad983758335009d522acb":
version "4.11.0-57.8fde8fef4033376662cad983758335009d522acb"
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-4.11.0-57.8fde8fef4033376662cad983758335009d522acb.tgz#74af5ff56170c78e93ce46c56510160f58cd3c01"
integrity sha512-3Vd8Qq06d5xD8Ch5WauWcUUrsVPdMC6Ge8ILji8RFfyhUpqon6qSyGM0apvr1O8n8qH8cKkEFqRPsYjuz5r83g==
"@prisma/engines-version@4.13.0-50.1e7af066ee9cb95cf3a403c78d9aab3e6b04f37a":
version "4.13.0-50.1e7af066ee9cb95cf3a403c78d9aab3e6b04f37a"
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-4.13.0-50.1e7af066ee9cb95cf3a403c78d9aab3e6b04f37a.tgz#ae338908d11685dee50e7683502d75442b955bf9"
integrity sha512-fsQlbkhPJf08JOzKoyoD9atdUijuGBekwoOPZC3YOygXEml1MTtgXVpnUNchQlRSY82OQ6pSGQ9PxUe4arcSLQ==
"@prisma/engines@4.11.0":
version "4.11.0"
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-4.11.0.tgz#c99749bfe20f58e8f4d2b5e04fee0785eba440e1"
integrity sha512-0AEBi2HXGV02cf6ASsBPhfsVIbVSDC9nbQed4iiY5eHttW9ZtMxHThuKZE1pnESbr8HRdgmFSa/Kn4OSNYuibg==
"@prisma/engines@4.13.0":
version "4.13.0"
resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-4.13.0.tgz#582a6b90b6efeb0f465984f1fe0e72a4afaaa5ae"
integrity sha512-HrniowHRZXHuGT9XRgoXEaP2gJLXM5RMoItaY2PkjvuZ+iHc0Zjbm/302MB8YsPdWozAPHHn+jpFEcEn71OgPw==
"@react-spring/animated@~9.5.5":
version "9.5.5"
@ -6628,12 +6628,12 @@ pretty-bytes@^5.6.0:
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb"
integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==
prisma@4.11.0:
version "4.11.0"
resolved "https://registry.yarnpkg.com/prisma/-/prisma-4.11.0.tgz#9695ba4129a43eab3e76b5f7a033c6c020377725"
integrity sha512-4zZmBXssPUEiX+GeL0MUq/Yyie4ltiKmGu7jCJFnYMamNrrulTBc+D+QwAQSJ01tyzeGHlD13kOnqPwRipnlNw==
prisma@4.13.0:
version "4.13.0"
resolved "https://registry.yarnpkg.com/prisma/-/prisma-4.13.0.tgz#0b83f40acf50cd47d7463a135c4e9b275713e602"
integrity sha512-L9mqjnSmvWIRCYJ9mQkwCtj4+JDYYTdhoyo8hlsHNDXaZLh/b4hR0IoKIBbTKxZuyHQzLopb/+0Rvb69uGV7uA==
dependencies:
"@prisma/engines" "4.11.0"
"@prisma/engines" "4.13.0"
prompts@2.4.2:
version "2.4.2"