Merge branch 'dev' of https://github.com/umami-software/umami into analytics

This commit is contained in:
Francis Cao 2024-07-25 12:33:35 -07:00
commit 3494ae46b7
190 changed files with 2039 additions and 1556 deletions

View File

@ -66,4 +66,112 @@ CREATE TABLE umami.session_data
) )
engine = MergeTree engine = MergeTree
ORDER BY (website_id, session_id, data_key, created_at) ORDER BY (website_id, session_id, data_key, created_at)
SETTINGS index_granularity = 8192; SETTINGS index_granularity = 8192;
-- stats hourly
CREATE TABLE umami.website_event_stats_hourly
(
website_id UUID,
session_id UUID,
visit_id UUID,
hostname LowCardinality(String),
browser LowCardinality(String),
os LowCardinality(String),
device LowCardinality(String),
screen LowCardinality(String),
language LowCardinality(String),
country LowCardinality(String),
subdivision1 LowCardinality(String),
city String,
entry_url AggregateFunction(argMin, String, DateTime('UTC')),
exit_url AggregateFunction(argMax, String, DateTime('UTC')),
url_path SimpleAggregateFunction(groupArrayArray, Array(String)),
url_query SimpleAggregateFunction(groupArrayArray, Array(String)),
referrer_domain SimpleAggregateFunction(groupArrayArray, Array(String)),
page_title SimpleAggregateFunction(groupArrayArray, Array(String)),
event_type UInt32,
event_name SimpleAggregateFunction(groupArrayArray, Array(String)),
views SimpleAggregateFunction(sum, UInt64),
min_time SimpleAggregateFunction(min, DateTime('UTC')),
max_time SimpleAggregateFunction(max, DateTime('UTC')),
created_at Datetime('UTC')
)
ENGINE = AggregatingMergeTree
PARTITION BY toYYYYMM(created_at)
ORDER BY (
website_id,
event_type,
toStartOfHour(created_at),
cityHash64(visit_id),
visit_id
)
SAMPLE BY cityHash64(visit_id);
CREATE MATERIALIZED VIEW umami.website_event_stats_hourly_mv
TO umami.website_event_stats_hourly
AS
SELECT
website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
subdivision1,
city,
entry_url,
exit_url,
url_paths as url_path,
url_query,
referrer_domain,
page_title,
event_type,
event_name,
views,
min_time,
max_time,
timestamp as created_at
FROM (SELECT
website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
subdivision1,
city,
argMinState(url_path, created_at) entry_url,
argMaxState(url_path, created_at) exit_url,
arrayFilter(x -> x != '', groupArray(url_path)) as url_paths,
arrayFilter(x -> x != '', groupArray(url_query)) url_query,
arrayFilter(x -> x != '', groupArray(referrer_domain)) referrer_domain,
arrayFilter(x -> x != '', groupArray(page_title)) page_title,
event_type,
if(event_type = 2, groupArray(event_name), []) event_name,
sumIf(1, event_type = 1) views,
min(created_at) min_time,
max(created_at) max_time,
toStartOfHour(created_at) timestamp
FROM umami.website_event
GROUP BY website_id,
session_id,
visit_id,
hostname,
browser,
os,
device,
screen,
language,
country,
subdivision1,
city,
event_type,
timestamp);

View File

@ -168,7 +168,7 @@ const config = {
destination: '/api/scripts/telemetry', destination: '/api/scripts/telemetry',
}, },
{ {
source: '/teams/:teamId/:path*', source: '/teams/:teamId/:path((?!settings).*)*',
destination: '/:path*', destination: '/:path*',
}, },
]; ];

View File

