Merge branch 'dev' into analytics

analytics
Brian Cao 2023-05-15 20:41:28 -07:00
commit 178a95f008
29 changed files with 782 additions and 530 deletions

32
.github/ISSUE_TEMPLATE/1.bug_report.yml vendored Normal file
View File

@ -0,0 +1,32 @@
name: "🐛 Bug Report"
description: Create a bug report for Umami.
body:
- type: textarea
attributes:
label: Describe the Bug
description: A clear and concise description of what the bug is.
validations:
required: true
- type: dropdown
attributes:
label: Database
description: What database are you using?
options:
- PostgreSQL
- MySQL
- Umami Cloud
validations:
required: true
- type: textarea
attributes:
label: Relevant log output
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
render: shell
- type: input
attributes:
label: Which browser are you using? (if relevant)
description: 'For example: Chrome, Edge, Firefox, etc'
- type: input
attributes:
label: How are you deploying your application? (if relevant)
description: 'For example: Vercel, Railway, Docker, etc'

View File

@ -0,0 +1,10 @@
name: "✨ Feature Request"
description: Create a feature or enhancement request for Umami.
labels: ['enhancement']
body:
- type: textarea
attributes:
label: Describe the feature or enhancement
description: A clear and concise description of what the feature or enhancement is.
validations:
required: true

6
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,6 @@
blank_issues_enabled: false
contact_links:
- name: "🤔 Ask a question"
url: https://github.com/umami-software/umami/discussions
about: Ask questions and discuss with other community members.

View File