@ -1,6 +1,6 @@
{ {
"name": "umami", "name": "umami",
"version": "2.12.0", "version": "2.12.1",
"description": "A simple, fast, privacy-focused alternative to Google Analytics.", "description": "A simple, fast, privacy-focused alternative to Google Analytics.",
"author": "Umami Software, Inc. <hello@umami.is>", "author": "Umami Software, Inc. <hello@umami.is>",
"license": "MIT", "license": "MIT",
@ -64,9 +64,9 @@
".next/cache" ".next/cache"
], ],
"dependencies": { "dependencies": {
"@clickhouse/client": "^1.0.2", "@clickhouse/client": "^1.3.0",
"@fontsource/inter": "^4.5.15", "@fontsource/inter": "^4.5.15",
"@prisma/client": "5.14.0", "@prisma/client": "5.16.2",
"@prisma/extension-read-replicas": "^0.3.0", "@prisma/extension-read-replicas": "^0.3.0",
"@react-spring/web": "^9.7.3", "@react-spring/web": "^9.7.3",
"@tanstack/react-query": "^5.28.6", "@tanstack/react-query": "^5.28.6",
@ -98,11 +98,11 @@
"maxmind": "^4.3.6", "maxmind": "^4.3.6",
"md5": "^2.3.0", "md5": "^2.3.0",
"moment-timezone": "^0.5.35", "moment-timezone": "^0.5.35",
"next": "14.2.3", "next": "14.2.4",
"next-basics": "^0.39.0", "next-basics": "^0.39.0",
"node-fetch": "^3.2.8", "node-fetch": "^3.2.8",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prisma": "5.14.0", "prisma": "5.16.2",
"react": "^18.2.0", "react": "^18.2.0",
"react-basics": "^0.123.0", "react-basics": "^0.123.0",
"react-beautiful-dnd": "^13.1.0", "react-beautiful-dnd": "^13.1.0",
@ -175,6 +175,6 @@
"tar": "^6.1.2", "tar": "^6.1.2",
"ts-jest": "^29.1.2", "ts-jest": "^29.1.2",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"typescript": "^5.4.3" "typescript": "^5.5.3"
} }
} }

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -152,7 +152,7 @@
"label.compare": [ "label.compare": [
{ {
"type": 0, "type": 0,
"value": "Compare" "value": "Comparar"
} }
], ],
"label.confirm": [ "label.confirm": [
@ -182,7 +182,7 @@
"label.count": [ "label.count": [
{ {
"type": 0, "type": 0,
"value": "Count" "value": "Recompte"
} }
], ],
"label.countries": [ "label.countries": [
@ -236,7 +236,7 @@
"label.current": [ "label.current": [
{ {
"type": 0, "type": 0,
"value": "Current" "value": "Actual"
} }
], ],
"label.current-password": [ "label.current-password": [
@ -398,13 +398,13 @@
"label.end-step": [ "label.end-step": [
{ {
"type": 0, "type": 0,
"value": "End Step" "value": "Pas Final"
} }
], ],
"label.entry": [ "label.entry": [
{ {
"type": 0, "type": 0,
"value": "Entry URL" "value": "URL d'entrada"
} }
], ],
"label.event": [ "label.event": [
@ -428,7 +428,7 @@
"label.exit": [ "label.exit": [
{ {
"type": 0, "type": 0,
"value": "Exit URL" "value": "URL de sortida"
} }
], ],
"label.false": [ "label.false": [
@ -488,19 +488,19 @@
"label.goal": [ "label.goal": [
{ {
"type": 0, "type": 0,
"value": "Goal" "value": "Meta"
} }
], ],
"label.goals": [ "label.goals": [
{ {
"type": 0, "type": 0,
"value": "Goals" "value": "Metes"
} }
], ],
"label.goals-description": [ "label.goals-description": [
{ {
"type": 0, "type": 0,
"value": "Track your goals for pageviews and events." "value": "Feu un seguiment de les seves metes per a pàgines vistes i esdeveniments."
} }
], ],
"label.greater-than": [ "label.greater-than": [
@ -518,13 +518,13 @@
"label.host": [ "label.host": [
{ {
"type": 0, "type": 0,
"value": "Host" "value": "Amfitrió"
} }
], ],
"label.hosts": [ "label.hosts": [
{ {
"type": 0, "type": 0,
"value": "Hosts" "value": "Amfitrions"
} }
], ],
"label.insights": [ "label.insights": [
@ -578,13 +578,13 @@
"label.journey": [ "label.journey": [
{ {
"type": 0, "type": 0,
"value": "Journey" "value": "Trajecte"
} }
], ],
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Entengui com naveguen els usuaris pel seu lloc web."
} }
], ],
"label.language": [ "label.language": [
@ -777,7 +777,7 @@
"value": [ "value": [
{ {
"type": 0, "type": 0,
"value": "record" "value": "registre"
} }
] ]
}, },
@ -785,7 +785,7 @@
"value": [ "value": [
{ {
"type": 0, "type": 0,
"value": "records" "value": "registres"
} }
] ]
} }
@ -874,19 +874,19 @@
"label.previous": [ "label.previous": [
{ {
"type": 0, "type": 0,
"value": "Previous" "value": "Anterior"
} }
], ],
"label.previous-period": [ "label.previous-period": [
{ {
"type": 0, "type": 0,
"value": "Previous period" "value": "Període anterior"
} }
], ],
"label.previous-year": [ "label.previous-year": [
{ {
"type": 0, "type": 0,
"value": "Previous year" "value": "Any anterior"
} }
], ],
"label.profile": [ "label.profile": [
@ -898,7 +898,7 @@
"label.property": [ "label.property": [
{ {
"type": 0, "type": 0,
"value": "Property" "value": "Propietat"
} }
], ],
"label.queries": [ "label.queries": [
@ -1090,7 +1090,7 @@
"label.start-step": [ "label.start-step": [
{ {
"type": 0, "type": 0,
"value": "Start Step" "value": "Pas inicial"
} }
], ],
"label.steps": [ "label.steps": [
@ -1360,7 +1360,7 @@
"label.views-per-visit": [ "label.views-per-visit": [
{ {
"type": 0, "type": 0,
"value": "Views per visit" "value": "Vistes per visita"
} }
], ],
"label.visit-duration": [ "label.visit-duration": [
@ -1462,7 +1462,7 @@
"message.collected-data": [ "message.collected-data": [
{ {
"type": 0, "type": 0,
"value": "Collected data" "value": "Dades recol·lectades"
} }
], ],
"message.confirm-delete": [ "message.confirm-delete": [
@ -1790,7 +1790,7 @@
"message.visitors-dropped-off": [ "message.visitors-dropped-off": [
{ {
"type": 0, "type": 0,
"value": "Els visitants han sortit" "value": "Visitants han sortit"
} }
] ]
} }

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -32,13 +32,13 @@
"label.add-member": [ "label.add-member": [
{ {
"type": 0, "type": 0,
"value": "Add member" "value": "Mitglied hinzufügen"
} }
], ],
"label.add-step": [ "label.add-step": [
{ {
"type": 0, "type": 0,
"value": "Add step" "value": "Schritt hinzufügen"
} }
], ],
"label.add-website": [ "label.add-website": [
@ -104,7 +104,7 @@
"label.breakdown": [ "label.breakdown": [
{ {
"type": 0, "type": 0,
"value": "Breakdown" "value": "Aufschlüsselung"
} }
], ],
"label.browser": [ "label.browser": [
@ -152,7 +152,7 @@
"label.compare": [ "label.compare": [
{ {
"type": 0, "type": 0,
"value": "Compare" "value": "Vergleich"
} }
], ],
"label.confirm": [ "label.confirm": [
@ -182,7 +182,7 @@
"label.count": [ "label.count": [
{ {
"type": 0, "type": 0,
"value": "Count" "value": "Anzahl"
} }
], ],
"label.countries": [ "label.countries": [
@ -200,7 +200,7 @@
"label.create": [ "label.create": [
{ {
"type": 0, "type": 0,
"value": "Create" "value": "Erstellen"
} }
], ],
"label.create-report": [ "label.create-report": [
@ -230,13 +230,13 @@
"label.created-by": [ "label.created-by": [
{ {
"type": 0, "type": 0,
"value": "Created By" "value": "Erstellt von"
} }
], ],
"label.current": [ "label.current": [
{ {
"type": 0, "type": 0,
"value": "Current" "value": "Aktuell"
} }
], ],
"label.current-password": [ "label.current-password": [
@ -296,7 +296,7 @@
"label.delete-report": [ "label.delete-report": [
{ {
"type": 0, "type": 0,
"value": "Delete report" "value": "Bericht löschen"
} }
], ],
"label.delete-team": [ "label.delete-team": [
@ -386,7 +386,7 @@
"label.edit-member": [ "label.edit-member": [
{ {
"type": 0, "type": 0,
"value": "Edit member" "value": "Mitglied bearbeiten"
} }
], ],
"label.enable-share-url": [ "label.enable-share-url": [
@ -398,7 +398,7 @@
"label.end-step": [ "label.end-step": [
{ {
"type": 0, "type": 0,
"value": "End Step" "value": "Schritt beenden"
} }
], ],
"label.entry": [ "label.entry": [
@ -482,25 +482,25 @@
"label.funnel-description": [ "label.funnel-description": [
{ {
"type": 0, "type": 0,
"value": "Understand the conversion and drop-off rate of users." "value": "Verstehe die Konversions- und Dropoffrate von Nutzern."
} }
], ],
"label.goal": [ "label.goal": [
{ {
"type": 0, "type": 0,
"value": "Goal" "value": "Ziel"
} }
], ],
"label.goals": [ "label.goals": [
{ {
"type": 0, "type": 0,
"value": "Goals" "value": "Ziele"
} }
], ],
"label.goals-description": [ "label.goals-description": [
{ {
"type": 0, "type": 0,
"value": "Track your goals for pageviews and events." "value": "Verfolgen Sie Ihre Ziele für Aufrufe und Events."
} }
], ],
"label.greater-than": [ "label.greater-than": [
@ -536,7 +536,7 @@
"label.insights-description": [ "label.insights-description": [
{ {
"type": 0, "type": 0,
"value": "Dive deeper into your data by using segments and filters." "value": "Tauchen Sie tiefer in Ihre Daten mit Filtern und Segmenten ein."
} }
], ],
"label.is": [ "label.is": [
@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Verstehen Sie, wie Nutzer Ihre Website navigieren."
} }
], ],
"label.language": [ "label.language": [
@ -686,7 +686,7 @@
"label.manage": [ "label.manage": [
{ {
"type": 0, "type": 0,
"value": "Manage" "value": "Verwalten"
} }
], ],
"label.manager": [ "label.manager": [
@ -704,7 +704,7 @@
"label.member": [ "label.member": [
{ {
"type": 0, "type": 0,
"value": "Member" "value": "Mitglied"
} }
], ],
"label.members": [ "label.members": [
@ -734,7 +734,7 @@
"label.my-account": [ "label.my-account": [
{ {
"type": 0, "type": 0,
"value": "My account" "value": "Mein Konto"
} }
], ],
"label.my-websites": [ "label.my-websites": [
@ -874,19 +874,19 @@
"label.previous": [ "label.previous": [
{ {
"type": 0, "type": 0,
"value": "Previous" "value": "Vorherige"
} }
], ],
"label.previous-period": [ "label.previous-period": [
{ {
"type": 0, "type": 0,
"value": "Previous period" "value": "Vorheriger Zeitraum"
} }
], ],
"label.previous-year": [ "label.previous-year": [
{ {
"type": 0, "type": 0,
"value": "Previous year" "value": "Vorheriges Jahr"
} }
], ],
"label.profile": [ "label.profile": [
@ -898,7 +898,7 @@
"label.property": [ "label.property": [
{ {
"type": 0, "type": 0,
"value": "Property" "value": "Besitz"
} }
], ],
"label.queries": [ "label.queries": [
@ -970,7 +970,7 @@
"label.remove-member": [ "label.remove-member": [
{ {
"type": 0, "type": 0,
"value": "Remove member" "value": "Mitglied entfernen"
} }
], ],
"label.reports": [ "label.reports": [
@ -1006,7 +1006,7 @@
"label.retention-description": [ "label.retention-description": [
{ {
"type": 0, "type": 0,
"value": "Measure your website stickiness by tracking how often users return." "value": "Messen Sie die Presenz Ihrer Website, indem Sie tracken wie oft Nutzer zurückkehren."
} }
], ],
"label.role": [ "label.role": [
@ -1036,13 +1036,13 @@
"label.search": [ "label.search": [
{ {
"type": 0, "type": 0,
"value": "Search" "value": "Suche"
} }
], ],
"label.select": [ "label.select": [
{ {
"type": 0, "type": 0,
"value": "Select" "value": "Auswählen"
} }
], ],
"label.select-date": [ "label.select-date": [
@ -1054,7 +1054,7 @@
"label.select-role": [ "label.select-role": [
{ {
"type": 0, "type": 0,
"value": "Select role" "value": "Rolle auswählen"
} }
], ],
"label.select-website": [ "label.select-website": [
@ -1090,13 +1090,13 @@
"label.start-step": [ "label.start-step": [
{ {
"type": 0, "type": 0,
"value": "Start Step" "value": "Schritt starten"
} }
], ],
"label.steps": [ "label.steps": [
{ {
"type": 0, "type": 0,
"value": "Steps" "value": "Schritte"
} }
], ],
"label.sum": [ "label.sum": [
@ -1126,7 +1126,7 @@
"label.team-manager": [ "label.team-manager": [
{ {
"type": 0, "type": 0,
"value": "Team manager" "value": "Team-Manager"
} }
], ],
"label.team-member": [ "label.team-member": [
@ -1234,13 +1234,13 @@
"label.transfer": [ "label.transfer": [
{ {
"type": 0, "type": 0,
"value": "Transfer" "value": "Übertragung"
} }
], ],
"label.transfer-website": [ "label.transfer-website": [
{ {
"type": 0, "type": 0,
"value": "Transfer website" "value": "Website übertragen"
} }
], ],
"label.true": [ "label.true": [
@ -1324,7 +1324,7 @@
"label.utm-description": [ "label.utm-description": [
{ {
"type": 0, "type": 0,
"value": "Track your campaigns through UTM parameters." "value": "Tracken Sie Ihre Kampagnen mit Hilfe von UTM Parametern."
} }
], ],
"label.value": [ "label.value": [
@ -1360,7 +1360,7 @@
"label.views-per-visit": [ "label.views-per-visit": [
{ {
"type": 0, "type": 0,
"value": "Views per visit" "value": "Aufrufe pro Besuch"
} }
], ],
"label.visit-duration": [ "label.visit-duration": [
@ -1378,7 +1378,7 @@
"label.visits": [ "label.visits": [
{ {
"type": 0, "type": 0,
"value": "Visits" "value": "Besuche"
} }
], ],
"label.website": [ "label.website": [
@ -1414,7 +1414,7 @@
"message.action-confirmation": [ "message.action-confirmation": [
{ {
"type": 0, "type": 0,
"value": "Type " "value": "Tippen Sie "
}, },
{ {
"type": 1, "type": 1,
@ -1422,7 +1422,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": " in the box below to confirm." "value": " in das untenliegende Feld, um zu bestätigen."
} }
], ],
"message.active-users": [ "message.active-users": [
@ -1462,7 +1462,7 @@
"message.collected-data": [ "message.collected-data": [
{ {
"type": 0, "type": 0,
"value": "Collected data" "value": "Gesammelte Daten"
} }
], ],
"message.confirm-delete": [ "message.confirm-delete": [
@ -1496,7 +1496,7 @@
"message.confirm-remove": [ "message.confirm-remove": [
{ {
"type": 0, "type": 0,
"value": "Are you sure you want to remove " "value": "Sind Sie sicher, dass Sie "
}, },
{ {
"type": 1, "type": 1,
@ -1504,7 +1504,7 @@
}, },
{ {
"type": 0, "type": 0,
"value": "?" "value": " entfernen möchten?"
} }
], ],
"message.confirm-reset": [ "message.confirm-reset": [
@ -1524,7 +1524,7 @@
"message.delete-team-warning": [ "message.delete-team-warning": [
{ {
"type": 0, "type": 0,
"value": "Deleting a team will also delete all team websites." "value": "Alle zugehörigen Websiten werden ebenfalls gelöscht."
} }
], ],
"message.delete-website-warning": [ "message.delete-website-warning": [
@ -1708,25 +1708,25 @@
"message.transfer-team-website-to-user": [ "message.transfer-team-website-to-user": [
{ {
"type": 0, "type": 0,
"value": "Transfer this website to your account?" "value": "Möchten Sie diese Website auf Ihr Konto übertragen?"
} }
], ],
"message.transfer-user-website-to-team": [ "message.transfer-user-website-to-team": [
{ {
"type": 0, "type": 0,
"value": "Select the team to transfer this website to." "value": "Wählen Sie das Team, auf das die Website übertragen wird."
} }
], ],
"message.transfer-website": [ "message.transfer-website": [
{ {
"type": 0, "type": 0,
"value": "Transfer website ownership to your account or another team." "value": "Übertragen Sie den Besitz der Website auf Ihren Account oder ein anderes Team."
} }
], ],
"message.triggered-event": [ "message.triggered-event": [
{ {
"type": 0, "type": 0,
"value": "Triggered event" "value": "Event ausgelöst"
} }
], ],
"message.user-deleted": [ "message.user-deleted": [
@ -1738,7 +1738,7 @@
"message.viewed-page": [ "message.viewed-page": [
{ {
"type": 0, "type": 0,
"value": "Viewed page" "value": "Seite besucht"
} }
], ],
"message.visitor-log": [ "message.visitor-log": [
@ -1778,7 +1778,7 @@
"message.visitors-dropped-off": [ "message.visitors-dropped-off": [
{ {
"type": 0, "type": 0,
"value": "Visitors dropped off" "value": "Besucher haben die Seite verlassen"
} }
] ]
} }

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

File diff suppressed because it is too large Load Diff

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -152,7 +152,7 @@
"label.compare": [ "label.compare": [
{ {
"type": 0, "type": 0,
"value": "Compare" "value": "Porównaj"
} }
], ],
"label.confirm": [ "label.confirm": [
@ -182,7 +182,7 @@
"label.count": [ "label.count": [
{ {
"type": 0, "type": 0,
"value": "Count" "value": "Liczba"
} }
], ],
"label.countries": [ "label.countries": [
@ -236,7 +236,7 @@
"label.current": [ "label.current": [
{ {
"type": 0, "type": 0,
"value": "Current" "value": "Aktualny"
} }
], ],
"label.current-password": [ "label.current-password": [
@ -398,7 +398,7 @@
"label.end-step": [ "label.end-step": [
{ {
"type": 0, "type": 0,
"value": "End Step" "value": "Krok końcowy"
} }
], ],
"label.entry": [ "label.entry": [
@ -428,7 +428,7 @@
"label.exit": [ "label.exit": [
{ {
"type": 0, "type": 0,
"value": "Exit URL" "value": "URL wyjściowy"
} }
], ],
"label.false": [ "label.false": [
@ -488,13 +488,13 @@
"label.goal": [ "label.goal": [
{ {
"type": 0, "type": 0,
"value": "Goal" "value": "Cel"
} }
], ],
"label.goals": [ "label.goals": [
{ {
"type": 0, "type": 0,
"value": "Goals" "value": "Cele"
} }
], ],
"label.goals-description": [ "label.goals-description": [
@ -524,7 +524,7 @@
"label.hosts": [ "label.hosts": [
{ {
"type": 0, "type": 0,
"value": "Hosts" "value": "Hosty"
} }
], ],
"label.insights": [ "label.insights": [
@ -578,13 +578,13 @@
"label.journey": [ "label.journey": [
{ {
"type": 0, "type": 0,
"value": "Journey" "value": "Droga"
} }
], ],
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Zrozum, w jaki sposób użytkownicy poruszają się po Twojej witrynie."
} }
], ],
"label.language": [ "label.language": [
@ -874,19 +874,19 @@
"label.previous": [ "label.previous": [
{ {
"type": 0, "type": 0,
"value": "Previous" "value": "Poprzedni"
} }
], ],
"label.previous-period": [ "label.previous-period": [
{ {
"type": 0, "type": 0,
"value": "Previous period" "value": "Poprzedni okres"
} }
], ],
"label.previous-year": [ "label.previous-year": [
{ {
"type": 0, "type": 0,
"value": "Previous year" "value": "Poprzedni rok"
} }
], ],
"label.profile": [ "label.profile": [
@ -928,7 +928,7 @@
"label.referrer": [ "label.referrer": [
{ {
"type": 0, "type": 0,
"value": "Referrer" "value": "Źródło odsyłające"
} }
], ],
"label.referrers": [ "label.referrers": [
@ -970,7 +970,7 @@
"label.remove-member": [ "label.remove-member": [
{ {
"type": 0, "type": 0,
"value": "Remove member" "value": "Usuń członka"
} }
], ],
"label.reports": [ "label.reports": [
@ -1090,7 +1090,7 @@
"label.start-step": [ "label.start-step": [
{ {
"type": 0, "type": 0,
"value": "Start Step" "value": "Krok startowy"
} }
], ],
"label.steps": [ "label.steps": [
@ -1378,7 +1378,7 @@
"label.visits": [ "label.visits": [
{ {
"type": 0, "type": 0,
"value": "Odwiedząjący" "value": "Wizyty"
} }
], ],
"label.website": [ "label.website": [
@ -1462,7 +1462,7 @@
"message.collected-data": [ "message.collected-data": [
{ {
"type": 0, "type": 0,
"value": "Collected data" "value": "Zebrane dane"
} }
], ],
"message.confirm-delete": [ "message.confirm-delete": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -566,7 +566,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -152,7 +152,7 @@
"label.compare": [ "label.compare": [
{ {
"type": 0, "type": 0,
"value": "Compare" "value": "比较"
} }
], ],
"label.confirm": [ "label.confirm": [
@ -182,7 +182,7 @@
"label.count": [ "label.count": [
{ {
"type": 0, "type": 0,
"value": "Count" "value": "统计"
} }
], ],
"label.countries": [ "label.countries": [
@ -236,7 +236,7 @@
"label.current": [ "label.current": [
{ {
"type": 0, "type": 0,
"value": "Current" "value": "目前"
} }
], ],
"label.current-password": [ "label.current-password": [
@ -398,13 +398,13 @@
"label.end-step": [ "label.end-step": [
{ {
"type": 0, "type": 0,
"value": "End Step" "value": "结束步骤"
} }
], ],
"label.entry": [ "label.entry": [
{ {
"type": 0, "type": 0,
"value": "Entry URL" "value": "入口 URL"
} }
], ],
"label.event": [ "label.event": [
@ -428,7 +428,7 @@
"label.exit": [ "label.exit": [
{ {
"type": 0, "type": 0,
"value": "Exit URL" "value": "退出 URL"
} }
], ],
"label.false": [ "label.false": [
@ -488,19 +488,19 @@
"label.goal": [ "label.goal": [
{ {
"type": 0, "type": 0,
"value": "Goal" "value": "目标"
} }
], ],
"label.goals": [ "label.goals": [
{ {
"type": 0, "type": 0,
"value": "Goals" "value": "目标"
} }
], ],
"label.goals-description": [ "label.goals-description": [
{ {
"type": 0, "type": 0,
"value": "Track your goals for pageviews and events." "value": "跟踪页面浏览量和事件的目标。"
} }
], ],
"label.greater-than": [ "label.greater-than": [
@ -518,13 +518,13 @@
"label.host": [ "label.host": [
{ {
"type": 0, "type": 0,
"value": "Host" "value": "主机"
} }
], ],
"label.hosts": [ "label.hosts": [
{ {
"type": 0, "type": 0,
"value": "Hosts" "value": "主机"
} }
], ],
"label.insights": [ "label.insights": [
@ -578,13 +578,13 @@
"label.journey": [ "label.journey": [
{ {
"type": 0, "type": 0,
"value": "Journey" "value": "用户浏览轨迹"
} }
], ],
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "了解用户如何浏览网站。"
} }
], ],
"label.language": [ "label.language": [
@ -692,7 +692,7 @@
"label.manager": [ "label.manager": [
{ {
"type": 0, "type": 0,
"value": "Manager" "value": "管理者"
} }
], ],
"label.max": [ "label.max": [
@ -798,7 +798,7 @@
"label.ok": [ "label.ok": [
{ {
"type": 0, "type": 0,
"value": "OK" "value": "好的"
} }
], ],
"label.os": [ "label.os": [
@ -882,19 +882,19 @@
"label.previous": [ "label.previous": [
{ {
"type": 0, "type": 0,
"value": "Previous" "value": "先前"
} }
], ],
"label.previous-period": [ "label.previous-period": [
{ {
"type": 0, "type": 0,
"value": "Previous period" "value": "上一时期"
} }
], ],
"label.previous-year": [ "label.previous-year": [
{ {
"type": 0, "type": 0,
"value": "Previous year" "value": "上一年"
} }
], ],
"label.profile": [ "label.profile": [
@ -906,7 +906,7 @@
"label.property": [ "label.property": [
{ {
"type": 0, "type": 0,
"value": "Property" "value": "属性"
} }
], ],
"label.queries": [ "label.queries": [
@ -1098,7 +1098,7 @@
"label.start-step": [ "label.start-step": [
{ {
"type": 0, "type": 0,
"value": "Start Step" "value": "开始步骤"
} }
], ],
"label.steps": [ "label.steps": [
@ -1134,7 +1134,7 @@
"label.team-manager": [ "label.team-manager": [
{ {
"type": 0, "type": 0,
"value": "Team manager" "value": "团队管理者"
} }
], ],
"label.team-member": [ "label.team-member": [
@ -1450,7 +1450,7 @@
"message.collected-data": [ "message.collected-data": [
{ {
"type": 0, "type": 0,
"value": "Collected data" "value": "已收集的数据"
} }
], ],
"message.confirm-delete": [ "message.confirm-delete": [

View File

@ -584,7 +584,7 @@
"label.journey-description": [ "label.journey-description": [
{ {
"type": 0, "type": 0,
"value": "Understand how users nagivate through your website." "value": "Understand how users navigate through your website."
} }
], ],
"label.language": [ "label.language": [

View File

@ -44,7 +44,7 @@ async function checkConnection() {
success('Database connection successful.'); success('Database connection successful.');
} catch (e) { } catch (e) {
throw new Error('Unable to connect to the database.'); throw new Error('Unable to connect to the database: ' + e.message);
} }
} }

View File

@ -2,7 +2,6 @@ require('dotenv').config();
const cli = require('next/dist/cli/next-start'); const cli = require('next/dist/cli/next-start');
cli.nextStart({ cli.nextStart({
'--port': process.env.PORT || 3000, port: process.env.PORT || 3000,
'--hostname': process.env.HOSTNAME || '0.0.0.0', hostname: process.env.HOSTNAME || '0.0.0.0',
_: [],
}); });

View File

@ -21,8 +21,12 @@ export function TestConsole({ websiteId }: { websiteId: string }) {
router.push(`/console/${value}`); router.push(`/console/${value}`);
} }
function handleClick() { function handleRunScript() {
window['umami'].track({ url: '/page-view', referrer: 'https://www.google.com' }); window['umami'].track(props => ({
...props,
url: '/page-view',
referrer: 'https://www.google.com',
}));
window['umami'].track('track-event-no-data'); window['umami'].track('track-event-no-data');
window['umami'].track('track-event-with-data', { window['umami'].track('track-event-with-data', {
test: 'test-data', test: 'test-data',
@ -44,7 +48,7 @@ export function TestConsole({ websiteId }: { websiteId: string }) {
}); });
} }
function handleIdentifyClick() { function handleRunIdentify() {
window['umami'].identify({ window['umami'].identify({
userId: 123, userId: 123,
name: 'brian', name: 'brian',
@ -145,10 +149,10 @@ export function TestConsole({ websiteId }: { websiteId: string }) {
</div> </div>
<div className={styles.group}> <div className={styles.group}>
<div className={styles.header}>Javascript events</div> <div className={styles.header}>Javascript events</div>
<Button id="manual-button" variant="primary" onClick={handleClick}> <Button id="manual-button" variant="primary" onClick={handleRunScript}>
Run script Run script
</Button> </Button>
<Button id="manual-button" variant="primary" onClick={handleIdentifyClick}> <Button id="manual-button" variant="primary" onClick={handleRunIdentify}>
Run identify Run identify
</Button> </Button>
</div> </div>

View File

@ -51,6 +51,12 @@ export function ReportTemplates({ showHeader = true }: { showHeader?: boolean })
url: renderTeamUrl('/reports/journey'), url: renderTeamUrl('/reports/journey'),
icon: <Path />, icon: <Path />,
}, },
// {
// title: formatMessage(labels.revenue),
// description: formatMessage(labels.revenueDescription),
// url: renderTeamUrl('/reports/revenue'),
// icon: <Path />,
// },
]; ];
return ( return (

View File

@ -34,6 +34,10 @@
background-color: var(--base100); background-color: var(--base100);
} }
.step:last-child::before {
display: none;
}
.card { .card {
display: grid; display: grid;
gap: 20px; gap: 20px;

View File

@ -121,7 +121,7 @@
} }
.name { .name {
font-weight: 500; max-width: 200px;
} }
.count { .count {

View File

@ -1,5 +1,5 @@
import { useContext, useMemo, useState } from 'react'; import { useContext, useMemo, useState } from 'react';
import { TooltipPopup } from 'react-basics'; import { TextOverflow, TooltipPopup } from 'react-basics';
import { firstBy } from 'thenby'; import { firstBy } from 'thenby';
import classNames from 'classnames'; import classNames from 'classnames';
import { useEscapeKey, useMessages } from 'components/hooks'; import { useEscapeKey, useMessages } from 'components/hooks';
@ -191,7 +191,9 @@ export default function JourneyView() {
})} })}
onClick={() => handleClick(name, columnIndex, paths)} onClick={() => handleClick(name, columnIndex, paths)}
> >
<div className={styles.name}>{name}</div> <div className={styles.name} title={name}>
<TextOverflow> {name}</TextOverflow>
</div>
<TooltipPopup label={dropOffPercent} disabled={!selected}> <TooltipPopup label={dropOffPercent} disabled={!selected}>
<div className={styles.count} title={nodeCount}> <div className={styles.count} title={nodeCount}>
{formatLongNumber(nodeCount)} {formatLongNumber(nodeCount)}

View File

@ -1,8 +1,13 @@
import TeamProvider from './TeamProvider'; import TeamProvider from './TeamProvider';
import { Metadata } from 'next'; import { Metadata } from 'next';
import TeamSettingsLayout from './settings/TeamSettingsLayout';
export default function ({ children, params: { teamId } }) { export default function ({ children, params: { teamId } }) {
return <TeamProvider teamId={teamId}>{children}</TeamProvider>; return (
<TeamProvider teamId={teamId}>
<TeamSettingsLayout>{children}</TeamSettingsLayout>
</TeamProvider>
);
} }
export const metadata: Metadata = { export const metadata: Metadata = {

View File

@ -0,0 +1,29 @@
'use client';
import { ReactNode } from 'react';
import { useMessages, useTeamUrl } from 'components/hooks';
import MenuLayout from 'components/layout/MenuLayout';
export default function TeamSettingsLayout({ children }: { children: ReactNode }) {
const { formatMessage, labels } = useMessages();
const { teamId } = useTeamUrl();
const items = [
{
key: 'team',
label: formatMessage(labels.team),
url: `/teams/${teamId}/settings/team`,
},
{
key: 'websites',
label: formatMessage(labels.websites),
url: `/teams/${teamId}/settings/websites`,
},
{
key: 'members',
label: formatMessage(labels.members),
url: `/teams/${teamId}/settings/members`,
},
].filter(n => n);
return <MenuLayout items={items}>{children}</MenuLayout>;
}

View File

@ -5,7 +5,7 @@ import PageHeader from 'components/layout/PageHeader';
import { ROLES } from 'lib/constants'; import { ROLES } from 'lib/constants';
import { useContext, useState } from 'react'; import { useContext, useState } from 'react';
import { Flexbox, Item, Tabs } from 'react-basics'; import { Flexbox, Item, Tabs } from 'react-basics';
import TeamLeaveButton from '../../TeamLeaveButton'; import TeamLeaveButton from 'app/(main)/settings/teams/TeamLeaveButton';
import TeamManage from './TeamManage'; import TeamManage from './TeamManage';
import TeamEditForm from './TeamEditForm'; import TeamEditForm from './TeamEditForm';

View File

@ -11,7 +11,7 @@ import {
} from 'react-basics'; } from 'react-basics';
import { getRandomChars } from 'next-basics'; import { getRandomChars } from 'next-basics';
import { useContext, useRef, useState } from 'react'; import { useContext, useRef, useState } from 'react';
import { useApi, useMessages } from 'components/hooks'; import { useApi, useMessages, useModified } from 'components/hooks';
import { TeamContext } from 'app/(main)/teams/[teamId]/TeamProvider'; import { TeamContext } from 'app/(main)/teams/[teamId]/TeamProvider';
const generateId = () => getRandomChars(16); const generateId = () => getRandomChars(16);
@ -26,12 +26,14 @@ export function TeamEditForm({ teamId, allowEdit }: { teamId: string; allowEdit?
const ref = useRef(null); const ref = useRef(null);
const [accessCode, setAccessCode] = useState(team.accessCode); const [accessCode, setAccessCode] = useState(team.accessCode);
const { showToast } = useToasts(); const { showToast } = useToasts();
const { touch } = useModified();
const cloudMode = !!process.env.cloudMode; const cloudMode = !!process.env.cloudMode;
const handleSubmit = async (data: any) => { const handleSubmit = async (data: any) => {
mutate(data, { mutate(data, {
onSuccess: async () => { onSuccess: async () => {
ref.current.reset(data); ref.current.reset(data);
touch('teams');
showToast({ message: formatMessage(messages.saved), variant: 'success' }); showToast({ message: formatMessage(messages.saved), variant: 'success' });
}, },
}); });

View File

@ -0,0 +1,5 @@
import Page from 'app/(main)/settings/websites/[websiteId]/page';
export default function ({ params }) {
return <Page params={params} />;
}

View File

@ -45,10 +45,15 @@ export function WebsiteHeader({
icon: <Icons.Reports />, icon: <Icons.Reports />,
path: '/reports', path: '/reports',
}, },
// {
// label: formatMessage(labels.sessions),
// icon: <Icons.User />,
// path: '/sessions',
// },
{ {
label: formatMessage(labels.eventData), label: formatMessage(labels.events),
icon: <Icons.Nodes />, icon: <Icons.Nodes />,
path: '/event-data', path: '/events',
}, },
]; ];

View File

@ -54,7 +54,7 @@ export function RealtimeLog({ data }: { data: RealtimeData }) {
}, },
]; ];
const getTime = ({ timestamp }) => format(timestamp * 1000, 'h:mm:ss'); const getTime = ({ createdAt }) => format(new Date(createdAt), 'h:mm:ss');
const getColor = ({ id, sessionId }) => stringToColor(sessionId || id); const getColor = ({ id, sessionId }) => stringToColor(sessionId || id);
@ -144,9 +144,12 @@ export function RealtimeLog({ data }: { data: RealtimeData }) {
const { events, visitors } = data; const { events, visitors } = data;
let logs = [ let logs = [
...events.map(e => ({ __type: e.eventName ? TYPE_EVENT : TYPE_PAGEVIEW, ...e })), ...events.map(e => ({
__type: e.eventName ? TYPE_EVENT : TYPE_PAGEVIEW,
...e,
})),
...visitors.map(v => ({ __type: TYPE_SESSION, ...v })), ...visitors.map(v => ({ __type: TYPE_SESSION, ...v })),
].sort(thenby.firstBy('timestamp', -1)); ].sort(thenby.firstBy('createdAt', -1));
if (search) { if (search) {
logs = logs.filter(({ eventName, urlPath, browser, os, country, device }) => { logs = logs.filter(({ eventName, urlPath, browser, os, country, device }) => {

View File

@ -0,0 +1,5 @@
export function SessionMetricsBar({ websiteId }: { websiteId: string }) {
return <h1>{websiteId}</h1>;
}
export default SessionMetricsBar;

View File

@ -0,0 +1,25 @@
import { useSessions } from 'components/hooks';
import SessionsTable from './SessionsTable';
import DataTable from 'components/common/DataTable';
import { ReactNode } from 'react';
export default function SessionsDataTable({
websiteId,
children,
}: {
websiteId?: string;
teamId?: string;
children?: ReactNode;
}) {
const queryResult = useSessions(websiteId);
if (queryResult?.result?.data?.length === 0) {
return children;
}
return (
<DataTable queryResult={queryResult} allowSearch={false}>
{({ data }) => <SessionsTable data={data} showDomain={!websiteId} />}
</DataTable>
);
}

View File

@ -0,0 +1,14 @@
'use client';
import WebsiteHeader from '../WebsiteHeader';
import SessionsDataTable from './SessionsDataTable';
export function SessionsPage({ websiteId }) {
return (
<>
<WebsiteHeader websiteId={websiteId} />
<SessionsDataTable websiteId={websiteId} />
</>
);
}
export default SessionsPage;

View File

@ -0,0 +1,31 @@
import { GridColumn, GridTable, useBreakpoint } from 'react-basics';
import { useFormat, useMessages } from 'components/hooks';
import { formatDistanceToNow } from 'date-fns';
export function SessionsTable({ data = [] }: { data: any[]; showDomain?: boolean }) {
const { formatMessage, labels } = useMessages();
const breakpoint = useBreakpoint();
const { formatValue } = useFormat();
return (
<GridTable data={data} cardMode={['xs', 'sm', 'md'].includes(breakpoint)}>
<GridColumn name="id" label="ID" />
<GridColumn name="country" label={formatMessage(labels.country)}>
{row => formatValue(row.country, 'country')}
</GridColumn>
<GridColumn name="city" label={formatMessage(labels.city)} />
<GridColumn name="browser" label={formatMessage(labels.browser)}>
{row => formatValue(row.browser, 'browser')}
</GridColumn>
<GridColumn name="os" label={formatMessage(labels.os)} />
<GridColumn name="device" label={formatMessage(labels.device)}>
{row => formatValue(row.device, 'device')}
</GridColumn>
<GridColumn name="createdAt" label={formatMessage(labels.created)}>
{row => formatDistanceToNow(new Date(row.createdAt))}
</GridColumn>
</GridTable>
);
}
export default SessionsTable;

View File

@ -0,0 +1,10 @@
import SessionsPage from './SessionsPage';
import { Metadata } from 'next';
export default function ({ params: { websiteId } }) {
return <SessionsPage websiteId={websiteId} />;
}
export const metadata: Metadata = {
title: 'Sessions',
};

View File

@ -0,0 +1,28 @@
import { CURRENT_VERSION, TELEMETRY_PIXEL } from 'lib/constants';
export async function GET() {
if (
process.env.NODE_ENV !== 'production' &&
process.env.DISABLE_TELEMETRY &&
process.env.PRIVATE_MODE
) {
const script = `
(()=>{const i=document.createElement('img');
i.setAttribute('src','${TELEMETRY_PIXEL}?v=${CURRENT_VERSION}');
i.setAttribute('style','width:0;height:0;position:absolute;pointer-events:none;');
document.body.appendChild(i);})();
`;
return new Response(script.replace(/\s\s+/g, ''), {
headers: {
'content-type': 'text/javascript',
},
});
}
return new Response('/* telemetry disabled */', {
headers: {
'content-type': 'text/javascript',
},
});
}

View File

@ -79,18 +79,20 @@ export function Chart({
}; };
const updateChart = (data: any) => { const updateChart = (data: any) => {
if (data.datasets.length === chart.current.data.datasets.length) { if (data.datasets) {
chart.current.data.datasets.forEach((dataset: { data: any }, index: string | number) => { if (data.datasets.length === chart.current.data.datasets.length) {
if (data?.datasets[index]) { chart.current.data.datasets.forEach((dataset: { data: any }, index: string | number) => {
dataset.data = data?.datasets[index]?.data; if (data?.datasets[index]) {
dataset.data = data?.datasets[index]?.data;
if (chart.current.legend.legendItems[index]) { if (chart.current.legend.legendItems[index]) {
chart.current.legend.legendItems[index].text = data?.datasets[index]?.label; chart.current.legend.legendItems[index].text = data?.datasets[index]?.label;
}
} }
} });
}); } else {
} else { chart.current.data.datasets = data.datasets;
chart.current.data.datasets = data.datasets; }
} }
chart.current.options = options; chart.current.options = options;

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