@ -73,7 +73,10 @@ export function MetricsTable({
const filteredData = useMemo(() => { const filteredData = useMemo(() => {
if (data) { if (data) {
let items = percentFilter(dataFilter ? dataFilter(data, filterOptions) : data); const dataWithoutNullValues = data.filter(val => val.x !== null);
let items = percentFilter(
dataFilter ? dataFilter(dataWithoutNullValues, filterOptions) : dataWithoutNullValues,
);
if (limit) { if (limit) {
items = items.filter((e, i) => i < limit); items = items.filter((e, i) => i < limit);
} }

View File

@ -58,7 +58,10 @@ CREATE TABLE umami.website_event_queue (
--event --event
event_type UInt32, event_type UInt32,
event_name String, event_name String,
created_at DateTime('UTC') created_at DateTime('UTC'),
--virtual columns
_error String,
_raw_message String
) )
ENGINE = Kafka ENGINE = Kafka
SETTINGS kafka_broker_list = 'domain:9092,domain:9093,domain:9094', -- input broker list SETTINGS kafka_broker_list = 'domain:9092,domain:9093,domain:9094', -- input broker list
@ -66,7 +69,7 @@ SETTINGS kafka_broker_list = 'domain:9092,domain:9093,domain:9094', -- input bro
kafka_group_name = 'event_consumer_group', kafka_group_name = 'event_consumer_group',
kafka_format = 'JSONEachRow', kafka_format = 'JSONEachRow',
kafka_max_block_size = 1048576, kafka_max_block_size = 1048576,
kafka_skip_broken_messages = 100; kafka_handle_error_mode = 'stream'
CREATE MATERIALIZED VIEW umami.website_event_queue_mv TO umami.website_event AS CREATE MATERIALIZED VIEW umami.website_event_queue_mv TO umami.website_event AS
SELECT website_id, SELECT website_id,
@ -93,6 +96,19 @@ SELECT website_id,
created_at created_at
FROM umami.website_event_queue; FROM umami.website_event_queue;
CREATE MATERIALIZED VIEW umami.website_event_errors_mv
(
error String,
raw String
)
ENGINE = MergeTree
ORDER BY (error, raw)
SETTINGS index_granularity = 8192 AS
SELECT _error AS error,
_raw_message AS raw
FROM umami.website_event_queue
WHERE length(_error) > 0
CREATE TABLE umami.event_data CREATE TABLE umami.event_data
( (
website_id UUID, website_id UUID,
@ -122,7 +138,10 @@ CREATE TABLE umami.event_data_queue (
event_numeric_value Nullable(Decimal64(4)), --922337203685477.5625 event_numeric_value Nullable(Decimal64(4)), --922337203685477.5625
event_date_value Nullable(DateTime('UTC')), event_date_value Nullable(DateTime('UTC')),
event_data_type UInt32, event_data_type UInt32,
created_at DateTime('UTC') created_at DateTime('UTC'),
--virtual columns
_error String,
_raw_message String
) )
ENGINE = Kafka ENGINE = Kafka
SETTINGS kafka_broker_list = 'domain:9092,domain:9093,domain:9094', -- input broker list SETTINGS kafka_broker_list = 'domain:9092,domain:9093,domain:9094', -- input broker list
@ -130,7 +149,7 @@ SETTINGS kafka_broker_list = 'domain:9092,domain:9093,domain:9094', -- input bro
kafka_group_name = 'event_data_consumer_group', kafka_group_name = 'event_data_consumer_group',
kafka_format = 'JSONEachRow', kafka_format = 'JSONEachRow',
kafka_max_block_size = 1048576, kafka_max_block_size = 1048576,
kafka_skip_broken_messages = 100; kafka_handle_error_mode = 'stream'
CREATE MATERIALIZED VIEW umami.event_data_queue_mv TO umami.event_data AS CREATE MATERIALIZED VIEW umami.event_data_queue_mv TO umami.event_data AS
SELECT website_id, SELECT website_id,
@ -145,3 +164,16 @@ SELECT website_id,
event_data_type, event_data_type,
created_at created_at
FROM umami.event_data_queue; FROM umami.event_data_queue;
CREATE MATERIALIZED VIEW umami.event_data_errors_mv
(
error String,
raw String
)
ENGINE = MergeTree
ORDER BY (error, raw)
SETTINGS index_granularity = 8192 AS
SELECT _error AS error,
_raw_message AS raw
FROM umami.event_data_queue
WHERE length(_error) > 0

View File

@ -10,7 +10,8 @@ services:
DATABASE_TYPE: postgresql DATABASE_TYPE: postgresql
APP_SECRET: replace-me-with-a-random-string APP_SECRET: replace-me-with-a-random-string
depends_on: depends_on:
- db db:
condition: service_healthy
restart: always restart: always
db: db:
image: postgres:15-alpine image: postgres:15-alpine
@ -19,8 +20,12 @@ services:
POSTGRES_USER: umami POSTGRES_USER: umami
POSTGRES_PASSWORD: umami POSTGRES_PASSWORD: umami
volumes: volumes:
- ./sql/schema.postgresql.sql:/docker-entrypoint-initdb.d/schema.postgresql.sql:ro
- umami-db-data:/var/lib/postgresql/data - umami-db-data:/var/lib/postgresql/data
restart: always restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
volumes: volumes:
umami-db-data: umami-db-data:

View File

@ -1,16 +1,32 @@
{ {
"cs-CZ": ["label.reset", "metrics.device.tablet"], "cs-CZ": ["label.reset", "metrics.device.tablet"],
"de-DE": [ "de-CH": [
"label.administrator", "label.admin",
"label.name", "label.analytics",
"label.desktop",
"label.details",
"label.domain", "label.domain",
"label.theme", "label.laptop",
"metrics.device.desktop", "label.tablet",
"metrics.device.laptop", "label.name",
"metrics.device.tablet", "label.sessions",
"metrics.referrers", "label.team",
"metrics.utm", "label.team-id",
"metrics.utm_medium" "label.teams"
],
"de-DE": [
"label.admin",
"label.analytics",
"label.desktop",
"label.details",
"label.domain",
"label.laptop",
"label.tablet",
"label.name",
"label.sessions",
"label.team",
"label.team-id",
"label.teams"
], ],
"en-GB": "*", "en-GB": "*",
"fr-FR": ["metrics.actions", "metrics.pages"], "fr-FR": ["metrics.actions", "metrics.pages"],
@ -22,12 +38,15 @@
], ],
"nb-NO": ["label.administrator", "label.dashboard"], "nb-NO": ["label.administrator", "label.dashboard"],
"nl-NL": [ "nl-NL": [
"label.administrator", "label.analytics",
"label.websites", "label.browsers",
"metrics.browsers", "label.laptop",
"metrics.device.desktop", "label.tablet",
"metrics.device.laptop", "label.team",
"metrics.device.tablet" "label.team-id",
"label.teams",
"label.website-id",
"label.websites"
], ],
"it-IT": [ "it-IT": [
"label.password", "label.password",
@ -37,9 +56,5 @@
"metrics.device.tablet", "metrics.device.tablet",
"metrics.filter.raw" "metrics.filter.raw"
], ],
"pt-PT": [ "pt-PT": ["label.websites", "metrics.device.desktop", "metrics.device.tablet"]
"label.websites",
"metrics.device.desktop",
"metrics.device.tablet"
]
} }

View File

@ -1,7 +1,7 @@
{ {
"label.access-code": "Access code", "label.access-code": "Zuegangscode",
"label.actions": "Aktione", "label.actions": "Aktione",
"label.activity-log": "Activity log", "label.activity-log": "Aktivitätsverlauf",
"label.add-website": "Websiite hinzuefüege", "label.add-website": "Websiite hinzuefüege",
"label.admin": "Administrator", "label.admin": "Administrator",
"label.all": "Alli", "label.all": "Alli",
@ -13,24 +13,24 @@
"label.browsers": "Browser", "label.browsers": "Browser",
"label.cancel": "Abbreche", "label.cancel": "Abbreche",
"label.change-password": "Passwort ändere", "label.change-password": "Passwort ändere",
"label.cities": "Cities", "label.cities": "Städt",
"label.clear-all": "Clear all", "label.clear-all": "Alles lösche",
"label.confirm": "Confirm", "label.confirm": "Bestätige",
"label.confirm-password": "Passwort widerhole", "label.confirm-password": "Passwort widerhole",
"label.continue": "Continue", "label.continue": "Wiiter",
"label.countries": "Länder", "label.countries": "Länder",
"label.create-team": "Create team", "label.create-team": "Team erstelle",
"label.create-user": "Create user", "label.create-user": "Benutzer erstelle",
"label.created": "Created", "label.created": "Erstellt",
"label.current-password": "Jetzigs Passwort", "label.current-password": "Jetzigs Passwort",
"label.custom-range": "Benutzerdefinierte Bereich", "label.custom-range": "Benutzerdefinierte Bereich",
"label.dashboard": "Übersicht", "label.dashboard": "Übersicht",
"label.data": "Data", "label.data": "Datä",
"label.date-range": "Datumsbereich", "label.date-range": "Datumsbereich",
"label.default-date-range": "Vorigstellte Datumsbereich", "label.default-date-range": "Vorigstellte Datumsbereich",
"label.delete": "Lösche", "label.delete": "Lösche",
"label.delete-team": "Delete team", "label.delete-team": "Team lösche",
"label.delete-user": "Delete user", "label.delete-user": "Benutzer lösche",
"label.delete-website": "Websiite lösche", "label.delete-website": "Websiite lösche",
"label.desktop": "Desktop", "label.desktop": "Desktop",
"label.details": "Details", "label.details": "Details",
@ -43,104 +43,104 @@
"label.events": "Ereigniss", "label.events": "Ereigniss",
"label.filter-combined": "Kombiniert", "label.filter-combined": "Kombiniert",
"label.filter-raw": "Rohdate", "label.filter-raw": "Rohdate",
"label.join": "Join", "label.join": "Biträte",
"label.join-team": "Join team", "label.join-team": "Team biträte",
"label.language": "Sprach", "label.language": "Sprach",
"label.languages": "Sprache", "label.languages": "Sprache",
"label.laptop": "Laptop", "label.laptop": "Laptop",
"label.last-days": "Letzti {x} Täg", "label.last-days": "Letzti {x} Täg",
"label.last-hours": "Letzti {x} Stunde", "label.last-hours": "Letzti {x} Stunde",
"label.leave": "Leave", "label.leave": "Verlah",
"label.leave-team": "Leave team", "label.leave-team": "Team verlah",
"label.login": "Login", "label.login": "Aamelde",
"label.logout": "Abmelde", "label.logout": "Abmelde",
"label.members": "Members", "label.members": "Mitglieder",
"label.mobile": "Handy", "label.mobile": "Handy",
"label.more": "Meh", "label.more": "Meh",
"label.name": "Name", "label.name": "Name",
"label.new-password": "Neus Passwort", "label.new-password": "Neus Passwort",
"label.none": "Keis", "label.none": "Keis",
"label.operating-systems": "Betriebssystem", "label.operating-systems": "Betriibssystem",
"label.owner": "Bsitzer", "label.owner": "Bsitzer",
"label.page-views": "Siitenufrüef", "label.page-views": "Siitenufrüef",
"label.pages": "Siite", "label.pages": "Siite",
"label.password": "Passwort", "label.password": "Passwort",
"label.powered-by": "Betribe dur {name}", "label.powered-by": "Betribe dur {name}",
"label.profile": "Profil", "label.profile": "Profil",
"label.queries": "Queries", "label.queries": "Abfrage",
"label.query-parameters": "Abfragparameter", "label.query-parameters": "Abfragparameter",
"label.realtime": "Echtzit", "label.realtime": "Echtzit",
"label.referrers": "Referrer", "label.referrers": "Referrer",
"label.refresh": "Aktualisiere", "label.refresh": "Aktualisiere",
"label.regenerate": "Regenerate", "label.regenerate": "Erneuere",
"label.regions": "Regions", "label.regions": "Regionä",
"label.remove": "Remove", "label.remove": "Entferne",
"label.required": "Erforderlich", "label.required": "Erforderlich",
"label.reset": "Zruggsetze", "label.reset": "Zruggsetze",
"label.reset-website": "Statistik zruggsetze", "label.reset-website": "Statistik zruggsetze",
"label.role": "Role", "label.role": "Rol",
"label.save": "Speichere", "label.save": "Speichere",
"label.screens": "Bildschirmuflösige", "label.screens": "Bildschirmuflösige",
"label.select-website": "Select website", "label.select-website": "Websiite uuswähle",
"label.sessions": "Sessions", "label.sessions": "Sessions",
"label.settings": "Istellige", "label.settings": "Istellige",
"label.share-url": "Freigab-URL", "label.share-url": "Freigab-URL",
"label.single-day": "Ein Tag", "label.single-day": "Ein Tag",
"label.tablet": "Tablet", "label.tablet": "Tablet",
"label.team": "Team", "label.team": "Team",
"label.team-guest": "Team guest", "label.team-guest": "Team Gast",
"label.team-id": "Team ID", "label.team-id": "Team ID",
"label.team-member": "Team member", "label.team-member": "Team Mitglied",
"label.team-owner": "Team owner", "label.team-owner": "Team Bsitzer",
"label.teams": "Teams", "label.teams": "Teams",
"label.theme": "Thema", "label.theme": "Thema",
"label.this-month": "De Monet", "label.this-month": "De Monet",
"label.this-week": "Die Wuche", "label.this-week": "Die Wuche",
"label.this-year": "Das Jahr", "label.this-year": "Das Jahr",
"label.timezone": "Zitzone", "label.timezone": "Ziitzone",
"label.title": "Title", "label.title": "Titel",
"label.today": "Hüt", "label.today": "Hüt",
"label.toggle-charts": "Schaubilder umschalte", "label.toggle-charts": "Schaubilder umschalte",
"label.tracking-code": "Tracking Code", "label.tracking-code": "Tracking Code",
"label.unique-visitors": "Eidütigi Bsuecher", "label.unique-visitors": "Eidütigi Bsuecher",
"label.unknown": "Unbekannt", "label.unknown": "Unbekannt",
"label.user": "User", "label.user": "Benutzer",
"label.username": "Benutzername", "label.username": "Benutzername",
"label.users": "Users", "label.users": "Benutzer",
"label.view": "View", "label.view": "Azeige",
"label.view-details": "Details azeige", "label.view-details": "Details azeige",
"label.views": "Ufrüef", "label.views": "Ufrüef",
"label.visitors": "Bsuecher", "label.visitors": "Bsuecher",
"label.website-id": "Website ID", "label.website-id": "Websiite ID",
"label.websites": "Websiite", "label.websites": "Websiite",
"label.yesterday": "Gester", "label.yesterday": "Gester",
"message.active-users": "{x} {x, plural, one {aktive Bsuecher} other {aktivi Bsuecher}}", "message.active-users": "{x} {x, plural, one {aktive Bsuecher} other {aktivi Bsuecher}}",
"message.confirm-delete": "Sind Sie sich sicher, {target} zlösche?", "message.confirm-delete": "Sind Sie sich sicher, {target} zlösche?",
"message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-leave": "Sind Sie sich sicher, {target} zverlah?",
"message.confirm-reset": "Sind Sie sicher, dass Sie dStatistike vo {target} zruggsetze wend?", "message.confirm-reset": "Sind Sie sicher, dass Sie dStatistike vo {target} zruggsetze wend?",
"message.delete-website": "Websiite lösche", "message.delete-website": "Websiite lösche",
"message.delete-website-warning": "Alli dezueghörige Date werdet ebefalls glöscht.", "message.delete-website-warning": "Alli dezueghörige Date werdet ebefalls glöscht.",
"message.error": "Es isch en Fehler uftrete.", "message.error": "Es isch en Fehler uftrete.",
"message.event-log": "{event} on {url}", "message.event-log": "{event} uf {url}",
"message.go-to-settings": "Zu de Istellige", "message.go-to-settings": "Zu de Istellige",
"message.incorrect-username-password": "Falschs Passwort oder Benutzername.", "message.incorrect-username-password": "Falschs Passwort oder Benutzername.",
"message.invalid-domain": "Ungültigi Domain", "message.invalid-domain": "Ungültigi Domain",
"message.min-password-length": "Minimum length of {n} characters", "message.min-password-length": "Miminamli längi vo {n} Zeiche",
"message.no-data-available": "Kei Date vorhande.", "message.no-data-available": "Kei Date vorhande.",
"message.no-match-password": "Passwörter stimmed ned überi", "message.no-match-password": "Passwörter stimmed ned überi",
"message.no-teams": "You have not created any teams.", "message.no-teams": "Bisher sind no kei Teams erstellt worde.",
"message.no-users": "There are no users.", "message.no-users": "Da gits kei Benutzer",
"message.page-not-found": "Siite ned gfunde.", "message.page-not-found": "Siite ned gfunde.",
"message.reset-website": "Statistik zruggsetze", "message.reset-website": "Statistik zruggsetze",
"message.reset-website-warning": "Alli Date für die Websiite werdet glöscht, nur de Tracking Code blibt bestah.", "message.reset-website-warning": "Alli Date für die Websiite werdet glöscht, nur de Tracking Code blibt bestah.",
"message.saved": "Erfolgrich gspeichert.", "message.saved": "Erfolgrich gspeichert.",
"message.share-url": "Das isch die öffentlichi URL zum Teile für {target}.", "message.share-url": "Ihri Websiitestatistik isch under de folgende URL öffentlich zuegänglich:",
"message.team-already-member": "You are already a member of the team.", "message.team-already-member": "Sie sind bereits es Mitglied vo dem Team.",
"message.team-not-found": "Team not found.", "message.team-not-found": "Team nöd gfunde.",
"message.tracking-code": "Tracking Code", "message.tracking-code": "Tracking Code",
"message.user-deleted": "User deleted.", "message.user-deleted": "Benutzer glöscht.",
"message.visitor-log": "Bsuecher us {country} benutzt {browser} uf {os} {device}", "message.visitor-log": "Bsuecher us {country} benutzt {browser} uf {os} {device}",
"messages.no-team-websites": "This team does not have any websites.", "messages.no-team-websites": "Dem Team sind kei Websiite zuegordnet.",
"messages.no-websites-configured": "Es isch kei Websiite vorhande.", "messages.no-websites-configured": "Es isch kei Websiite vorhande.",
"messages.team-websites-info": "Websites can be viewed by anyone on the team." "messages.team-websites-info": "Websiite chönd vo jedem im Team agluegt werde"
} }

View File

@ -19,8 +19,8 @@
"label.confirm-password": "Passwort wiederholen", "label.confirm-password": "Passwort wiederholen",
"label.continue": "Weiter", "label.continue": "Weiter",
"label.countries": "Länder", "label.countries": "Länder",
"label.create-team": "Erstelle Team", "label.create-team": "Team erstellen",
"label.create-user": "Erstelle Nutzer", "label.create-user": "Benutzer erstellen",
"label.created": "Erstellt", "label.created": "Erstellt",
"label.current-password": "Derzeitiges Passwort", "label.current-password": "Derzeitiges Passwort",
"label.custom-range": "Benutzerdefinierter Bereich", "label.custom-range": "Benutzerdefinierter Bereich",
@ -29,8 +29,8 @@
"label.date-range": "Datumsbereich", "label.date-range": "Datumsbereich",
"label.default-date-range": "Voreingestellter Datumsbereich", "label.default-date-range": "Voreingestellter Datumsbereich",
"label.delete": "Löschen", "label.delete": "Löschen",
"label.delete-team": "Lösche Team", "label.delete-team": "Team löschen",
"label.delete-user": "Lösche Nutzer", "label.delete-user": "Benutzer löschen",
"label.delete-website": "Webseite löschen", "label.delete-website": "Webseite löschen",
"label.desktop": "Desktop", "label.desktop": "Desktop",
"label.details": "Details", "label.details": "Details",
@ -48,8 +48,8 @@
"label.language": "Sprache", "label.language": "Sprache",
"label.languages": "Sprachen", "label.languages": "Sprachen",
"label.laptop": "Laptop", "label.laptop": "Laptop",
"label.last-days": "Letzten {x} Tage", "label.last-days": "Letzte {x} Tage",
"label.last-hours": "Letzten {x} Stunden", "label.last-hours": "Letzte {x} Stunden",
"label.leave": "Verlassen", "label.leave": "Verlassen",
"label.leave-team": "Team verlassen", "label.leave-team": "Team verlassen",
"label.login": "Anmelden", "label.login": "Anmelden",
@ -73,7 +73,7 @@
"label.referrers": "Referrer", "label.referrers": "Referrer",
"label.refresh": "Aktualisieren", "label.refresh": "Aktualisieren",
"label.regenerate": "Erneuern", "label.regenerate": "Erneuern",
"label.regions": "Regions", "label.regions": "Regionen",
"label.remove": "Entfernen", "label.remove": "Entfernen",
"label.required": "Erforderlich", "label.required": "Erforderlich",
"label.reset": "Zurücksetzen", "label.reset": "Zurücksetzen",
@ -101,17 +101,17 @@
"label.title": "Titel", "label.title": "Titel",
"label.today": "Heute", "label.today": "Heute",
"label.toggle-charts": "Schaubilder umschalten", "label.toggle-charts": "Schaubilder umschalten",
"label.tracking-code": "Tracking Kennung", "label.tracking-code": "Tracking Code",
"label.unique-visitors": "Eindeutige Besucher", "label.unique-visitors": "Eindeutige Besucher",
"label.unknown": "Unbekannt", "label.unknown": "Unbekannt",
"label.user": "User", "label.user": "Benutzer",
"label.username": "Benutzername", "label.username": "Benutzername",
"label.users": "Users", "label.users": "Benutzer",
"label.view": "View", "label.view": "Anzeigen",
"label.view-details": "Details anzeigen", "label.view-details": "Details anzeigen",
"label.views": "Aufrufe", "label.views": "Aufrufe",
"label.visitors": "Besucher", "label.visitors": "Besucher",
"label.website-id": "Website ID", "label.website-id": "Webseite ID",
"label.websites": "Webseiten", "label.websites": "Webseiten",
"label.yesterday": "Gestern", "label.yesterday": "Gestern",
"message.active-users": "{x} {x, plural, one {aktiver Besucher} other {aktive Besucher}}", "message.active-users": "{x} {x, plural, one {aktiver Besucher} other {aktive Besucher}}",
@ -121,7 +121,7 @@
"message.delete-website": "Webseite löschen", "message.delete-website": "Webseite löschen",
"message.delete-website-warning": "Alle zugehörigen Daten werden ebenfalls gelöscht.", "message.delete-website-warning": "Alle zugehörigen Daten werden ebenfalls gelöscht.",
"message.error": "Es ist ein Fehler aufgetreten.", "message.error": "Es ist ein Fehler aufgetreten.",
"message.event-log": "{event} on {url}", "message.event-log": "{event} auf {url}",
"message.go-to-settings": "Zu den Einstellungen", "message.go-to-settings": "Zu den Einstellungen",
"message.incorrect-username-password": "Falsches Passwort oder Benutzername.", "message.incorrect-username-password": "Falsches Passwort oder Benutzername.",
"message.invalid-domain": "Ungültige Domain", "message.invalid-domain": "Ungültige Domain",
@ -129,16 +129,16 @@
"message.no-data-available": "Keine Daten vorhanden.", "message.no-data-available": "Keine Daten vorhanden.",
"message.no-match-password": "Passwörter stimmen nicht überein", "message.no-match-password": "Passwörter stimmen nicht überein",
"message.no-teams": "Bisher wurden keine Teams erstellt.", "message.no-teams": "Bisher wurden keine Teams erstellt.",
"message.no-users": "Hier gibt es keine Nutzer.", "message.no-users": "Hier gibt es keine Benutzer.",
"message.page-not-found": "Seite nicht gefunden.", "message.page-not-found": "Seite nicht gefunden.",
"message.reset-website": "Statistik zurücksetzen", "message.reset-website": "Statistik zurücksetzen",
"message.reset-website-warning": "Alle Daten für diese Webseite werden gelöscht, jedoch bleibt der Tracking Code bestehen.", "message.reset-website-warning": "Alle Daten für diese Webseite werden gelöscht, jedoch bleibt der Tracking Code bestehen.",
"message.saved": "Erfolgreich gespeichert.", "message.saved": "Erfolgreich gespeichert.",
"message.share-url": "Dies ist die öffentliche URL zum Teilen für {target}.", "message.share-url": "Ihre Webseitenstatistik ist unter der folgenden URL öffentlich zugänglich:",
"message.team-already-member": "Sie sind bereits Mitglied des Teams.", "message.team-already-member": "Sie sind bereits Mitglied des Teams.",
"message.team-not-found": "Team nicht gefunden.", "message.team-not-found": "Team nicht gefunden.",
"message.tracking-code": "Tracking Kennung", "message.tracking-code": "Tracking Code",
"message.user-deleted": "Nutzer gelöscht.", "message.user-deleted": "Benutzer gelöscht.",
"message.visitor-log": "Besucher aus {country} benutzt {browser} auf {os} {device}", "message.visitor-log": "Besucher aus {country} benutzt {browser} auf {os} {device}",
"messages.no-team-websites": "Diesem Team sind keine Websites zugeordnet.", "messages.no-team-websites": "Diesem Team sind keine Websites zugeordnet.",
"messages.no-websites-configured": "Es ist keine Webseite vorhanden.", "messages.no-websites-configured": "Es ist keine Webseite vorhanden.",

View File

@ -1,7 +1,7 @@
{ {
"label.access-code": "Access code", "label.access-code": "Хандалтын код",
"label.actions": "Үйлдлүүд", "label.actions": "Үйлдлүүд",
"label.activity-log": "Activity log", "label.activity-log": "Үйл ажиллагааны бүртгэл",
"label.add-website": "Веб нэмэх", "label.add-website": "Веб нэмэх",
"label.admin": "Админ", "label.admin": "Админ",
"label.all": "Бүх", "label.all": "Бүх",
@ -13,27 +13,27 @@
"label.browsers": "Хөтөч", "label.browsers": "Хөтөч",
"label.cancel": "Цуцлах", "label.cancel": "Цуцлах",
"label.change-password": "Нууц үг солих", "label.change-password": "Нууц үг солих",
"label.cities": "Cities", "label.cities": "Хотууд",
"label.clear-all": "Clear all", "label.clear-all": "Бүгдийг арилгах",
"label.confirm": "Confirm", "label.confirm": "Батлах",
"label.confirm-password": "Шинэ нууц үгээ давтах", "label.confirm-password": "Шинэ нууц үгээ давтах",
"label.continue": "Continue", "label.continue": "Үргэлжлүүлэх",
"label.countries": "Улс", "label.countries": "Улс",
"label.create-team": "Create team", "label.create-team": "Баг үүсгэх",
"label.create-user": "Create user", "label.create-user": "Хэрэглэгч үүсгэх",
"label.created": "Created", "label.created": "Үүсгэсэн",
"label.current-password": "Ашиглаж буй нууц үг", "label.current-password": "Ашиглаж буй нууц үг",
"label.custom-range": "Дурын хугацаа", "label.custom-range": "Дурын хугацаа",
"label.dashboard": "Хянах самбар", "label.dashboard": "Хянах самбар",
"label.data": "Data", "label.data": "Өгөгдөл",
"label.date-range": "Хугацааны мужид", "label.date-range": "Хугацааны муж",
"label.default-date-range": "Өгөгдмөл хугацааны муж", "label.default-date-range": "Өгөгдмөл хугацааны муж",
"label.delete": "Устгах", "label.delete": "Устгах",
"label.delete-team": "Delete team", "label.delete-team": "Баг устгах",
"label.delete-user": "Delete user", "label.delete-user": "Хэрэглэгч устгах",
"label.delete-website": "Веб устгах", "label.delete-website": "Веб устгах",
"label.desktop": "Суурин компьютер", "label.desktop": "Суурин компьютер",
"label.details": "Details", "label.details": "Мэдээлэл",
"label.devices": "Төхөөрөмж", "label.devices": "Төхөөрөмж",
"label.dismiss": "Үл хэргэсэх", "label.dismiss": "Үл хэргэсэх",
"label.domain": "Домэйн", "label.domain": "Домэйн",
@ -43,18 +43,18 @@
"label.events": "Үйлдэл", "label.events": "Үйлдэл",
"label.filter-combined": "Нэгтгэсэн", "label.filter-combined": "Нэгтгэсэн",
"label.filter-raw": "Түүхий", "label.filter-raw": "Түүхий",
"label.join": "Join", "label.join": "Нэгдэх",
"label.join-team": "Join team", "label.join-team": "Багт нэгдэх",
"label.language": "Хэл", "label.language": "Хэл",
"label.languages": "Хэл", "label.languages": "Хэл",
"label.laptop": "Зөөврийн компьютер", "label.laptop": "Зөөврийн компьютер",
"label.last-days": "Сүүлийн {x} хоног", "label.last-days": "Сүүлийн {x} хоног",
"label.last-hours": "Сүүлийн {x} цаг", "label.last-hours": "Сүүлийн {x} цаг",
"label.leave": "Leave", "label.leave": "Гарах",
"label.leave-team": "Leave team", "label.leave-team": "Багаас гарах",
"label.login": "Нэвтрэх", "label.login": "Нэвтрэх",
"label.logout": "Гарах", "label.logout": "Гарах",
"label.members": "Members", "label.members": "Гишүүд",
"label.mobile": "Утас", "label.mobile": "Утас",
"label.more": "Цааш", "label.more": "Цааш",
"label.name": "Нэр", "label.name": "Нэр",
@ -67,80 +67,80 @@
"label.password": "Нууц үг", "label.password": "Нууц үг",
"label.powered-by": "{name} дээр суурилсан", "label.powered-by": "{name} дээр суурилсан",
"label.profile": "Бүртгэл", "label.profile": "Бүртгэл",
"label.queries": "Queries", "label.queries": "Query-нүүд",
"label.query-parameters": "Query параметр", "label.query-parameters": "Query параметр",
"label.realtime": "Яг одоо", "label.realtime": "Яг одоо",
"label.referrers": "Чиглүүлэгч", "label.referrers": "Чиглүүлэгч",
"label.refresh": "Сэргээх", "label.refresh": "Сэргээх",
"label.regenerate": "Regenerate", "label.regenerate": "Дахин үүсгэх",
"label.regions": "Regions", "label.regions": "Бүсүүд",
"label.remove": "Remove", "label.remove": "Устгах",
"label.required": "Шаардлагатай", "label.required": "Шаардлагатай",
"label.reset": "Хуучин хэвд нь оруулах", "label.reset": "Дахин эхлүүлэх",
"label.reset-website": "Тоон үзүүлэлтийг дахин эхлүүлэх", "label.reset-website": "Тоон үзүүлэлтийг дахин эхлүүлэх",
"label.role": "Role", "label.role": "Эрх",
"label.save": "Хадгалах", "label.save": "Хадгалах",
"label.screens": "Дэлгэц", "label.screens": "Дэлгэц",
"label.select-website": "Select website", "label.select-website": "Веб сонгох",
"label.sessions": "Sessions", "label.sessions": "Sessions",
"label.settings": "Тохиргоо", "label.settings": "Тохиргоо",
"label.share-url": "Хуваалцах холбоос", "label.share-url": "Хуваалцах холбоос",
"label.single-day": "Нэг өдөр", "label.single-day": "Нэг өдөр",
"label.tablet": "Таблет", "label.tablet": "Таблет",
"label.team": "Team", "label.team": "Баг",
"label.team-guest": "Team guest", "label.team-guest": "Багийн зочин",
"label.team-id": "Team ID", "label.team-id": "Багийн ID",
"label.team-member": "Team member", "label.team-member": "Багийн гишүүн",
"label.team-owner": "Team owner", "label.team-owner": "Багийн эзэмшигч",
"label.teams": "Teams", "label.teams": "Багууд",
"label.theme": "Загвар", "label.theme": "Загвар",
"label.this-month": "Энэ сар", "label.this-month": "Энэ сар",
"label.this-week": "Энэ долоо хоног", "label.this-week": "Энэ долоо хоног",
"label.this-year": "Энэ жил", "label.this-year": "Энэ жил",
"label.timezone": "Цагийн бүс", "label.timezone": "Цагийн бүс",
"label.title": "Title", "label.title": "Гарчиг",
"label.today": "Өнөөдөр", "label.today": "Өнөөдөр",
"label.toggle-charts": "Графикийг харуулах/нуух", "label.toggle-charts": "Графикийг харуулах/нуух",
"label.tracking-code": "Мөрдөх код", "label.tracking-code": "Мөрдөх код",
"label.unique-visitors": "Зочин", "label.unique-visitors": "Зочин",
"label.unknown": "Тодорхойгүй", "label.unknown": "Тодорхойгүй",
"label.user": "User", "label.user": "Хэрэглэгч",
"label.username": "Хэрэглэгчийн нэр", "label.username": "Хэрэглэгчийн нэр",
"label.users": "Users", "label.users": "Хэрэглэгчид",
"label.view": "View", "label.view": "Харах",
"label.view-details": "Дэлгэрүүлж харах", "label.view-details": "Дэлгэрүүлж харах",
"label.views": "Үзсэн", "label.views": "Үзсэн",
"label.visitors": "Зочин", "label.visitors": "Зочин",
"label.website-id": "Website ID", "label.website-id": "Вебийн ID",
"label.websites": "Вебүүд", "label.websites": "Вебүүд",
"label.yesterday": "Өчигдөр", "label.yesterday": "Өчигдөр",
"message.active-users": "одоо {x} {x, plural, one {зочин} other {зочин}} байна", "message.active-users": "одоо {x} {x, plural, one {зочин} other {зочин}} байна",
"message.confirm-delete": "Та {target}-г устгахдаа итгэлтэй байна уу?", "message.confirm-delete": "Та {target}-г устгахдаа итгэлтэй байна уу?",
"message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-leave": "Та {target}-с гарахдаа итгэлтэй байна уу?",
"message.confirm-reset": "Та {target}-н тоон үзүүлэлтүүдийг устгахдаа итгэлтэй байна уу?", "message.confirm-reset": "Та {target}-н тоон үзүүлэлтүүдийг устгахдаа итгэлтэй байна уу?",
"message.delete-website": "Веб устгах", "message.delete-website": "Веб устгахын тулд доорх хэсэгт {confirmation} гэж бичиж, баталгаажуулна уу.",
"message.delete-website-warning": "Үүнтэй холбоотой бүх өгөгдөл устах болно.", "message.delete-website-warning": "Энэ вебтэй холбоотой бүх өгөгдөл устах болно.",
"message.error": "Ямар нэг зүйл буруу боллоо.", "message.error": "Ямар нэг зүйл буруу боллоо.",
"message.event-log": "{event} on {url}", "message.event-log": "{url}-д {event}",
"message.go-to-settings": "Тохиргоо руу очих", "message.go-to-settings": "Тохиргоо руу очих",
"message.incorrect-username-password": "Буруу хэрэглэгчийн нэр/нууц үг.", "message.incorrect-username-password": "Буруу хэрэглэгчийн нэр/нууц үг.",
"message.invalid-domain": "Буруу домэйн", "message.invalid-domain": "Буруу домэйн",
"message.min-password-length": "Minimum length of {n} characters", "message.min-password-length": "Хамгийн багадаа {n} тэмдэгт",
"message.no-data-available": "Өгөгдөл алга.", "message.no-data-available": "Өгөгдөл алга.",
"message.no-match-password": "Нууц үг тохирохгүй байна", "message.no-match-password": "Нууц үг тохирохгүй байна.",
"message.no-teams": "You have not created any teams.", "message.no-teams": "Та ямар ч баг үүсгээгүй байна.",
"message.no-users": "There are no users.", "message.no-users": "Хэрэглэгч байхгүй байна.",
"message.page-not-found": "Хуудас олдсонгүй.", "message.page-not-found": "Хуудас олдсонгүй.",
"message.reset-website": "Тоон үзүүлэлтийг дахин эхлүүлэх", "message.reset-website": "Тоон үзүүлэлийг дахин эхлүүлэхийн тулд доорх хэсэгт {confirmation} гэж бичиж, баталгаажуулна уу.",
"message.reset-website-warning": "Энэ вебийн бүх тоон үзүүлэлтүүдийг устгах болно. Гэхдээ мөрдөх код хэвэндээ үлдэнэ.", "message.reset-website-warning": "Энэ вебийн бүх тоон үзүүлэлтүүдийг устгах болно. Гэхдээ мөрдөх код хэвэндээ үлдэнэ.",
"message.saved": "Амжилттай хадгаллаа.", "message.saved": "Хадгалсан.",
"message.share-url": "{target}-г нийтэд хуваалцах холбоос.", "message.share-url": "Таны вебийн тоон үзүүлэлтүүд доорх URL дээр нийтэд харагдах болно:",
"message.team-already-member": "You are already a member of the team.", "message.team-already-member": "Та аль хэдийн энэ багийн гишүүн болсон байна.",
"message.team-not-found": "Team not found.", "message.team-not-found": "Баг олдсонгүй.",
"message.tracking-code": "Мөрдөх код", "message.tracking-code": "Энэ вебийн хандалтуудыг мөрдөхийн тулд доорх кодыг HTML-нхээ <head>...</head> хэсэгт байрлуулна уу.",
"message.user-deleted": "User deleted.", "message.user-deleted": "Хэрэглэгч устсан.",
"message.visitor-log": "{country} улсаас {os} {device} дээр {browser} хөтөч ашиглан орсон", "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.no-websites-configured": "Та ямар нэгэн веб тохируулаагүй байна.",
"messages.team-websites-info": "Websites can be viewed by anyone on the team." "messages.team-websites-info": "Вебийг багийн бүх гишүүд үзэж болно."
} }

View File

@ -1,9 +1,9 @@
{ {
"label.access-code": "Access code", "label.access-code": "Toegangscode",
"label.actions": "Acties", "label.actions": "Acties",
"label.activity-log": "Activity log", "label.activity-log": "Activiteiten logboek",
"label.add-website": "Website toevoegen", "label.add-website": "Website koppelen",
"label.admin": "Administrator", "label.admin": "Beheerder",
"label.all": "Alles", "label.all": "Alles",
"label.all-time": "Onbeperkt", "label.all-time": "Onbeperkt",
"label.analytics": "Analytics", "label.analytics": "Analytics",
@ -13,48 +13,48 @@
"label.browsers": "Browsers", "label.browsers": "Browsers",
"label.cancel": "Annuleren", "label.cancel": "Annuleren",
"label.change-password": "Wachtwoord wijzigen", "label.change-password": "Wachtwoord wijzigen",
"label.cities": "Cities", "label.cities": "Steden",
"label.clear-all": "Clear all", "label.clear-all": "Filters wissen",
"label.confirm": "Confirm", "label.confirm": "Bevestigen",
"label.confirm-password": "Wachtwoord bevestigen", "label.confirm-password": "Wachtwoord bevestigen",
"label.continue": "Continue", "label.continue": "Doorgaan",
"label.countries": "Landen", "label.countries": "Landen",
"label.create-team": "Create team", "label.create-team": "Team aanmaken",
"label.create-user": "Create user", "label.create-user": "Gebruiker maken",
"label.created": "Created", "label.created": "Gemaakt",
"label.current-password": "Huidig wachtwoord", "label.current-password": "Huidig wachtwoord",
"label.custom-range": "Aangepast bereik", "label.custom-range": "Aangepast bereik",
"label.dashboard": "Overzicht", "label.dashboard": "Overzicht",
"label.data": "Data", "label.data": "Gegevens",
"label.date-range": "Datumbereik", "label.date-range": "Datumbereik",
"label.default-date-range": "Standaard bereik", "label.default-date-range": "Standaard bereik",
"label.delete": "Verwijderen", "label.delete": "Verwijderen",
"label.delete-team": "Delete team", "label.delete-team": "Team verwijderen",
"label.delete-user": "Delete user", "label.delete-user": "Verwijder gebruiker",
"label.delete-website": "Website verwijderen", "label.delete-website": "Website verwijderen",
"label.desktop": "Desktop", "label.desktop": "Computer",
"label.details": "Details", "label.details": "Informatie",
"label.devices": "Apparaten", "label.devices": "Apparaten",
"label.dismiss": "Negeren", "label.dismiss": "Negeren",
"label.domain": "Domein", "label.domain": "Domein",
"label.edit": "Bewerken", "label.edit": "Bewerken",
"label.edit-dashboard": "Edit dashboard", "label.edit-dashboard": "Dashboard aanpassen",
"label.enable-share-url": "Sta delen via openbare URL toe", "label.enable-share-url": "Sta delen via openbare URL toe",
"label.events": "Gebeurtenissen", "label.events": "Gebeurtenissen",
"label.filter-combined": "Gecombineerd", "label.filter-combined": "Gecombineerd",
"label.filter-raw": "Ruw", "label.filter-raw": "Ruw",
"label.join": "Join", "label.join": "Lid worden",
"label.join-team": "Join team", "label.join-team": "Word lid van een team",
"label.language": "Taal", "label.language": "Taal",
"label.languages": "Languages", "label.languages": "Talen",
"label.laptop": "Laptop", "label.laptop": "Laptop",
"label.last-days": "Laatste {x} dagen", "label.last-days": "Laatste {x} dagen",
"label.last-hours": "Laatste {x} uur", "label.last-hours": "Laatste {x} uur",
"label.leave": "Leave", "label.leave": "Verlaten",
"label.leave-team": "Leave team", "label.leave-team": "Verlaat team",
"label.login": "Inloggen", "label.login": "Inloggen",
"label.logout": "Uitloggen", "label.logout": "Uitloggen",
"label.members": "Members", "label.members": "Gebruikers",
"label.mobile": "Mobiel", "label.mobile": "Mobiel",
"label.more": "Toon meer", "label.more": "Toon meer",
"label.name": "Naam", "label.name": "Naam",
@ -67,80 +67,80 @@
"label.password": "Wachtwoord", "label.password": "Wachtwoord",
"label.powered-by": "mogelijk gemaakt door {name}", "label.powered-by": "mogelijk gemaakt door {name}",
"label.profile": "Profiel", "label.profile": "Profiel",
"label.queries": "Queries", "label.queries": "Parameters",
"label.query-parameters": "Query parameters", "label.query-parameters": "URL-parameters",
"label.realtime": "Actueel", "label.realtime": "Actueel",
"label.referrers": "Verwijzers", "label.referrers": "Verwijzers",
"label.refresh": "Vernieuwen", "label.refresh": "Vernieuwen",
"label.regenerate": "Regenerate", "label.regenerate": "Opnieuw genereren",
"label.regions": "Regions", "label.regions": "Regio's",
"label.remove": "Remove", "label.remove": "Verwijderen",
"label.required": "Verplicht", "label.required": "Verplicht",
"label.reset": "Resetten", "label.reset": "Opnieuw instellen",
"label.reset-website": "Statistieken opnieuw instellen", "label.reset-website": "Statistieken opnieuw instellen",
"label.role": "Role", "label.role": "Gebruikersrol",
"label.save": "Opslaan", "label.save": "Opslaan",
"label.screens": "Schermen", "label.screens": "Schermen",
"label.select-website": "Select website", "label.select-website": "Website selecteren",
"label.sessions": "Sessions", "label.sessions": "Sessies",
"label.settings": "Instellingen", "label.settings": "Instellingen",
"label.share-url": "URL delen", "label.share-url": "URL delen",
"label.single-day": "Enkele dag", "label.single-day": "Enkele dag",
"label.tablet": "Tablet", "label.tablet": "Tablet",
"label.team": "Team", "label.team": "Team",
"label.team-guest": "Team guest", "label.team-guest": "Team gast",
"label.team-id": "Team ID", "label.team-id": "Team ID",
"label.team-member": "Team member", "label.team-member": "Teamlid",
"label.team-owner": "Team owner", "label.team-owner": "Teameigenaar",
"label.teams": "Teams", "label.teams": "Teams",
"label.theme": "Thema", "label.theme": "Thema",
"label.this-month": "Deze maand", "label.this-month": "Deze maand",
"label.this-week": "Deze week", "label.this-week": "Deze week",
"label.this-year": "Dit jaar", "label.this-year": "Dit jaar",
"label.timezone": "Tijdzone", "label.timezone": "Tijdzone",
"label.title": "Title", "label.title": "Titel",
"label.today": "Vandaag", "label.today": "Vandaag",
"label.toggle-charts": "Grafieken tonen/verbergen", "label.toggle-charts": "Grafieken tonen/verbergen",
"label.tracking-code": "Volgcode", "label.tracking-code": "Volgcode",
"label.unique-visitors": "Unieke bezoekers", "label.unique-visitors": "Unieke bezoekers",
"label.unknown": "Onbekend", "label.unknown": "Onbekend",
"label.user": "User", "label.user": "Gebruiker",
"label.username": "Gebruikersnaam", "label.username": "Gebruikersnaam",
"label.users": "Users", "label.users": "Gebruikers",
"label.view": "View", "label.view": "Weergave",
"label.view-details": "Meer details", "label.view-details": "Meer details",
"label.views": "Weergaven", "label.views": "Weergaven",
"label.visitors": "Bezoekers", "label.visitors": "Bezoekers",
"label.website-id": "Website ID", "label.website-id": "Website ID",
"label.websites": "Websites", "label.websites": "Websites",
"label.yesterday": "Yesterday", "label.yesterday": "Gisteren",
"message.active-users": "{x} actieve {x, plural, one {bezoeker} other {bezoekers}}", "message.active-users": "{x} actieve {x, plural, one {bezoeker} other {bezoekers}}",
"message.confirm-delete": "Weet je zeker dat je {target} wilt verwijderen?", "message.confirm-delete": "Weet je zeker dat je {target} wilt verwijderen?",
"message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-leave": "Weet je zeker dat je {target} wilt verlaten?",
"message.confirm-reset": "Weet je zeker dat je de statistieken van {target} opnieuw wilt instellen?", "message.confirm-reset": "Weet je zeker dat je de statistieken van {target} opnieuw wilt instellen?",
"message.delete-website": "Website verwijderen", "message.delete-website": "Website verwijderen",
"message.delete-website-warning": "Alle verwante gegezens zullen ook verwijderd worden.", "message.delete-website-warning": "Alle verwante gegezens zullen ook verwijderd worden.",
"message.error": "Er is iets misgegaan.", "message.error": "Er is iets misgegaan.",
"message.event-log": "{event} on {url}", "message.event-log": "{event} op {url}",
"message.go-to-settings": "Naar instellingen", "message.go-to-settings": "Naar instellingen",
"message.incorrect-username-password": "Incorrecte gebruikersnaam/wachtwoord.", "message.incorrect-username-password": "Incorrecte gebruikersnaam/wachtwoord.",
"message.invalid-domain": "Ongeldig domein", "message.invalid-domain": "Ongeldig domein",
"message.min-password-length": "Minimum length of {n} characters", "message.min-password-length": "Minimale lengte van {n} tekens",
"message.no-data-available": "Geen gegevens beschikbaar.", "message.no-data-available": "Geen gegevens beschikbaar.",
"message.no-match-password": "Wachtwoorden komen niet overeen", "message.no-match-password": "Wachtwoorden komen niet overeen",
"message.no-teams": "You have not created any teams.", "message.no-teams": "Er zijn nog geen teams aangemaakt.",
"message.no-users": "There are no users.", "message.no-users": "Er zijn geen gebruikers.",
"message.page-not-found": "Pagina niet gevonden.", "message.page-not-found": "Pagina niet gevonden.",
"message.reset-website": "Statistieken opnieuw instellen", "message.reset-website": "Statistieken opnieuw instellen",
"message.reset-website-warning": "Alle bijhorende statistieken van deze website worden verwijderd, maar jouw volgcode blijft gelden.", "message.reset-website-warning": "Alle bijhorende statistieken van deze website worden verwijderd, maar jouw volgcode blijft gelden.",
"message.saved": "Opslaan succesvol.", "message.saved": "Opslaan succesvol.",
"message.share-url": "Met deze URL kan {target} openbaar gedeeld worden.", "message.share-url": "Met deze URL kan {target} openbaar gedeeld worden.",
"message.team-already-member": "You are already a member of the team.", "message.team-already-member": "Je bent al lid van het team.",
"message.team-not-found": "Team not found.", "message.team-not-found": "Team niet gevonden.",
"message.tracking-code": "Volgcode", "message.tracking-code": "Volgcode",
"message.user-deleted": "User deleted.", "message.user-deleted": "Gebruiker verwijderd.",
"message.visitor-log": "Bezoeker uit {country} met {browser} op een {os} {device}", "message.visitor-log": "Bezoeker uit {country} met {browser} op een {os} {device}",
"messages.no-team-websites": "This team does not have any websites.", "messages.no-team-websites": "Er zijn geen websites gekoppeld aan dit team.",
"messages.no-websites-configured": "Je hebt geen websites ingesteld.", "messages.no-websites-configured": "Je hebt geen websites ingesteld.",
"messages.team-websites-info": "Websites can be viewed by anyone on the team." "messages.team-websites-info": "Websites kunnen door iedereen in het team worden bekeken."
} }

View File

@ -1,27 +1,27 @@
{ {
"label.access-code": "Access code", "label.access-code": "Código de acesso",
"label.actions": "Ações", "label.actions": "Ações",
"label.activity-log": "Activity log", "label.activity-log": "Log de atividade",
"label.add-website": "Adicionar site", "label.add-website": "Adicionar site",
"label.admin": "Administrador", "label.admin": "Administrador",
"label.all": "Todos", "label.all": "Todos",
"label.all-time": "Todo o período", "label.all-time": "Todo o período",
"label.analytics": "Analytics", "label.analytics": "Estatísticas",
"label.average-visit-time": "Tempo médio da visita", "label.average-visit-time": "Tempo médio da visita",
"label.back": "Voltar", "label.back": "Voltar",
"label.bounce-rate": "Taxa de rejeição", "label.bounce-rate": "Taxa de rejeição",
"label.browsers": "Navegadores", "label.browsers": "Navegadores",
"label.cancel": "Cancelar", "label.cancel": "Cancelar",
"label.change-password": "Alterar a senha", "label.change-password": "Alterar a senha",
"label.cities": "Cities", "label.cities": "Cidades",
"label.clear-all": "Clear all", "label.clear-all": "Limpar tudo",
"label.confirm": "Confirm", "label.confirm": "Confirmar",
"label.confirm-password": "Confirme a nova senha", "label.confirm-password": "Confirme a nova senha",
"label.continue": "Continue", "label.continue": "Continuar",
"label.countries": "Países", "label.countries": "Países",
"label.create-team": "Create team", "label.create-team": "Criar time",
"label.create-user": "Create user", "label.create-user": "Criar usuário",
"label.created": "Created", "label.created": "Criado",
"label.current-password": "Senha atual", "label.current-password": "Senha atual",
"label.custom-range": "Intervalo personalizado", "label.custom-range": "Intervalo personalizado",
"label.dashboard": "Painel", "label.dashboard": "Painel",
@ -29,37 +29,37 @@
"label.date-range": "Intervalo de datas", "label.date-range": "Intervalo de datas",
"label.default-date-range": "Intervalo de datas predefinido", "label.default-date-range": "Intervalo de datas predefinido",
"label.delete": "Remover", "label.delete": "Remover",
"label.delete-team": "Delete team", "label.delete-team": "Remover time",
"label.delete-user": "Delete user", "label.delete-user": "Remover usuário",
"label.delete-website": "Remover site", "label.delete-website": "Remover site",
"label.desktop": "Computador", "label.desktop": "Computador",
"label.details": "Details", "label.details": "Detalhes",
"label.devices": "Dispositivos", "label.devices": "Dispositivos",
"label.dismiss": "Dispensar", "label.dismiss": "Dispensar",
"label.domain": "Domínio", "label.domain": "Domínio",
"label.edit": "Editar", "label.edit": "Editar",
"label.edit-dashboard": "Edit dashboard", "label.edit-dashboard": "Editar painel",
"label.enable-share-url": "Ativar link de compartilhamento", "label.enable-share-url": "Ativar link de compartilhamento",
"label.events": "Eventos", "label.events": "Eventos",
"label.filter-combined": "Combinado", "label.filter-combined": "Combinado",
"label.filter-raw": "Dados brutos", "label.filter-raw": "Dados brutos",
"label.join": "Join", "label.join": "Entrar",
"label.join-team": "Join team", "label.join-team": "Entrar no time",
"label.language": "Idioma", "label.language": "Idioma",
"label.languages": "Idiomas", "label.languages": "Idiomas",
"label.laptop": "Notebook", "label.laptop": "Notebook",
"label.last-days": "Últimos {x} dias", "label.last-days": "Últimos {x} dias",
"label.last-hours": "Últimas {x} horas", "label.last-hours": "Últimas {x} horas",
"label.leave": "Leave", "label.leave": "Sair",
"label.leave-team": "Leave team", "label.leave-team": "Sair do time",
"label.login": "Iniciar sessão", "label.login": "Iniciar sessão",
"label.logout": "Sair", "label.logout": "Sair",
"label.members": "Members", "label.members": "Membros",
"label.mobile": "Celular", "label.mobile": "Celular",
"label.more": "Mais", "label.more": "Mais",
"label.name": "Nome", "label.name": "Nome",
"label.new-password": "Nova senha", "label.new-password": "Nova senha",
"label.none": "None", "label.none": "Nenhum",
"label.operating-systems": "Sistemas operacionais", "label.operating-systems": "Sistemas operacionais",
"label.owner": "Proprietário", "label.owner": "Proprietário",
"label.page-views": "Visualizações de página", "label.page-views": "Visualizações de página",
@ -67,80 +67,80 @@
"label.password": "Senha", "label.password": "Senha",
"label.powered-by": "Distribuído por {name}", "label.powered-by": "Distribuído por {name}",
"label.profile": "Perfil", "label.profile": "Perfil",
"label.queries": "Queries", "label.queries": "Parâmetros",
"label.query-parameters": "Parâmetros de Consulta", "label.query-parameters": "Parâmetros de Consulta",
"label.realtime": "Tempo real", "label.realtime": "Tempo real",
"label.referrers": "Referências", "label.referrers": "Referências",
"label.refresh": "Atualizar", "label.refresh": "Atualizar",
"label.regenerate": "Regenerate", "label.regenerate": "Regerar",
"label.regions": "Regions", "label.regions": "Regiões",
"label.remove": "Remove", "label.remove": "Remover",
"label.required": "Obrigatório", "label.required": "Obrigatório",
"label.reset": "Redefinir", "label.reset": "Redefinir",
"label.reset-website": "Redefinir estatísticas", "label.reset-website": "Redefinir estatísticas",
"label.role": "Role", "label.role": "Papel",
"label.save": "Salvar", "label.save": "Salvar",
"label.screens": "Telas", "label.screens": "Telas",
"label.select-website": "Select website", "label.select-website": "Selecionar site",
"label.sessions": "Sessions", "label.sessions": "Sessões",
"label.settings": "Configurações", "label.settings": "Configurações",
"label.share-url": "Link de compartilhamento", "label.share-url": "Link de compartilhamento",
"label.single-day": "Dia específico", "label.single-day": "Dia específico",
"label.tablet": "Tablet", "label.tablet": "Tablet",
"label.team": "Team", "label.team": "Time",
"label.team-guest": "Team guest", "label.team-guest": "Convidado",
"label.team-id": "Team ID", "label.team-id": "ID do Time",
"label.team-member": "Team member", "label.team-member": "Membro",
"label.team-owner": "Team owner", "label.team-owner": "Proprietário",
"label.teams": "Teams", "label.teams": "Times",
"label.theme": "Tema", "label.theme": "Tema",
"label.this-month": "Este mês", "label.this-month": "Este mês",
"label.this-week": "Esta semana", "label.this-week": "Esta semana",
"label.this-year": "Este ano", "label.this-year": "Este ano",
"label.timezone": "Fuso horário", "label.timezone": "Fuso horário",
"label.title": "Title", "label.title": "Título",
"label.today": "Hoje", "label.today": "Hoje",
"label.toggle-charts": "Mostrar/Esconder gráficos", "label.toggle-charts": "Mostrar/Esconder gráficos",
"label.tracking-code": "Código de rastreamento", "label.tracking-code": "Código de rastreamento",
"label.unique-visitors": "Visitantes únicos", "label.unique-visitors": "Visitantes únicos",
"label.unknown": "Desconhecido", "label.unknown": "Desconhecido",
"label.user": "User", "label.user": "Usuário",
"label.username": "Nome de usuário", "label.username": "Nome de usuário",
"label.users": "Users", "label.users": "Usuários",
"label.view": "View", "label.view": "Ver",
"label.view-details": "Ver detalhes", "label.view-details": "Ver detalhes",
"label.views": "Visualizações", "label.views": "Visualizações",
"label.visitors": "Visitantes", "label.visitors": "Visitantes",
"label.website-id": "Website ID", "label.website-id": "ID do Site",
"label.websites": "Sites", "label.websites": "Sites",
"label.yesterday": "Ontem", "label.yesterday": "Ontem",
"message.active-users": "{x} {x, plural, one {visitante} other {visitantes}} neste momento", "message.active-users": "{x} {x, plural, one {visitante} other {visitantes}} neste momento",
"message.confirm-delete": "Deseja realmente remover {target}?", "message.confirm-delete": "Deseja realmente remover {target}?",
"message.confirm-leave": "Are you sure you want to leave {target}?", "message.confirm-leave": "Você tem certeza que deseja sair de {target}?",
"message.confirm-reset": "Você tem certeza que deseja redefinir as estatísticas de {target}?", "message.confirm-reset": "Você tem certeza que deseja redefinir as estatísticas de {target}?",
"message.delete-website": "Remover site", "message.delete-website": "Remover site",
"message.delete-website-warning": "Todos os dados associados também serão eliminados.", "message.delete-website-warning": "Todos os dados associados também serão eliminados.",
"message.error": "Ocorreu um erro.", "message.error": "Ocorreu um erro.",
"message.event-log": "{event} on {url}", "message.event-log": "{event} em {url}",
"message.go-to-settings": "Ir para as configurações", "message.go-to-settings": "Ir para as configurações",
"message.incorrect-username-password": "O nome de usuário e/ou senha está incorreto.", "message.incorrect-username-password": "O nome de usuário e/ou senha está incorreto.",
"message.invalid-domain": "Domínio inválido", "message.invalid-domain": "Domínio inválido",
"message.min-password-length": "Minimum length of {n} characters", "message.min-password-length": "Quantidade mínima de {n} caracteres",
"message.no-data-available": "Sem dados disponíveis.", "message.no-data-available": "Sem dados disponíveis.",
"message.no-match-password": "As senhas não correspondem", "message.no-match-password": "As senhas não correspondem",
"message.no-teams": "You have not created any teams.", "message.no-teams": "Você não criou nenhum time.",
"message.no-users": "There are no users.", "message.no-users": "Não há nenhum usuário.",
"message.page-not-found": "Página não encontrada.", "message.page-not-found": "Página não encontrada.",
"message.reset-website": "Redefinir estatísticas", "message.reset-website": "Redefinir estatísticas",
"message.reset-website-warning": "Todas as estatísticas deste site serão removidas, mas seu código de rastreamento permanecerá intacto.", "message.reset-website-warning": "Todas as estatísticas deste site serão removidas, mas seu código de rastreamento permanecerá intacto.",
"message.saved": "Salvo com sucesso.", "message.saved": "Salvo com sucesso.",
"message.share-url": "Este é o link público de compartilhamento para {target}.", "message.share-url": "Este é o link público de compartilhamento para {target}.",
"message.team-already-member": "You are already a member of the team.", "message.team-already-member": "Você já um membro do time.",
"message.team-not-found": "Team not found.", "message.team-not-found": "Time não encontrado.",
"message.tracking-code": "Código de rastreamento", "message.tracking-code": "Código de rastreamento",
"message.user-deleted": "User deleted.", "message.user-deleted": "Usuário removido.",
"message.visitor-log": "Visitante de {country} usando {browser} no {device} {os}", "message.visitor-log": "Visitante de {country} usando {browser} no {device} {os}",
"messages.no-team-websites": "This team does not have any websites.", "messages.no-team-websites": "Este time não possui nenhum site.",
"messages.no-websites-configured": "Nenhum site foi configurado ainda.", "messages.no-websites-configured": "Nenhum site foi configurado ainda.",
"messages.team-websites-info": "Websites can be viewed by anyone on the team." "messages.team-websites-info": "Os sites podem ser visualizados por qualquer membro da equipe."
} }

View File

@ -2,35 +2,7 @@ import { User, Website } from '@prisma/client';
import redis from '@umami/redis-client'; import redis from '@umami/redis-client';
import { getSession, getUser, getWebsite } from '../queries'; import { getSession, getUser, getWebsite } from '../queries';
const DELETED = 'DELETED'; const { fetchObject, storeObject, deleteObject } = redis;
async function fetchObject(key, query) {
const obj = await redis.get(key);
if (obj === DELETED) {
return null;
}
if (!obj) {
return query().then(async data => {
if (data) {
await redis.set(key, data);
}
return data;
});
}
return obj;
}
async function storeObject(key, data) {
return redis.set(key, data);
}
async function deleteObject(key, soft = false) {
return soft ? redis.set(key, DELETED) : redis.del(key);
}
async function fetchWebsite(id): Promise<Website> { async function fetchWebsite(id): Promise<Website> {
return fetchObject(`website:${id}`, () => getWebsite({ id })); return fetchObject(`website:${id}`, () => getWebsite({ id }));
@ -77,6 +49,11 @@ async function deleteSession(id) {
return deleteObject(`session:${id}`); return deleteObject(`session:${id}`);
} }
async function fetchUserBlock(userId: string) {
const key = `user:block:${userId}`;
return redis.get(key);
}
export default { export default {
fetchWebsite, fetchWebsite,
storeWebsite, storeWebsite,
@ -87,5 +64,6 @@ export default {
fetchSession, fetchSession,
storeSession, storeSession,
deleteSession, deleteSession,
fetchUserBlock,
enabled: redis.enabled, enabled: redis.enabled,
}; };

View File

@ -1,4 +1,10 @@
import { createMiddleware, unauthorized, badRequest, parseSecureToken } from 'next-basics'; import {
createMiddleware,
unauthorized,
badRequest,
parseSecureToken,
tooManyRequest,
} from 'next-basics';
import debug from 'debug'; import debug from 'debug';
import cors from 'cors'; import cors from 'cors';
import { validate } from 'uuid'; import { validate } from 'uuid';
@ -30,6 +36,9 @@ export const useSession = createMiddleware(async (req, res, next) => {
(req as any).session = session; (req as any).session = session;
} catch (e: any) { } catch (e: any) {
if (e.message === 'Usage Limit.') {
return tooManyRequest(res, e.message);
}
return badRequest(res, e.message); return badRequest(res, e.message);
} }

View File

@ -6,6 +6,7 @@ import { CollectRequestBody, NextApiRequestCollect } from 'pages/api/send';
import { createSession } from 'queries'; import { createSession } from 'queries';
import { validate } from 'uuid'; import { validate } from 'uuid';
import { loadSession, loadWebsite } from './query'; import { loadSession, loadWebsite } from './query';
import cache from './cache';
export async function findSession(req: NextApiRequestCollect) { export async function findSession(req: NextApiRequestCollect) {
const { payload } = getJsonBody<CollectRequestBody>(req); const { payload } = getJsonBody<CollectRequestBody>(req);
@ -21,6 +22,8 @@ export async function findSession(req: NextApiRequestCollect) {
const result = await parseToken(cacheToken, secret()); const result = await parseToken(cacheToken, secret());
if (result) { if (result) {
await checkUserBlock(result?.ownerId);
return result; return result;
} }
} }
@ -39,6 +42,8 @@ export async function findSession(req: NextApiRequestCollect) {
throw new Error(`Website not found: ${websiteId}.`); throw new Error(`Website not found: ${websiteId}.`);
} }
await checkUserBlock(website.userId);
const { userAgent, browser, os, ip, country, subdivision1, subdivision2, city, device } = const { userAgent, browser, os, ip, country, subdivision1, subdivision2, city, device } =
await getClientInfo(req, payload); await getClientInfo(req, payload);
const sessionId = uuid(websiteId, hostname, ip, userAgent); const sessionId = uuid(websiteId, hostname, ip, userAgent);
@ -88,5 +93,11 @@ export async function findSession(req: NextApiRequestCollect) {
} }
} }
return session; return { ...session, ownerId: website.userId };
}
async function checkUserBlock(userId: string) {
if (process.env.ENABLE_BLOCKER && (await cache.fetchUserBlock(userId))) {
throw new Error('Usage Limit.');
}
} }

View File

@ -62,7 +62,7 @@
"@prisma/client": "4.13.0", "@prisma/client": "4.13.0",
"@tanstack/react-query": "^4.16.1", "@tanstack/react-query": "^4.16.1",
"@umami/prisma-client": "^0.2.0", "@umami/prisma-client": "^0.2.0",
"@umami/redis-client": "^0.2.0", "@umami/redis-client": "^0.5.0",
"chalk": "^4.1.1", "chalk": "^4.1.1",
"chart.js": "^4.2.1", "chart.js": "^4.2.1",
"chartjs-adapter-date-fns": "^3.0.0", "chartjs-adapter-date-fns": "^3.0.0",

View File

@ -28,6 +28,7 @@ export interface NextApiRequestCollect extends NextApiRequest {
session: { session: {
id: string; id: string;
websiteId: string; websiteId: string;
ownerId: string;
hostname: string; hostname: string;
browser: string; browser: string;
os: string; os: string;

View File

@ -51,11 +51,11 @@ export default async (
data.password = hashPassword(password); data.password = hashPassword(password);
} }
// Only admin can change these fields
if (role && isAdmin) { if (role && isAdmin) {
data.role = role; data.role = role;
} }
// Only admin can change these fields
if (username && isAdmin) { if (username && isAdmin) {
data.username = username; data.username = username;
} }

View File

@ -1,8 +1,8 @@
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, serverError, unauthorized } from 'next-basics';
import { Website, NextApiRequestQueryBody } from 'lib/types'; import { Website, NextApiRequestQueryBody } from 'lib/types';
import { canViewWebsite, canUpdateWebsite, canDeleteWebsite } from 'lib/auth'; import { canViewWebsite, canUpdateWebsite, canDeleteWebsite } from 'lib/auth';
import { useAuth, useCors } from 'lib/middleware'; import { useAuth, useCors } from 'lib/middleware';
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, serverError, unauthorized } from 'next-basics';
import { deleteWebsite, getWebsite, updateWebsite } from 'queries'; import { deleteWebsite, getWebsite, updateWebsite } from 'queries';
export interface WebsiteRequestQuery { export interface WebsiteRequestQuery {

View File

@ -10,7 +10,7 @@ export default function RealtimeDetailsPage() {
const { formatMessage, labels } = useMessages(); const { formatMessage, labels } = useMessages();
const { get, useQuery } = useApi(); const { get, useQuery } = useApi();
const { data: website } = useQuery(['websites', websiteId], () => const { data: website } = useQuery(['websites', websiteId], () =>
get(`/websites/${websiteId}`, { enabled: !!websiteId }), websiteId ? get(`/websites/${websiteId}`, { enabled: !!websiteId }) : null,
); );
const title = `${formatMessage(labels.realtime)}${website?.name ? ` - ${website.name}` : ''}`; const title = `${formatMessage(labels.realtime)}${website?.name ? ` - ${website.name}` : ''}`;

View File

@ -2,7 +2,7 @@
"label.access-code": [ "label.access-code": [
{ {
"type": 0, "type": 0,
"value": "Access code" "value": "Zuegangscode"
} }
], ],
"label.actions": [ "label.actions": [
@ -14,7 +14,7 @@
"label.activity-log": [ "label.activity-log": [
{ {
"type": 0, "type": 0,
"value": "Activity log" "value": "Aktivitätsverlauf"
} }
], ],
"label.add-website": [ "label.add-website": [
@ -86,19 +86,19 @@
"label.cities": [ "label.cities": [
{ {
"type": 0, "type": 0,
"value": "Cities" "value": "Städt"
} }
], ],
"label.clear-all": [ "label.clear-all": [
{ {
"type": 0, "type": 0,
"value": "Clear all" "value": "Alles lösche"
} }
], ],
"label.confirm": [ "label.confirm": [
{ {
"type": 0, "type": 0,
"value": "Confirm" "value": "Bestätige"
} }
], ],
"label.confirm-password": [ "label.confirm-password": [
@ -110,7 +110,7 @@
"label.continue": [ "label.continue": [
{ {
"type": 0, "type": 0,
"value": "Continue" "value": "Wiiter"
} }
], ],
"label.countries": [ "label.countries": [
@ -122,19 +122,19 @@
"label.create-team": [ "label.create-team": [
{ {
"type": 0, "type": 0,
"value": "Create team" "value": "Team erstelle"
} }
], ],
"label.create-user": [ "label.create-user": [
{ {
"type": 0, "type": 0,
"value": "Create user" "value": "Benutzer erstelle"
} }
], ],
"label.created": [ "label.created": [
{ {
"type": 0, "type": 0,
"value": "Created" "value": "Erstellt"
} }
], ],
"label.current-password": [ "label.current-password": [
@ -158,7 +158,7 @@
"label.data": [ "label.data": [
{ {
"type": 0, "type": 0,
"value": "Data" "value": "Datä"
} }
], ],
"label.date-range": [ "label.date-range": [
@ -182,13 +182,13 @@
"label.delete-team": [ "label.delete-team": [
{ {
"type": 0, "type": 0,
"value": "Delete team" "value": "Team lösche"
} }
], ],
"label.delete-user": [ "label.delete-user": [
{ {
"type": 0, "type": 0,
"value": "Delete user" "value": "Benutzer lösche"
} }
], ],
"label.delete-website": [ "label.delete-website": [
@ -266,13 +266,13 @@
"label.join": [ "label.join": [
{ {
"type": 0, "type": 0,
"value": "Join" "value": "Biträte"
} }
], ],
"label.join-team": [ "label.join-team": [
{ {
"type": 0, "type": 0,
"value": "Join team" "value": "Team biträte"
} }
], ],
"label.language": [ "label.language": [
@ -324,19 +324,19 @@
"label.leave": [ "label.leave": [
{ {
"type": 0, "type": 0,
"value": "Leave" "value": "Verlah"
} }
], ],
"label.leave-team": [ "label.leave-team": [
{ {
"type": 0, "type": 0,
"value": "Leave team" "value": "Team verlah"
} }
], ],
"label.login": [ "label.login": [
{ {
"type": 0, "type": 0,
"value": "Login" "value": "Aamelde"
} }
], ],
"label.logout": [ "label.logout": [
@ -348,7 +348,7 @@
"label.members": [ "label.members": [
{ {
"type": 0, "type": 0,
"value": "Members" "value": "Mitglieder"
} }
], ],
"label.mobile": [ "label.mobile": [
@ -384,7 +384,7 @@
"label.operating-systems": [ "label.operating-systems": [
{ {
"type": 0, "type": 0,
"value": "Betriebssystem" "value": "Betriibssystem"
} }
], ],
"label.owner": [ "label.owner": [
@ -430,7 +430,7 @@
"label.queries": [ "label.queries": [
{ {
"type": 0, "type": 0,
"value": "Queries" "value": "Abfrage"
} }
], ],
"label.query-parameters": [ "label.query-parameters": [
@ -460,19 +460,19 @@
"label.regenerate": [ "label.regenerate": [
{ {
"type": 0, "type": 0,
"value": "Regenerate" "value": "Erneuere"
} }
], ],
"label.regions": [ "label.regions": [
{ {
"type": 0, "type": 0,
"value": "Regions" "value": "Regionä"
} }
], ],
"label.remove": [ "label.remove": [
{ {
"type": 0, "type": 0,
"value": "Remove" "value": "Entferne"
} }
], ],
"label.required": [ "label.required": [
@ -496,7 +496,7 @@
"label.role": [ "label.role": [
{ {
"type": 0, "type": 0,
"value": "Role" "value": "Rol"
} }
], ],
"label.save": [ "label.save": [
@ -514,7 +514,7 @@
"label.select-website": [ "label.select-website": [
{ {
"type": 0, "type": 0,
"value": "Select website" "value": "Websiite uuswähle"
} }
], ],
"label.sessions": [ "label.sessions": [
@ -556,7 +556,7 @@
"label.team-guest": [ "label.team-guest": [
{ {
"type": 0, "type": 0,
"value": "Team guest" "value": "Team Gast"
} }
], ],
"label.team-id": [ "label.team-id": [
@ -568,13 +568,13 @@
"label.team-member": [ "label.team-member": [
{ {
"type": 0, "type": 0,
"value": "Team member" "value": "Team Mitglied"
} }
], ],
"label.team-owner": [ "label.team-owner": [
{ {
"type": 0, "type": 0,
"value": "Team owner" "value": "Team Bsitzer"
} }
], ],
"label.teams": [ "label.teams": [
@ -610,13 +610,13 @@
"label.timezone": [ "label.timezone": [
{ {
"type": 0, "type": 0,
"value": "Zitzone" "value": "Ziitzone"
} }
], ],
"label.title": [ "label.title": [
{ {
"type": 0, "type": 0,
"value": "Title" "value": "Titel"
} }
], ],
"label.today": [ "label.today": [
@ -652,7 +652,7 @@
"label.user": [ "label.user": [
{ {
"type": 0, "type": 0,
"value": "User" "value": "Benutzer"
} }
], ],
"label.username": [ "label.username": [
@ -664,13 +664,13 @@
"label.users": [ "label.users": [
{ {
"type": 0, "type": 0,
"value": "Users" "value": "Benutzer"
} }
], ],
"label.view": [ "label.view": [
{ {
"type": 0, "type": 0,
"value": "View" "value": "Azeige"
} }
], ],
"label.view-details": [ "label.view-details": [
@ -694,7 +694,7 @@
"label.website-id": [ "label.website-id": [
{ {
"type": 0, "type": 0,
"value": "Website ID" "value": "Websiite ID"
} }
], ],
"label.websites": [ "label.websites": [
@ -760,7 +760,7 @@
"message.confirm-leave": [ "message.confirm-leave": [
{ {
"type": 0, "type": 0,
"value": "Are you sure you want to leave " "value": "Sind Sie sich sicher, "
}, },
{ {
"type": 1, "type": 1,
@ -768,7 +768,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": "?" "value": " zverlah?"
} }
], ],
"message.confirm-reset": [ "message.confirm-reset": [
@ -810,7 +810,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": " on " "value": " uf "
}, },
{ {
"type": 1, "type": 1,
@ -838,7 +838,7 @@
"message.min-password-length": [ "message.min-password-length": [
{ {
"type": 0, "type": 0,
"value": "Minimum length of " "value": "Miminamli längi vo "
}, },
{ {
"type": 1, "type": 1,
@ -846,7 +846,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": " characters" "value": " Zeiche"
} }
], ],
"message.no-data-available": [ "message.no-data-available": [
@ -864,13 +864,13 @@
"message.no-teams": [ "message.no-teams": [
{ {
"type": 0, "type": 0,
"value": "You have not created any teams." "value": "Bisher sind no kei Teams erstellt worde."
} }
], ],
"message.no-users": [ "message.no-users": [
{ {
"type": 0, "type": 0,
"value": "There are no users." "value": "Da gits kei Benutzer"
} }
], ],
"message.page-not-found": [ "message.page-not-found": [
@ -900,27 +900,19 @@
"message.share-url": [ "message.share-url": [
{ {
"type": 0, "type": 0,
"value": "Das isch die öffentlichi URL zum Teile für " "value": "Ihri Websiitestatistik isch under de folgende URL öffentlich zuegänglich:"
},
{
"type": 1,
"value": "target"
},
{
"type": 0,
"value": "."
} }
], ],
"message.team-already-member": [ "message.team-already-member": [
{ {
"type": 0, "type": 0,
"value": "You are already a member of the team." "value": "Sie sind bereits es Mitglied vo dem Team."
} }
], ],
"message.team-not-found": [ "message.team-not-found": [
{ {
"type": 0, "type": 0,
"value": "Team not found." "value": "Team nöd gfunde."
} }
], ],
"message.tracking-code": [ "message.tracking-code": [
@ -932,7 +924,7 @@
"message.user-deleted": [ "message.user-deleted": [
{ {
"type": 0, "type": 0,
"value": "User deleted." "value": "Benutzer glöscht."
} }
], ],
"message.visitor-log": [ "message.visitor-log": [
@ -972,7 +964,7 @@
"messages.no-team-websites": [ "messages.no-team-websites": [
{ {
"type": 0, "type": 0,
"value": "This team does not have any websites." "value": "Dem Team sind kei Websiite zuegordnet."
} }
], ],
"messages.no-websites-configured": [ "messages.no-websites-configured": [
@ -984,7 +976,7 @@
"messages.team-websites-info": [ "messages.team-websites-info": [
{ {
"type": 0, "type": 0,
"value": "Websites can be viewed by anyone on the team." "value": "Websiite chönd vo jedem im Team agluegt werde"
} }
] ]
} }

View File

@ -122,13 +122,13 @@
"label.create-team": [ "label.create-team": [
{ {
"type": 0, "type": 0,
"value": "Erstelle Team" "value": "Team erstellen"
} }
], ],
"label.create-user": [ "label.create-user": [
{ {
"type": 0, "type": 0,
"value": "Erstelle Nutzer" "value": "Benutzer erstellen"
} }
], ],
"label.created": [ "label.created": [
@ -182,13 +182,13 @@
"label.delete-team": [ "label.delete-team": [
{ {
"type": 0, "type": 0,
"value": "Lösche Team" "value": "Team löschen"
} }
], ],
"label.delete-user": [ "label.delete-user": [
{ {
"type": 0, "type": 0,
"value": "Lösche Nutzer" "value": "Benutzer löschen"
} }
], ],
"label.delete-website": [ "label.delete-website": [
@ -296,7 +296,7 @@
"label.last-days": [ "label.last-days": [
{ {
"type": 0, "type": 0,
"value": "Letzten " "value": "Letzte "
}, },
{ {
"type": 1, "type": 1,
@ -310,7 +310,7 @@
"label.last-hours": [ "label.last-hours": [
{ {
"type": 0, "type": 0,
"value": "Letzten " "value": "Letzte "
}, },
{ {
"type": 1, "type": 1,
@ -466,7 +466,7 @@
"label.regions": [ "label.regions": [
{ {
"type": 0, "type": 0,
"value": "Regions" "value": "Regionen"
} }
], ],
"label.remove": [ "label.remove": [
@ -634,7 +634,7 @@
"label.tracking-code": [ "label.tracking-code": [
{ {
"type": 0, "type": 0,
"value": "Tracking Kennung" "value": "Tracking Code"
} }
], ],
"label.unique-visitors": [ "label.unique-visitors": [
@ -652,7 +652,7 @@
"label.user": [ "label.user": [
{ {
"type": 0, "type": 0,
"value": "User" "value": "Benutzer"
} }
], ],
"label.username": [ "label.username": [
@ -664,13 +664,13 @@
"label.users": [ "label.users": [
{ {
"type": 0, "type": 0,
"value": "Users" "value": "Benutzer"
} }
], ],
"label.view": [ "label.view": [
{ {
"type": 0, "type": 0,
"value": "View" "value": "Anzeigen"
} }
], ],
"label.view-details": [ "label.view-details": [
@ -694,7 +694,7 @@
"label.website-id": [ "label.website-id": [
{ {
"type": 0, "type": 0,
"value": "Website ID" "value": "Webseite ID"
} }
], ],
"label.websites": [ "label.websites": [
@ -810,7 +810,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": " on " "value": " auf "
}, },
{ {
"type": 1, "type": 1,
@ -870,7 +870,7 @@
"message.no-users": [ "message.no-users": [
{ {
"type": 0, "type": 0,
"value": "Hier gibt es keine Nutzer." "value": "Hier gibt es keine Benutzer."
} }
], ],
"message.page-not-found": [ "message.page-not-found": [
@ -900,15 +900,7 @@
"message.share-url": [ "message.share-url": [
{ {
"type": 0, "type": 0,
"value": "Dies ist die öffentliche URL zum Teilen für " "value": "Ihre Webseitenstatistik ist unter der folgenden URL öffentlich zugänglich:"
},
{
"type": 1,
"value": "target"
},
{
"type": 0,
"value": "."
} }
], ],
"message.team-already-member": [ "message.team-already-member": [
@ -926,13 +918,13 @@
"message.tracking-code": [ "message.tracking-code": [
{ {
"type": 0, "type": 0,
"value": "Tracking Kennung" "value": "Tracking Code"
} }
], ],
"message.user-deleted": [ "message.user-deleted": [
{ {
"type": 0, "type": 0,
"value": "Nutzer gelöscht." "value": "Benutzer gelöscht."
} }
], ],
"message.visitor-log": [ "message.visitor-log": [

View File

@ -2,7 +2,7 @@
"label.access-code": [ "label.access-code": [
{ {
"type": 0, "type": 0,
"value": "Access code" "value": "Хандалтын код"
} }
], ],
"label.actions": [ "label.actions": [
@ -14,7 +14,7 @@
"label.activity-log": [ "label.activity-log": [
{ {
"type": 0, "type": 0,
"value": "Activity log" "value": "Үйл ажиллагааны бүртгэл"
} }
], ],
"label.add-website": [ "label.add-website": [
@ -86,19 +86,19 @@
"label.cities": [ "label.cities": [
{ {
"type": 0, "type": 0,
"value": "Cities" "value": "Хотууд"
} }
], ],
"label.clear-all": [ "label.clear-all": [
{ {
"type": 0, "type": 0,
"value": "Clear all" "value": "Бүгдийг арилгах"
} }
], ],
"label.confirm": [ "label.confirm": [
{ {
"type": 0, "type": 0,
"value": "Confirm" "value": "Батлах"
} }
], ],
"label.confirm-password": [ "label.confirm-password": [
@ -110,7 +110,7 @@
"label.continue": [ "label.continue": [
{ {
"type": 0, "type": 0,
"value": "Continue" "value": "Үргэлжлүүлэх"
} }
], ],
"label.countries": [ "label.countries": [
@ -122,19 +122,19 @@
"label.create-team": [ "label.create-team": [
{ {
"type": 0, "type": 0,
"value": "Create team" "value": "Баг үүсгэх"
} }
], ],
"label.create-user": [ "label.create-user": [
{ {
"type": 0, "type": 0,
"value": "Create user" "value": "Хэрэглэгч үүсгэх"
} }
], ],
"label.created": [ "label.created": [
{ {
"type": 0, "type": 0,
"value": "Created" "value": "Үүсгэсэн"
} }
], ],
"label.current-password": [ "label.current-password": [
@ -158,13 +158,13 @@
"label.data": [ "label.data": [
{ {
"type": 0, "type": 0,
"value": "Data" "value": "Өгөгдөл"
} }
], ],
"label.date-range": [ "label.date-range": [
{ {
"type": 0, "type": 0,
"value": "Хугацааны мужид" "value": "Хугацааны муж"
} }
], ],
"label.default-date-range": [ "label.default-date-range": [
@ -182,13 +182,13 @@
"label.delete-team": [ "label.delete-team": [
{ {
"type": 0, "type": 0,
"value": "Delete team" "value": "Баг устгах"
} }
], ],
"label.delete-user": [ "label.delete-user": [
{ {
"type": 0, "type": 0,
"value": "Delete user" "value": "Хэрэглэгч устгах"
} }
], ],
"label.delete-website": [ "label.delete-website": [
@ -206,7 +206,7 @@
"label.details": [ "label.details": [
{ {
"type": 0, "type": 0,
"value": "Details" "value": "Мэдээлэл"
} }
], ],
"label.devices": [ "label.devices": [
@ -266,13 +266,13 @@
"label.join": [ "label.join": [
{ {
"type": 0, "type": 0,
"value": "Join" "value": "Нэгдэх"
} }
], ],
"label.join-team": [ "label.join-team": [
{ {
"type": 0, "type": 0,
"value": "Join team" "value": "Багт нэгдэх"
} }
], ],
"label.language": [ "label.language": [
@ -324,13 +324,13 @@
"label.leave": [ "label.leave": [
{ {
"type": 0, "type": 0,
"value": "Leave" "value": "Гарах"
} }
], ],
"label.leave-team": [ "label.leave-team": [
{ {
"type": 0, "type": 0,
"value": "Leave team" "value": "Багаас гарах"
} }
], ],
"label.login": [ "label.login": [
@ -348,7 +348,7 @@
"label.members": [ "label.members": [
{ {
"type": 0, "type": 0,
"value": "Members" "value": "Гишүүд"
} }
], ],
"label.mobile": [ "label.mobile": [
@ -430,7 +430,7 @@
"label.queries": [ "label.queries": [
{ {
"type": 0, "type": 0,
"value": "Queries" "value": "Query-нүүд"
} }
], ],
"label.query-parameters": [ "label.query-parameters": [
@ -460,19 +460,19 @@
"label.regenerate": [ "label.regenerate": [
{ {
"type": 0, "type": 0,
"value": "Regenerate" "value": "Дахин үүсгэх"
} }
], ],
"label.regions": [ "label.regions": [
{ {
"type": 0, "type": 0,
"value": "Regions" "value": "Бүсүүд"
} }
], ],
"label.remove": [ "label.remove": [
{ {
"type": 0, "type": 0,
"value": "Remove" "value": "Устгах"
} }
], ],
"label.required": [ "label.required": [
@ -484,7 +484,7 @@
"label.reset": [ "label.reset": [
{ {
"type": 0, "type": 0,
"value": "Хуучин хэвд нь оруулах" "value": "Дахин эхлүүлэх"
} }
], ],
"label.reset-website": [ "label.reset-website": [
@ -496,7 +496,7 @@
"label.role": [ "label.role": [
{ {
"type": 0, "type": 0,
"value": "Role" "value": "Эрх"
} }
], ],
"label.save": [ "label.save": [
@ -514,7 +514,7 @@
"label.select-website": [ "label.select-website": [
{ {
"type": 0, "type": 0,
"value": "Select website" "value": "Веб сонгох"
} }
], ],
"label.sessions": [ "label.sessions": [
@ -550,37 +550,37 @@
"label.team": [ "label.team": [
{ {
"type": 0, "type": 0,
"value": "Team" "value": "Баг"
} }
], ],
"label.team-guest": [ "label.team-guest": [
{ {
"type": 0, "type": 0,
"value": "Team guest" "value": "Багийн зочин"
} }
], ],
"label.team-id": [ "label.team-id": [
{ {
"type": 0, "type": 0,
"value": "Team ID" "value": "Багийн ID"
} }
], ],
"label.team-member": [ "label.team-member": [
{ {
"type": 0, "type": 0,
"value": "Team member" "value": "Багийн гишүүн"
} }
], ],
"label.team-owner": [ "label.team-owner": [
{ {
"type": 0, "type": 0,
"value": "Team owner" "value": "Багийн эзэмшигч"
} }
], ],
"label.teams": [ "label.teams": [
{ {
"type": 0, "type": 0,
"value": "Teams" "value": "Багууд"
} }
], ],
"label.theme": [ "label.theme": [
@ -616,7 +616,7 @@
"label.title": [ "label.title": [
{ {
"type": 0, "type": 0,
"value": "Title" "value": "Гарчиг"
} }
], ],
"label.today": [ "label.today": [
@ -652,7 +652,7 @@
"label.user": [ "label.user": [
{ {
"type": 0, "type": 0,
"value": "User" "value": "Хэрэглэгч"
} }
], ],
"label.username": [ "label.username": [
@ -664,13 +664,13 @@
"label.users": [ "label.users": [
{ {
"type": 0, "type": 0,
"value": "Users" "value": "Хэрэглэгчид"
} }
], ],
"label.view": [ "label.view": [
{ {
"type": 0, "type": 0,
"value": "View" "value": "Харах"
} }
], ],
"label.view-details": [ "label.view-details": [
@ -694,7 +694,7 @@
"label.website-id": [ "label.website-id": [
{ {
"type": 0, "type": 0,
"value": "Website ID" "value": "Вебийн ID"
} }
], ],
"label.websites": [ "label.websites": [
@ -768,7 +768,7 @@
"message.confirm-leave": [ "message.confirm-leave": [
{ {
"type": 0, "type": 0,
"value": "Are you sure you want to leave " "value": "Та "
}, },
{ {
"type": 1, "type": 1,
@ -776,7 +776,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": "?" "value": "-с гарахдаа итгэлтэй байна уу?"
} }
], ],
"message.confirm-reset": [ "message.confirm-reset": [
@ -796,13 +796,21 @@
"message.delete-website": [ "message.delete-website": [
{ {
"type": 0, "type": 0,
"value": "Веб устгах" "value": "Веб устгахын тулд доорх хэсэгт "
},
{
"type": 1,
"value": "confirmation"
},
{
"type": 0,
"value": " гэж бичиж, баталгаажуулна уу."
} }
], ],
"message.delete-website-warning": [ "message.delete-website-warning": [
{ {
"type": 0, "type": 0,
"value": "Үүнтэй холбоотой бүх өгөгдөл устах болно." "value": "Энэ вебтэй холбоотой бүх өгөгдөл устах болно."
} }
], ],
"message.error": [ "message.error": [
@ -814,15 +822,15 @@
"message.event-log": [ "message.event-log": [
{ {
"type": 1, "type": 1,
"value": "event" "value": "url"
}, },
{ {
"type": 0, "type": 0,
"value": " on " "value": " "
}, },
{ {
"type": 1, "type": 1,
"value": "url" "value": "event"
} }
], ],
"message.go-to-settings": [ "message.go-to-settings": [
@ -846,7 +854,7 @@
"message.min-password-length": [ "message.min-password-length": [
{ {
"type": 0, "type": 0,
"value": "Minimum length of " "value": "Хамгийн багадаа "
}, },
{ {
"type": 1, "type": 1,
@ -854,7 +862,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": " characters" "value": " тэмдэгт"
} }
], ],
"message.no-data-available": [ "message.no-data-available": [
@ -866,19 +874,19 @@
"message.no-match-password": [ "message.no-match-password": [
{ {
"type": 0, "type": 0,
"value": "Нууц үг тохирохгүй байна" "value": "Нууц үг тохирохгүй байна."
} }
], ],
"message.no-teams": [ "message.no-teams": [
{ {
"type": 0, "type": 0,
"value": "You have not created any teams." "value": "Та ямар ч баг үүсгээгүй байна."
} }
], ],
"message.no-users": [ "message.no-users": [
{ {
"type": 0, "type": 0,
"value": "There are no users." "value": "Хэрэглэгч байхгүй байна."
} }
], ],
"message.page-not-found": [ "message.page-not-found": [
@ -890,7 +898,15 @@
"message.reset-website": [ "message.reset-website": [
{ {
"type": 0, "type": 0,
"value": "Тоон үзүүлэлтийг дахин эхлүүлэх" "value": "Тоон үзүүлэлийг дахин эхлүүлэхийн тулд доорх хэсэгт "
},
{
"type": 1,
"value": "confirmation"
},
{
"type": 0,
"value": " гэж бичиж, баталгаажуулна уу."
} }
], ],
"message.reset-website-warning": [ "message.reset-website-warning": [
@ -902,41 +918,51 @@
"message.saved": [ "message.saved": [
{ {
"type": 0, "type": 0,
"value": "Амжилттай хадгаллаа." "value": "Хадгалсан."
} }
], ],
"message.share-url": [ "message.share-url": [
{
"type": 1,
"value": "target"
},
{ {
"type": 0, "type": 0,
"value": "-г нийтэд хуваалцах холбоос." "value": "Таны вебийн тоон үзүүлэлтүүд доорх URL дээр нийтэд харагдах болно:"
} }
], ],
"message.team-already-member": [ "message.team-already-member": [
{ {
"type": 0, "type": 0,
"value": "You are already a member of the team." "value": "Та аль хэдийн энэ багийн гишүүн болсон байна."
} }
], ],
"message.team-not-found": [ "message.team-not-found": [
{ {
"type": 0, "type": 0,
"value": "Team not found." "value": "Баг олдсонгүй."
} }
], ],
"message.tracking-code": [ "message.tracking-code": [
{ {
"type": 0, "type": 0,
"value": "Мөрдөх код" "value": "Энэ вебийн хандалтуудыг мөрдөхийн тулд доорх кодыг HTML-нхээ "
},
{
"children": [
{
"type": 0,
"value": "..."
}
],
"type": 8,
"value": "head"
},
{
"type": 0,
"value": " хэсэгт байрлуулна уу."
} }
], ],
"message.user-deleted": [ "message.user-deleted": [
{ {
"type": 0, "type": 0,
"value": "User deleted." "value": "Хэрэглэгч устсан."
} }
], ],
"message.visitor-log": [ "message.visitor-log": [
@ -976,7 +1002,7 @@
"messages.no-team-websites": [ "messages.no-team-websites": [
{ {
"type": 0, "type": 0,
"value": "This team does not have any websites." "value": "Энэ багт ямар ч веб алга."
} }
], ],
"messages.no-websites-configured": [ "messages.no-websites-configured": [
@ -988,7 +1014,7 @@
"messages.team-websites-info": [ "messages.team-websites-info": [
{ {
"type": 0, "type": 0,
"value": "Websites can be viewed by anyone on the team." "value": "Вебийг багийн бүх гишүүд үзэж болно."
} }
] ]
} }

View File

@ -2,7 +2,7 @@
"label.access-code": [ "label.access-code": [
{ {
"type": 0, "type": 0,
"value": "Access code" "value": "Toegangscode"
} }
], ],
"label.actions": [ "label.actions": [
@ -14,19 +14,19 @@
"label.activity-log": [ "label.activity-log": [
{ {
"type": 0, "type": 0,
"value": "Activity log" "value": "Activiteiten logboek"
} }
], ],
"label.add-website": [ "label.add-website": [
{ {
"type": 0, "type": 0,
"value": "Website toevoegen" "value": "Website koppelen"
} }
], ],
"label.admin": [ "label.admin": [
{ {
"type": 0, "type": 0,
"value": "Administrator" "value": "Beheerder"
} }
], ],
"label.all": [ "label.all": [
@ -86,19 +86,19 @@
"label.cities": [ "label.cities": [
{ {
"type": 0, "type": 0,
"value": "Cities" "value": "Steden"
} }
], ],
"label.clear-all": [ "label.clear-all": [
{ {
"type": 0, "type": 0,
"value": "Clear all" "value": "Filters wissen"
} }
], ],
"label.confirm": [ "label.confirm": [
{ {
"type": 0, "type": 0,
"value": "Confirm" "value": "Bevestigen"
} }
], ],
"label.confirm-password": [ "label.confirm-password": [
@ -110,7 +110,7 @@
"label.continue": [ "label.continue": [
{ {
"type": 0, "type": 0,
"value": "Continue" "value": "Doorgaan"
} }
], ],
"label.countries": [ "label.countries": [
@ -122,19 +122,19 @@
"label.create-team": [ "label.create-team": [
{ {
"type": 0, "type": 0,
"value": "Create team" "value": "Team aanmaken"
} }
], ],
"label.create-user": [ "label.create-user": [
{ {
"type": 0, "type": 0,
"value": "Create user" "value": "Gebruiker maken"
} }
], ],
"label.created": [ "label.created": [
{ {
"type": 0, "type": 0,
"value": "Created" "value": "Gemaakt"
} }
], ],
"label.current-password": [ "label.current-password": [
@ -158,7 +158,7 @@
"label.data": [ "label.data": [
{ {
"type": 0, "type": 0,
"value": "Data" "value": "Gegevens"
} }
], ],
"label.date-range": [ "label.date-range": [
@ -182,13 +182,13 @@
"label.delete-team": [ "label.delete-team": [
{ {
"type": 0, "type": 0,
"value": "Delete team" "value": "Team verwijderen"
} }
], ],
"label.delete-user": [ "label.delete-user": [
{ {
"type": 0, "type": 0,
"value": "Delete user" "value": "Verwijder gebruiker"
} }
], ],
"label.delete-website": [ "label.delete-website": [
@ -200,13 +200,13 @@
"label.desktop": [ "label.desktop": [
{ {
"type": 0, "type": 0,
"value": "Desktop" "value": "Computer"
} }
], ],
"label.details": [ "label.details": [
{ {
"type": 0, "type": 0,
"value": "Details" "value": "Informatie"
} }
], ],
"label.devices": [ "label.devices": [
@ -236,7 +236,7 @@
"label.edit-dashboard": [ "label.edit-dashboard": [
{ {
"type": 0, "type": 0,
"value": "Edit dashboard" "value": "Dashboard aanpassen"
} }
], ],
"label.enable-share-url": [ "label.enable-share-url": [
@ -266,13 +266,13 @@
"label.join": [ "label.join": [
{ {
"type": 0, "type": 0,
"value": "Join" "value": "Lid worden"
} }
], ],
"label.join-team": [ "label.join-team": [
{ {
"type": 0, "type": 0,
"value": "Join team" "value": "Word lid van een team"
} }
], ],
"label.language": [ "label.language": [
@ -284,7 +284,7 @@
"label.languages": [ "label.languages": [
{ {
"type": 0, "type": 0,
"value": "Languages" "value": "Talen"
} }
], ],
"label.laptop": [ "label.laptop": [
@ -324,13 +324,13 @@
"label.leave": [ "label.leave": [
{ {
"type": 0, "type": 0,
"value": "Leave" "value": "Verlaten"
} }
], ],
"label.leave-team": [ "label.leave-team": [
{ {
"type": 0, "type": 0,
"value": "Leave team" "value": "Verlaat team"
} }
], ],
"label.login": [ "label.login": [
@ -348,7 +348,7 @@
"label.members": [ "label.members": [
{ {
"type": 0, "type": 0,
"value": "Members" "value": "Gebruikers"
} }
], ],
"label.mobile": [ "label.mobile": [
@ -430,13 +430,13 @@
"label.queries": [ "label.queries": [
{ {
"type": 0, "type": 0,
"value": "Queries" "value": "Parameters"
} }
], ],
"label.query-parameters": [ "label.query-parameters": [
{ {
"type": 0, "type": 0,
"value": "Query parameters" "value": "URL-parameters"
} }
], ],
"label.realtime": [ "label.realtime": [
@ -460,19 +460,19 @@
"label.regenerate": [ "label.regenerate": [
{ {
"type": 0, "type": 0,
"value": "Regenerate" "value": "Opnieuw genereren"
} }
], ],
"label.regions": [ "label.regions": [
{ {
"type": 0, "type": 0,
"value": "Regions" "value": "Regio's"
} }
], ],
"label.remove": [ "label.remove": [
{ {
"type": 0, "type": 0,
"value": "Remove" "value": "Verwijderen"
} }
], ],
"label.required": [ "label.required": [
@ -484,7 +484,7 @@
"label.reset": [ "label.reset": [
{ {
"type": 0, "type": 0,
"value": "Resetten" "value": "Opnieuw instellen"
} }
], ],
"label.reset-website": [ "label.reset-website": [
@ -496,7 +496,7 @@
"label.role": [ "label.role": [
{ {
"type": 0, "type": 0,
"value": "Role" "value": "Gebruikersrol"
} }
], ],
"label.save": [ "label.save": [
@ -514,13 +514,13 @@
"label.select-website": [ "label.select-website": [
{ {
"type": 0, "type": 0,
"value": "Select website" "value": "Website selecteren"
} }
], ],
"label.sessions": [ "label.sessions": [
{ {
"type": 0, "type": 0,
"value": "Sessions" "value": "Sessies"
} }
], ],
"label.settings": [ "label.settings": [
@ -556,7 +556,7 @@
"label.team-guest": [ "label.team-guest": [
{ {
"type": 0, "type": 0,
"value": "Team guest" "value": "Team gast"
} }
], ],
"label.team-id": [ "label.team-id": [
@ -568,13 +568,13 @@
"label.team-member": [ "label.team-member": [
{ {
"type": 0, "type": 0,
"value": "Team member" "value": "Teamlid"
} }
], ],
"label.team-owner": [ "label.team-owner": [
{ {
"type": 0, "type": 0,
"value": "Team owner" "value": "Teameigenaar"
} }
], ],
"label.teams": [ "label.teams": [
@ -616,7 +616,7 @@
"label.title": [ "label.title": [
{ {
"type": 0, "type": 0,
"value": "Title" "value": "Titel"
} }
], ],
"label.today": [ "label.today": [
@ -652,7 +652,7 @@
"label.user": [ "label.user": [
{ {
"type": 0, "type": 0,
"value": "User" "value": "Gebruiker"
} }
], ],
"label.username": [ "label.username": [
@ -664,13 +664,13 @@
"label.users": [ "label.users": [
{ {
"type": 0, "type": 0,
"value": "Users" "value": "Gebruikers"
} }
], ],
"label.view": [ "label.view": [
{ {
"type": 0, "type": 0,
"value": "View" "value": "Weergave"
} }
], ],
"label.view-details": [ "label.view-details": [
@ -706,7 +706,7 @@
"label.yesterday": [ "label.yesterday": [
{ {
"type": 0, "type": 0,
"value": "Yesterday" "value": "Gisteren"
} }
], ],
"message.active-users": [ "message.active-users": [
@ -760,7 +760,7 @@
"message.confirm-leave": [ "message.confirm-leave": [
{ {
"type": 0, "type": 0,
"value": "Are you sure you want to leave " "value": "Weet je zeker dat je "
}, },
{ {
"type": 1, "type": 1,
@ -768,7 +768,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": "?" "value": " wilt verlaten?"
} }
], ],
"message.confirm-reset": [ "message.confirm-reset": [
@ -810,7 +810,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": " on " "value": " op "
}, },
{ {
"type": 1, "type": 1,
@ -838,7 +838,7 @@
"message.min-password-length": [ "message.min-password-length": [
{ {
"type": 0, "type": 0,
"value": "Minimum length of " "value": "Minimale lengte van "
}, },
{ {
"type": 1, "type": 1,
@ -846,7 +846,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": " characters" "value": " tekens"
} }
], ],
"message.no-data-available": [ "message.no-data-available": [
@ -864,13 +864,13 @@
"message.no-teams": [ "message.no-teams": [
{ {
"type": 0, "type": 0,
"value": "You have not created any teams." "value": "Er zijn nog geen teams aangemaakt."
} }
], ],
"message.no-users": [ "message.no-users": [
{ {
"type": 0, "type": 0,
"value": "There are no users." "value": "Er zijn geen gebruikers."
} }
], ],
"message.page-not-found": [ "message.page-not-found": [
@ -914,13 +914,13 @@
"message.team-already-member": [ "message.team-already-member": [
{ {
"type": 0, "type": 0,
"value": "You are already a member of the team." "value": "Je bent al lid van het team."
} }
], ],
"message.team-not-found": [ "message.team-not-found": [
{ {
"type": 0, "type": 0,
"value": "Team not found." "value": "Team niet gevonden."
} }
], ],
"message.tracking-code": [ "message.tracking-code": [
@ -932,7 +932,7 @@
"message.user-deleted": [ "message.user-deleted": [
{ {
"type": 0, "type": 0,
"value": "User deleted." "value": "Gebruiker verwijderd."
} }
], ],
"message.visitor-log": [ "message.visitor-log": [
@ -972,7 +972,7 @@
"messages.no-team-websites": [ "messages.no-team-websites": [
{ {
"type": 0, "type": 0,
"value": "This team does not have any websites." "value": "Er zijn geen websites gekoppeld aan dit team."
} }
], ],
"messages.no-websites-configured": [ "messages.no-websites-configured": [
@ -984,7 +984,7 @@
"messages.team-websites-info": [ "messages.team-websites-info": [
{ {
"type": 0, "type": 0,
"value": "Websites can be viewed by anyone on the team." "value": "Websites kunnen door iedereen in het team worden bekeken."
} }
] ]
} }

View File

@ -2,7 +2,7 @@
"label.access-code": [ "label.access-code": [
{ {
"type": 0, "type": 0,
"value": "Access code" "value": "Código de acesso"
} }
], ],
"label.actions": [ "label.actions": [
@ -14,7 +14,7 @@
"label.activity-log": [ "label.activity-log": [
{ {
"type": 0, "type": 0,
"value": "Activity log" "value": "Log de atividade"
} }
], ],
"label.add-website": [ "label.add-website": [
@ -44,7 +44,7 @@
"label.analytics": [ "label.analytics": [
{ {
"type": 0, "type": 0,
"value": "Analytics" "value": "Estatísticas"
} }
], ],
"label.average-visit-time": [ "label.average-visit-time": [
@ -86,19 +86,19 @@
"label.cities": [ "label.cities": [
{ {
"type": 0, "type": 0,
"value": "Cities" "value": "Cidades"
} }
], ],
"label.clear-all": [ "label.clear-all": [
{ {
"type": 0, "type": 0,
"value": "Clear all" "value": "Limpar tudo"
} }
], ],
"label.confirm": [ "label.confirm": [
{ {
"type": 0, "type": 0,
"value": "Confirm" "value": "Confirmar"
} }
], ],
"label.confirm-password": [ "label.confirm-password": [
@ -110,7 +110,7 @@
"label.continue": [ "label.continue": [
{ {
"type": 0, "type": 0,
"value": "Continue" "value": "Continuar"
} }
], ],
"label.countries": [ "label.countries": [
@ -122,19 +122,19 @@
"label.create-team": [ "label.create-team": [
{ {
"type": 0, "type": 0,
"value": "Create team" "value": "Criar time"
} }
], ],
"label.create-user": [ "label.create-user": [
{ {
"type": 0, "type": 0,
"value": "Create user" "value": "Criar usuário"
} }
], ],
"label.created": [ "label.created": [
{ {
"type": 0, "type": 0,
"value": "Created" "value": "Criado"
} }
], ],
"label.current-password": [ "label.current-password": [
@ -182,13 +182,13 @@
"label.delete-team": [ "label.delete-team": [
{ {
"type": 0, "type": 0,
"value": "Delete team" "value": "Remover time"
} }
], ],
"label.delete-user": [ "label.delete-user": [
{ {
"type": 0, "type": 0,
"value": "Delete user" "value": "Remover usuário"
} }
], ],
"label.delete-website": [ "label.delete-website": [
@ -206,7 +206,7 @@
"label.details": [ "label.details": [
{ {
"type": 0, "type": 0,
"value": "Details" "value": "Detalhes"
} }
], ],
"label.devices": [ "label.devices": [
@ -236,7 +236,7 @@
"label.edit-dashboard": [ "label.edit-dashboard": [
{ {
"type": 0, "type": 0,
"value": "Edit dashboard" "value": "Editar painel"
} }
], ],
"label.enable-share-url": [ "label.enable-share-url": [
@ -266,13 +266,13 @@
"label.join": [ "label.join": [
{ {
"type": 0, "type": 0,
"value": "Join" "value": "Entrar"
} }
], ],
"label.join-team": [ "label.join-team": [
{ {
"type": 0, "type": 0,
"value": "Join team" "value": "Entrar no time"
} }
], ],
"label.language": [ "label.language": [
@ -324,13 +324,13 @@
"label.leave": [ "label.leave": [
{ {
"type": 0, "type": 0,
"value": "Leave" "value": "Sair"
} }
], ],
"label.leave-team": [ "label.leave-team": [
{ {
"type": 0, "type": 0,
"value": "Leave team" "value": "Sair do time"
} }
], ],
"label.login": [ "label.login": [
@ -348,7 +348,7 @@
"label.members": [ "label.members": [
{ {
"type": 0, "type": 0,
"value": "Members" "value": "Membros"
} }
], ],
"label.mobile": [ "label.mobile": [
@ -378,7 +378,7 @@
"label.none": [ "label.none": [
{ {
"type": 0, "type": 0,
"value": "None" "value": "Nenhum"
} }
], ],
"label.operating-systems": [ "label.operating-systems": [
@ -430,7 +430,7 @@
"label.queries": [ "label.queries": [
{ {
"type": 0, "type": 0,
"value": "Queries" "value": "Parâmetros"
} }
], ],
"label.query-parameters": [ "label.query-parameters": [
@ -460,19 +460,19 @@
"label.regenerate": [ "label.regenerate": [
{ {
"type": 0, "type": 0,
"value": "Regenerate" "value": "Regerar"
} }
], ],
"label.regions": [ "label.regions": [
{ {
"type": 0, "type": 0,
"value": "Regions" "value": "Regiões"
} }
], ],
"label.remove": [ "label.remove": [
{ {
"type": 0, "type": 0,
"value": "Remove" "value": "Remover"
} }
], ],
"label.required": [ "label.required": [
@ -496,7 +496,7 @@
"label.role": [ "label.role": [
{ {
"type": 0, "type": 0,
"value": "Role" "value": "Papel"
} }
], ],
"label.save": [ "label.save": [
@ -514,13 +514,13 @@
"label.select-website": [ "label.select-website": [
{ {
"type": 0, "type": 0,
"value": "Select website" "value": "Selecionar site"
} }
], ],
"label.sessions": [ "label.sessions": [
{ {
"type": 0, "type": 0,
"value": "Sessions" "value": "Sessões"
} }
], ],
"label.settings": [ "label.settings": [
@ -550,37 +550,37 @@
"label.team": [ "label.team": [
{ {
"type": 0, "type": 0,
"value": "Team" "value": "Time"
} }
], ],
"label.team-guest": [ "label.team-guest": [
{ {
"type": 0, "type": 0,
"value": "Team guest" "value": "Convidado"
} }
], ],
"label.team-id": [ "label.team-id": [
{ {
"type": 0, "type": 0,
"value": "Team ID" "value": "ID do Time"
} }
], ],
"label.team-member": [ "label.team-member": [
{ {
"type": 0, "type": 0,
"value": "Team member" "value": "Membro"
} }
], ],
"label.team-owner": [ "label.team-owner": [
{ {
"type": 0, "type": 0,
"value": "Team owner" "value": "Proprietário"
} }
], ],
"label.teams": [ "label.teams": [
{ {
"type": 0, "type": 0,
"value": "Teams" "value": "Times"
} }
], ],
"label.theme": [ "label.theme": [
@ -616,7 +616,7 @@
"label.title": [ "label.title": [
{ {
"type": 0, "type": 0,
"value": "Title" "value": "Título"
} }
], ],
"label.today": [ "label.today": [
@ -652,7 +652,7 @@
"label.user": [ "label.user": [
{ {
"type": 0, "type": 0,
"value": "User" "value": "Usuário"
} }
], ],
"label.username": [ "label.username": [
@ -664,13 +664,13 @@
"label.users": [ "label.users": [
{ {
"type": 0, "type": 0,
"value": "Users" "value": "Usuários"
} }
], ],
"label.view": [ "label.view": [
{ {
"type": 0, "type": 0,
"value": "View" "value": "Ver"
} }
], ],
"label.view-details": [ "label.view-details": [
@ -694,7 +694,7 @@
"label.website-id": [ "label.website-id": [
{ {
"type": 0, "type": 0,
"value": "Website ID" "value": "ID do Site"
} }
], ],
"label.websites": [ "label.websites": [
@ -764,7 +764,7 @@
"message.confirm-leave": [ "message.confirm-leave": [
{ {
"type": 0, "type": 0,
"value": "Are you sure you want to leave " "value": "Você tem certeza que deseja sair de "
}, },
{ {
"type": 1, "type": 1,
@ -814,7 +814,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": " on " "value": " em "
}, },
{ {
"type": 1, "type": 1,
@ -842,7 +842,7 @@
"message.min-password-length": [ "message.min-password-length": [
{ {
"type": 0, "type": 0,
"value": "Minimum length of " "value": "Quantidade mínima de "
}, },
{ {
"type": 1, "type": 1,
@ -850,7 +850,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": " characters" "value": " caracteres"
} }
], ],
"message.no-data-available": [ "message.no-data-available": [
@ -868,13 +868,13 @@
"message.no-teams": [ "message.no-teams": [
{ {
"type": 0, "type": 0,
"value": "You have not created any teams." "value": "Você não criou nenhum time."
} }
], ],
"message.no-users": [ "message.no-users": [
{ {
"type": 0, "type": 0,
"value": "There are no users." "value": "Não há nenhum usuário."
} }
], ],
"message.page-not-found": [ "message.page-not-found": [
@ -918,13 +918,13 @@
"message.team-already-member": [ "message.team-already-member": [
{ {
"type": 0, "type": 0,
"value": "You are already a member of the team." "value": "Você já um membro do time."
} }
], ],
"message.team-not-found": [ "message.team-not-found": [
{ {
"type": 0, "type": 0,
"value": "Team not found." "value": "Time não encontrado."
} }
], ],
"message.tracking-code": [ "message.tracking-code": [
@ -936,7 +936,7 @@
"message.user-deleted": [ "message.user-deleted": [
{ {
"type": 0, "type": 0,
"value": "User deleted." "value": "Usuário removido."
} }
], ],
"message.visitor-log": [ "message.visitor-log": [
@ -976,7 +976,7 @@
"messages.no-team-websites": [ "messages.no-team-websites": [
{ {
"type": 0, "type": 0,
"value": "This team does not have any websites." "value": "Este time não possui nenhum site."
} }
], ],
"messages.no-websites-configured": [ "messages.no-websites-configured": [
@ -988,7 +988,7 @@
"messages.team-websites-info": [ "messages.team-websites-info": [
{ {
"type": 0, "type": 0,
"value": "Websites can be viewed by anyone on the team." "value": "Os sites podem ser visualizados por qualquer membro da equipe."
} }
] ]
} }

View File

@ -1,4 +1,5 @@
import { Prisma, Team, TeamUser } from '@prisma/client'; import { Prisma, Team, TeamUser } from '@prisma/client';
import { getRandomChars } from 'next-basics';
import cache from 'lib/cache'; import cache from 'lib/cache';
import { ROLES } from 'lib/constants'; import { ROLES } from 'lib/constants';
import prisma from 'lib/prisma'; import prisma from 'lib/prisma';
@ -222,6 +223,7 @@ export async function deleteUser(
cloudMode cloudMode
? client.user.update({ ? client.user.update({
data: { data: {
username: getRandomChars(32),
deletedAt: new Date(), deletedAt: new Date(),
}, },
where: { where: {

View File

@ -11,7 +11,7 @@ if (process.env.SKIP_DB_CHECK) {
} }
function getDatabaseType(url = process.env.DATABASE_URL) { function getDatabaseType(url = process.env.DATABASE_URL) {
const type = process.env.DATABASE_TYPE || (url && url.split(':')[0]); const type = url && url.split(':')[0];
if (type === 'postgres') { if (type === 'postgres') {
return 'postgresql'; return 'postgresql';
@ -20,7 +20,6 @@ function getDatabaseType(url = process.env.DATABASE_URL) {
return type; return type;
} }
const databaseType = getDatabaseType();
const prisma = new PrismaClient(); const prisma = new PrismaClient();
function success(msg) { function success(msg) {
@ -49,10 +48,11 @@ async function checkConnection() {
} }
} }
async function checkDatabaseVersion(databaseType) { async function checkDatabaseVersion() {
const query = await prisma.$queryRaw`select version() as version`; const query = await prisma.$queryRaw`select version() as version`;
const version = semver.valid(semver.coerce(query[0].version)); const version = semver.valid(semver.coerce(query[0].version));
const databaseType = getDatabaseType();
const minVersion = databaseType === 'postgresql' ? '9.4.0' : '5.7.0'; const minVersion = databaseType === 'postgresql' ? '9.4.0' : '5.7.0';
if (semver.lt(version, minVersion)) { if (semver.lt(version, minVersion)) {
@ -87,7 +87,7 @@ async function applyMigration() {
let err = false; let err = false;
for (let fn of [checkEnv, checkConnection, checkDatabaseVersion, checkV1Tables, applyMigration]) { for (let fn of [checkEnv, checkConnection, checkDatabaseVersion, checkV1Tables, applyMigration]) {
try { try {
fn.name === 'checkDatabaseVersion' ? await fn(databaseType) : await fn(); await fn();
} catch (e) { } catch (e) {
error(e.message); error(e.message);
err = true; err = true;

138
tracker/index.d.ts vendored Normal file
View File

@ -0,0 +1,138 @@
type TrackedProperties = {
/**
* Hostname of server
*
* @description extracted from `window.location.hostname`
* @example 'analytics.umami.is'
*/
hostname: string;
/**
* Browser language
*
* @description extracted from `window.navigator.language`
* @example 'en-US', 'fr-FR'
*/
language: string;
/**
* Page referrer
*
* @description extracted from `window.navigator.language`
* @example 'https://analytics.umami.is/docs/getting-started'
*/
referrer: string;
/**
* Screen dimensions
*
* @description extracted from `window.screen.width` and `window.screen.height`
* @example '1920x1080', '2560x1440'
*/
screen: string;
/**
* Page title
*
* @description extracted from `document.querySelector('head > title')`
* @example 'umami'
*/
title: string;
/**
* Page url
*
* @description built from `${window.location.pathname}${window.location.search}`
* @example 'docs/getting-started'
*/
url: string;
/**
* Website ID (required)
*
* @example 'b59e9c65-ae32-47f1-8400-119fcf4861c4'
*/
website: string;
};
type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] }
/**
*
* Event Data can work with any JSON data. There are a few rules in place to maintain performance.
* - Numbers have a max precision of 4.
* - Strings have a max length of 500.
* - Arrays are converted to a String, with the same max length of 500.
* - Objects have a max of 50 properties. Arrays are considered 1 property.
*/
type EventData = Record<string, object>;
type EventProperties = {
name: string;
data?: EventData;
} & WithRequired<TrackedProperties, 'website'>
| WithRequired<TrackedProperties, 'website'>;
interface Window {
umami: {
track: {
/**
* Track a page view
*
* @example ```
* umami.track();
* ```
*/
(): Promise<string>;
/**
* Track an event with a given name
*
* @example ```
* umami.track('signup-button');
* ```
*/
(eventName: string): Promise<string>;
/**
* Tracks an event with dynamic data.
*
* When tracking events, the default properties are included in the payload. This is equivalent to running:
*
* ```js
* umami.track(props => ({
* ...props,
* name: 'signup-button',
* data: {
* name: 'newsletter',
* id: 123
* }
* }));
* ```
*
* @example ```
* umami.track('signup-button', { name: 'newsletter', id: 123 });
* ```
*/
(eventName: string, obj: EventData): Promise<string>;
/**
* Tracks a page view with custom properties
*
* @example ```
* umami.track({ website: 'e676c9b4-11e4-4ef1-a4d7-87001773e9f2', url: '/home', title: 'Home page' });
* ```
*/
(properties: WithRequired<Partial<TrackedProperties>, 'website'>): Promise<string>;
/**
* Tracks an event with fully customizable dynamic data
* Ilf you don't specify any `name` and/or `data`, it will be treated as a page view
*
* @example ```
* umami.track((props) => ({ ...props, url: path }));
* ```
*/
(eventFunction: (prop: TrackedProperties) => EventProperties): Promise<string>;
};
};
}

View File

@ -3272,10 +3272,10 @@
dependencies: dependencies:
debug "^4.3.4" debug "^4.3.4"
"@umami/redis-client@^0.2.0": "@umami/redis-client@^0.5.0":
version "0.2.0" version "0.5.0"
resolved "https://registry.yarnpkg.com/@umami/redis-client/-/redis-client-0.2.0.tgz#bdb1cd8b5c99afc5230621f19296c6d3559d68af" resolved "https://registry.yarnpkg.com/@umami/redis-client/-/redis-client-0.5.0.tgz#09b15458001bc172fc856d65316efbe5ff749461"
integrity sha512-TONWhkuC//K2hRo3Psk7FHsuvu3XkQIYMY62/CERPtlIJz4Ac7DqsmYw4jO9/RkljA9XLl/5u+OggD4ARhMV8A== integrity sha512-x7wx/pMjyg3AAYzgjGOw031bNhyZ81h6tRMAl60RQQI9xlJaJEA1r0TEUrWfFi21gHAvdBLJGYCsvHzpix4LKQ==
dependencies: dependencies:
debug "^4.3.4" debug "^4.3.4"
redis "^4.5.1" redis "^4.5.1"