implement session replay filters

This commit is contained in:
Francis Cao
2026-06-17 11:38:57 -07:00
parent f3ce0e64ca
commit c61c01e3bb
62 changed files with 264 additions and 372 deletions
+2
View File
@@ -102,6 +102,7 @@
"download": "تحميل",
"dropoff": "إنزال",
"duration": "المدة",
"min-duration-seconds": "الحد الأدنى للمدة (ثواني)",
"edit": "تعديل",
"edit-member": "عدّل العضو",
"email": "بريد إلكتروني",
@@ -419,6 +420,7 @@
"triggered-event": "أُطلق الحدث",
"unauthorized": "غير مصرح",
"user-deleted": "تم حذف المستخدم.",
"replay-min-duration-description": "إظهار التسجيلات ذات المدة الأطول أو المساوية لهذه المدة فقط.",
"viewed-page": "شوهدت الصفحة",
"visitor-log": "زائر من <b>{country}</b> يستخدم <b>{browser}</b> على <b>{os}</b> <b>{device}</b>"
}
+2
View File
@@ -102,6 +102,7 @@
"download": "Спампаваць",
"dropoff": "Адмовы",
"duration": "Працягласць",
"min-duration-seconds": "Мінімальная працягласць (секунды)",
"edit": "Змяніць",
"edit-member": "Рэдагаваць удзельніка",
"email": "Электронная пошта",
@@ -419,6 +420,7 @@
"triggered-event": "Падзея якая спрацавала",
"unauthorized": "Не аўтарызаваны",
"user-deleted": "Карыстальнік выдалены.",
"replay-min-duration-description": "Паказваць толькі паўторы з такой або большай працягласцю.",
"viewed-page": "Праглядзеў старонку",
"visitor-log": "Наведвальнік з <b>{country}</b> праз <b>{browser}</b> на <b>{os}</b> <b>{device}</b>"
}
+2
View File
@@ -102,6 +102,7 @@
"download": "Изтегляне",
"dropoff": "Отпадане",
"duration": "Продължителност",
"min-duration-seconds": "Минимална продължителност (секунди)",
"edit": "Редактирай",
"edit-member": "Редактирай член",
"email": "Имейл",
@@ -419,6 +420,7 @@
"triggered-event": "Активирано събитие",
"unauthorized": "Неоторизиран достъп",
"user-deleted": "Потребителят е изтрит.",
"replay-min-duration-description": "Показвай само записи с тази или по-голяма продължителност.",
"viewed-page": "Страницата е видяна",
"visitor-log": "Посетител от <b>{country}</b>, използващ <b>{browser}</b> на <b>{os}</b> <b>{device}</b>"
}
+2
View File
@@ -102,6 +102,7 @@
"download": "ডাউনলোড",
"dropoff": "ছেড়ে যাওয়া",
"duration": "সময়কাল",
"min-duration-seconds": "ন্যূনতম সময়কাল (সেকেন্ড)",
"edit": "সম্পাদনা করুন",
"edit-member": "সদস্য সম্পাদনা করুন",
"email": "ইমেইল",
@@ -419,6 +420,7 @@
"triggered-event": "ট্রিগার করা ইভেন্ট",
"unauthorized": "অননুমোদিত",
"user-deleted": "ব্যবহারকারী মুছে ফেলা হয়েছে।",
"replay-min-duration-description": "শুধুমাত্র এই সময়কাল বা তার উপরে রিপ্লেগুলি দেখান।",
"viewed-page": "দেখা পৃষ্ঠা",
"visitor-log": "<b>{country}</b> থেকে একজন ভিসিটর {ব্রাউজার}, ব্যবহার করছেন <b>{os}</b> <b>{device}</b> এর মধ্যে।"
}
+2
View File
@@ -103,6 +103,7 @@
"download": "Preuzmi",
"dropoff": "Odlazak",
"duration": "Trajanje",
"min-duration-seconds": "Minimalno trajanje (sekunde)",
"edit": "Uredi",
"edit-member": "Uredi člana",
"email": "E-mail",
@@ -430,6 +431,7 @@
"triggered-event": "Trigerovani događaj",
"unauthorized": "Neautorizirano",
"user-deleted": "Korisnik obrisan.",
"replay-min-duration-description": "Prikaži samo snimke s ovim ili dužim trajanjem.",
"viewed-page": "Pogledana stranica",
"upgrade-required": "Ova funkcija zahtijeva pretplatu na plan {plan}.",
"visitor-log": "Posjetitelj iz <b>{country}</b> koristi <b>{browser}</b> na <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Descarregar",
"dropoff": "Abandonament",
"duration": "Durada",
"min-duration-seconds": "Durada mínima (segons)",
"edit": "Edita",
"edit-member": "Edita membre",
"email": "Correu electrònic",
@@ -430,6 +431,7 @@
"triggered-event": "Esdeveniment desencadenat",
"unauthorized": "No autoritzat",
"user-deleted": "Usuari eliminat.",
"replay-min-duration-description": "Mostra només les reproduccions amb aquesta durada o superior.",
"viewed-page": "Pàgina vista",
"upgrade-required": "Aquesta funció requereix una subscripció al pla {plan}.",
"visitor-log": "Visitant de <b>{country}</b> usant <b>{browser}</b> a <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Stáhnout",
"dropoff": "Opuštění",
"duration": "Trvání",
"min-duration-seconds": "Minimální délka (sekundy)",
"edit": "Upravit",
"edit-member": "Upravit člena",
"email": "E-mail",
@@ -430,6 +431,7 @@
"triggered-event": "Spuštěná událost",
"unauthorized": "Neautorizováno",
"user-deleted": "Uživatel smazán.",
"replay-min-duration-description": "Zobrazit pouze záznamy s touto nebo delší délkou.",
"viewed-page": "Zobrazená stránka",
"upgrade-required": "Tato funkce vyžaduje předplatné plánu {plan}.",
"visitor-log": "Návštěvník z <b>{country}</b> s prohlížečem <b>{browser}</b> na <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Download",
"dropoff": "Frafald",
"duration": "Varighed",
"min-duration-seconds": "Minimumsvarighed (sekunder)",
"edit": "Rediger",
"edit-member": "Rediger medlem",
"email": "E-mail",
@@ -430,6 +431,7 @@
"triggered-event": "Udløst begivenhed",
"unauthorized": "Ikke autoriseret",
"user-deleted": "Bruger slettet.",
"replay-min-duration-description": "Vis kun gengivelser med denne varighed eller derover.",
"viewed-page": "Vist side",
"upgrade-required": "Denne funktion kræver et {plan}-abonnement.",
"visitor-log": "Besøgende fra <b>{country}</b> bruger <b>{browser}</b> på <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Herunterladen",
"dropoff": "Absprung",
"duration": "Dauer",
"min-duration-seconds": "Mindestdauer (Sekunden)",
"edit": "Bearbeite",
"edit-member": "Mitglied bearbeite",
"email": "E-Mail",
@@ -430,6 +431,7 @@
"triggered-event": "Usglösts Ereigniss",
"unauthorized": "Nicht autorisiert",
"user-deleted": "Bnutzer glöscht.",
"replay-min-duration-description": "Nur Wiedergaben mit dieser oder längerer Dauer anzeigen.",
"viewed-page": "Siite agluegt",
"upgrade-required": "Diese Funktion erfordert ein {plan}-Abonnement.",
"visitor-log": "Bsuecher us <b>{country}</b> nutzt <b>{browser}</b> uf <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Herunterladen",
"dropoff": "Absprung",
"duration": "Dauer",
"min-duration-seconds": "Mindestdauer (Sekunden)",
"edit": "Bearbeiten",
"edit-member": "Mitglied bearbeiten",
"email": "E-Mail",
@@ -430,6 +431,7 @@
"triggered-event": "Ereignis ausgelöst",
"unauthorized": "Nicht autorisiert",
"user-deleted": "Benutzer gelöscht.",
"replay-min-duration-description": "Nur Wiedergaben mit dieser oder längerer Dauer anzeigen.",
"viewed-page": "Seite besucht",
"upgrade-required": "Diese Funktion erfordert ein {plan}-Abonnement.",
"visitor-log": "Besucher aus <b>{country}</b> benutzt <b>{browser}</b> auf <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -102,6 +102,7 @@
"download": "Λήψη",
"dropoff": "Εγκατάλειψη",
"duration": "Διάρκεια",
"min-duration-seconds": "Ελάχιστη διάρκεια (δευτερόλεπτα)",
"edit": "Επεξεργασία",
"edit-member": "Επεξεργασία μέλους",
"email": "Email",
@@ -419,6 +420,7 @@
"triggered-event": "Ενεργοποιημένο συμβάν",
"unauthorized": "Μη εξουσιοδοτημένο",
"user-deleted": "Ο χρήστης διαγράφηκε.",
"replay-min-duration-description": "Εμφάνιση μόνο αναπαραγωγών με αυτή ή μεγαλύτερη διάρκεια.",
"viewed-page": "Προβολή σελίδας",
"visitor-log": "Επισκέπτης από <b>{country}</b> χρησιμοποιώντας <b>{browser}</b> σε <b>{os}</b> <b>{device}</b>"
}
+2
View File
@@ -103,6 +103,7 @@
"download": "Download",
"dropoff": "Dropoff",
"duration": "Duration",
"min-duration-seconds": "Minimum duration (seconds)",
"edit": "Edit",
"edit-member": "Edit member",
"email": "Email",
@@ -430,6 +431,7 @@
"triggered-event": "Triggered event",
"unauthorized": "Unauthorized",
"user-deleted": "User deleted.",
"replay-min-duration-description": "Only show replays at or above this duration.",
"viewed-page": "Viewed page",
"upgrade-required": "This feature requires a {plan} plan subscription.",
"visitor-log": "Visitor from <b>{country}</b> using <b>{browser}</b> on <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -104,6 +104,7 @@
"download": "Download",
"dropoff": "Dropoff",
"duration": "Duration",
"min-duration-seconds": "Minimum duration (seconds)",
"edit": "Edit",
"edit-member": "Edit member",
"email": "Email",
@@ -439,6 +440,7 @@
"triggered-event": "Triggered event",
"unauthorized": "Unauthorized",
"user-deleted": "User deleted.",
"replay-min-duration-description": "Only show replays at or above this duration.",
"viewed-page": "Viewed page",
"upgrade-required": "This feature requires a {plan} plan subscription.",
"visitor-log": "Visitor from <b>{country}</b> using <b>{browser}</b> on <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Descargar",
"dropoff": "Abandono",
"duration": "Duración",
"min-duration-seconds": "Duración mínima (segundos)",
"edit": "Editar",
"edit-member": "Editar miembro",
"email": "Correo electrónico",
@@ -432,6 +433,7 @@
"triggered-event": "Evento lanzado",
"unauthorized": "No autorizado",
"user-deleted": "Usuario eliminado.",
"replay-min-duration-description": "Mostrar solo las repeticiones con esta duración o superior.",
"viewed-page": "Página vista",
"upgrade-required": "Esta función requiere una suscripción al plan {plan}.",
"visitor-log": "Visitante desde <b>{country}</b> usando <b>{browser}</b> en <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -102,6 +102,7 @@
"download": "دانلود",
"dropoff": "رها کردن",
"duration": "مدت",
"min-duration-seconds": "حداقل مدت زمان (ثانیه)",
"edit": "ویرایش",
"edit-member": "ویرایش عضو",
"email": "ایمیل",
@@ -419,6 +420,7 @@
"triggered-event": "رویداد فعال شده",
"unauthorized": "غیرمجاز",
"user-deleted": "کاربر حذف شد.",
"replay-min-duration-description": "فقط پخش‌هایی را نشان بده که مدت زمان آن‌ها برابر یا بیشتر از این مقدار است.",
"viewed-page": "صفحه مشاهده شد",
"visitor-log": "بازدیدکننده از کشور <b>{country}</b> با مروگر <b>{browser}</b> در <b>{os}</b> <b>{device}</b>"
}
+2
View File
@@ -103,6 +103,7 @@
"download": "Lataa",
"dropoff": "Poistuminen",
"duration": "Kesto",
"min-duration-seconds": "Vähimmäiskesto (sekuntia)",
"edit": "Muokkaa",
"edit-member": "Muokkaa jäsentä",
"email": "Sähköposti",
@@ -430,6 +431,7 @@
"triggered-event": "Laukaistu tapahtuma",
"unauthorized": "Ei oikeuksia",
"user-deleted": "Käyttäjä poistettu.",
"replay-min-duration-description": "Näytä vain toistot, joiden kesto on tämä tai enemmän.",
"viewed-page": "Katsottu sivu",
"upgrade-required": "Tämä ominaisuus vaatii {plan}-tilauksen.",
"visitor-log": "Vierailija maasta <b>{country}</b> selaimella <b>{browser}</b> laitteella <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Tak niður",
"dropoff": "Fráfall",
"duration": "Tíðarlongd",
"min-duration-seconds": "Lágmarkslongd (sekund)",
"edit": "Ger broyting",
"edit-member": "Ritstjórna lim",
"email": "Teldupostur",
@@ -430,6 +431,7 @@
"triggered-event": "Avbjóðað hending",
"unauthorized": "Ikki góðkent",
"user-deleted": "Brúkari strikaður.",
"replay-min-duration-description": "Vís bert endurspælingar við hesa ella longri longd.",
"viewed-page": "Síð vís",
"upgrade-required": "Hesin virknisháttur krevur eitt {plan}-lyftirtak.",
"visitor-log": "Vitjandi frá <b>{country}</b> brúkar <b>{browser}</b> á <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -104,6 +104,7 @@
"download": "Télécharger",
"dropoff": "Abandons",
"duration": "Durée",
"min-duration-seconds": "Durée minimale (secondes)",
"edit": "Modifier",
"edit-member": "Modifier le membre",
"email": "E-mail",
@@ -431,6 +432,7 @@
"unauthorized": "Non authorisé!",
"upgrade-required": "Cette fonctionnalité nécessite un abonnement {plan}.",
"user-deleted": "Utilisateur supprimé.",
"replay-min-duration-description": "Afficher uniquement les lectures de cette durée ou plus.",
"viewed-page": "Page vue",
"visitor-log": "Visiteur de <b>{country}</b> utilisant <b>{browser}</b> sur <b>{os}</b> <b>{device}</b>"
}
+2
View File
@@ -103,6 +103,7 @@
"download": "Descargar",
"dropoff": "Disminución",
"duration": "Duración",
"min-duration-seconds": "Duración mínima (segundos)",
"edit": "Editar",
"edit-member": "Editar membro",
"email": "Correo electrónico",
@@ -430,6 +431,7 @@
"triggered-event": "Activou o evento",
"unauthorized": "Non autorizado",
"user-deleted": "Usuario eliminado.",
"replay-min-duration-description": "Mostrar só as repeticións con esta duración ou superior.",
"viewed-page": "Páxina vista",
"upgrade-required": "Esta función require unha subscrición ao plan {plan}.",
"visitor-log": "Visitante desde <b>{country}</b> usando <b>{browser}</b> en <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -102,6 +102,7 @@
"download": "הורדה",
"dropoff": "עזיבה",
"duration": "משך",
"min-duration-seconds": "משך מינימלי (שניות)",
"edit": "עריכה",
"edit-member": "ערוך חבר",
"email": "אימייל",
@@ -419,6 +420,7 @@
"triggered-event": "אירוע שהופעל",
"unauthorized": "לא מורשה",
"user-deleted": "משתמש נמחק.",
"replay-min-duration-description": "הצג רק הקלטות בהפעלה חוזרת בעלות משך זמן זה או ארוך יותר.",
"viewed-page": "עמוד שנצפה",
"visitor-log": "מבקר ממדינת <b>{country}</b> משתמבש בדפדפן <b>{browser}</b> ב-<b>{os}</b> <b>{device}</b>"
}
+2
View File
@@ -102,6 +102,7 @@
"download": "डाउनलोड",
"dropoff": "ड्रॉपऑफ",
"duration": "अवधि",
"min-duration-seconds": "न्यूनतम अवधि (सेकंड)",
"edit": "संपादित करें",
"edit-member": "सदस्य संपादित करें",
"email": "ईमेल",
@@ -419,6 +420,7 @@
"triggered-event": "ट्रिगर किया गया ईवेंट",
"unauthorized": "अनधिकृत",
"user-deleted": "उपयोगकर्ता हटाया गया।",
"replay-min-duration-description": "केवल इस अवधि या उससे अधिक की रिप्ले दिखाएं।",
"viewed-page": "देखा गया पेज",
"visitor-log": "<b>{country}</b> का आगंतुक, जो <b>{browser}</b> का उपयोग करता है, <b>{os}</b> यन्त्र पर"
}
+2
View File
@@ -103,6 +103,7 @@
"download": "Preuzmi",
"dropoff": "Odlazak",
"duration": "Trajanje",
"min-duration-seconds": "Minimalno trajanje (sekunde)",
"edit": "Uredi",
"edit-member": "Uredi člana",
"email": "E-mail",
@@ -430,6 +431,7 @@
"triggered-event": "Pokrenuti događaj",
"unauthorized": "Neautorizirano",
"user-deleted": "Korisnik izbrisan.",
"replay-min-duration-description": "Prikaži samo snimke s ovim ili dužim trajanjem.",
"viewed-page": "Pregledana stranica",
"upgrade-required": "Ova značajka zahtijeva pretplatu na plan {plan}.",
"visitor-log": "Posjetitelj iz <b>{country}</b> koristi <b>{browser}</b> na <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Letöltés",
"dropoff": "Lemorzsolódás",
"duration": "Időtartam",
"min-duration-seconds": "Minimális időtartam (másodperc)",
"edit": "Módosítás",
"edit-member": "Tag szerkesztése",
"email": "E-mail",
@@ -430,6 +431,7 @@
"triggered-event": "Kiváltott esemény",
"unauthorized": "Nincs jogosultság",
"user-deleted": "Felhasználó törölve.",
"replay-min-duration-description": "Csak az ezzel az időtartammal vagy annál hosszabb visszajátszásokat mutasd.",
"viewed-page": "Megtekintett oldal",
"upgrade-required": "Ez a funkció {plan} előfizetést igényel.",
"visitor-log": "Látógató <b>{country}</b> területéről, <b>{os}</b> <b>{device}</b> eszközön, <b>{browser}</b> böngészőből."
+2
View File
@@ -103,6 +103,7 @@
"download": "Unduh",
"dropoff": "Penurunan",
"duration": "Durasi",
"min-duration-seconds": "Durasi minimum (detik)",
"edit": "Sunting",
"edit-member": "Sunting anggota",
"email": "Email",
@@ -430,6 +431,7 @@
"triggered-event": "Peristiwa terjadi",
"unauthorized": "Tidak diotorisasi",
"user-deleted": "Pengguna telah dihapus.",
"replay-min-duration-description": "Hanya tampilkan ulangan dengan durasi ini atau lebih.",
"viewed-page": "Halaman dilihat",
"upgrade-required": "Fitur ini memerlukan langganan paket {plan}.",
"visitor-log": "Pengunjung dari <b>{country}</b> dengan <b>{browser}</b> di <b>{device}</b> <b>{os}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Scarica",
"dropoff": "Abbandono",
"duration": "Durata",
"min-duration-seconds": "Durata minima (secondi)",
"edit": "Modifica",
"edit-member": "Modifica membro",
"email": "Email",
@@ -430,6 +431,7 @@
"triggered-event": "Evento attivato",
"unauthorized": "Non autorizzato",
"user-deleted": "Utente eliminato.",
"replay-min-duration-description": "Mostra solo le riproduzioni con questa durata o superiore.",
"viewed-page": "Pagina visualizzata",
"upgrade-required": "Questa funzionalità richiede un abbonamento al piano {plan}.",
"visitor-log": "Utenti da <b>{country}</b> tramite <b>{browser}</b> su <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -102,6 +102,7 @@
"download": "ダウンロード",
"dropoff": "切り捨て",
"duration": "継続時間",
"min-duration-seconds": "最小時間(秒)",
"edit": "編集",
"edit-member": "メンバーの編集",
"email": "メール",
@@ -419,6 +420,7 @@
"triggered-event": "トリガーされたイベント",
"unauthorized": "認証が必要です",
"user-deleted": "ユーザーが削除されました。",
"replay-min-duration-description": "この時間以上の再生のみ表示します。",
"viewed-page": "閲覧されたページ",
"visitor-log": "<b>{os}</b>(<b>{device}</b>)で<b>{browser}</b>を使用している<b>{country}</b>からの訪問者"
}
+2
View File
@@ -102,6 +102,7 @@
"download": "ទាញយក",
"dropoff": "ការចាកចេញ",
"duration": "រយៈពេល",
"min-duration-seconds": "រយៈពេលអប្បបរមា (វិនាទី)",
"edit": "កែប្រែ",
"edit-member": "កែព័ត៌មានសមាជិក",
"email": "អ៊ីមែល",
@@ -419,6 +420,7 @@
"triggered-event": "ព្រឹត្តិការណ៍ដែលបានដំណើរការ",
"unauthorized": "មិនមានសិទ្ធិ",
"user-deleted": "អ្នកប្រើប្រាស់ត្រូវបានលុបចោល។",
"replay-min-duration-description": "បង្ហាញតែការចាក់ឡើងវិញដែលមានរយៈពេលនេះ ឬខ្ពស់ជាងនេះ។",
"viewed-page": "ទំព័រដែលបានមើល",
"visitor-log": "អ្នកមើលពីប្រទេស <b>{country}</b> ប្រើប្រាស់កម្មវិធី <b>{browser}</b> លើឧបករណ៍ <b>{os}</b> <b>{device}</b>"
}
+2
View File
@@ -102,6 +102,7 @@
"download": "다운로드",
"dropoff": "이탈",
"duration": "재생 시간",
"min-duration-seconds": "최소 지속 시간(초)",
"edit": "편집",
"edit-member": "멤버 편집",
"email": "이메일",
@@ -419,6 +420,7 @@
"triggered-event": "트리거된 이벤트",
"unauthorized": "인증되지 않음",
"user-deleted": "사용자를 삭제했습니다.",
"replay-min-duration-description": "이 지속 시간 이상의 리플레이만 표시합니다.",
"viewed-page": "조회한 페이지",
"visitor-log": "<b>{os}</b> <b>{device}</b>에서 <b>{browser}</b>을(를) 사용하는 <b>{country}</b>의 방문자"
}
+2
View File
@@ -103,6 +103,7 @@
"download": "Atsisiųsti",
"dropoff": "Atsitraukimas",
"duration": "Trukmė",
"min-duration-seconds": "Minimali trukmė (sekundės)",
"edit": "Redaguoti",
"edit-member": "Redaguoti narį",
"email": "El. paštas",
@@ -430,6 +431,7 @@
"triggered-event": "Suaktyvintas įvykis",
"unauthorized": "Neautorizuota",
"user-deleted": "Vartotojas ištrintas.",
"replay-min-duration-description": "Rodyti tik atkūrimus su šia arba didesne trukme.",
"viewed-page": "Peržiūrėtas puslapis",
"upgrade-required": "Šiai funkcijai reikalinga {plan} plano prenumerata.",
"visitor-log": "Lankytojas iš <b>{country}</b>, naudojantis <b>{browser}</b> sistemoje <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -102,6 +102,7 @@
"download": "Татах",
"dropoff": "Уналт",
"duration": "Хугацаа",
"min-duration-seconds": "Хамгийн бага үргэлжлэх хугацаа (секунд)",
"edit": "Засах",
"edit-member": "Гишүүн засах",
"email": "Имэйл",
@@ -419,6 +420,7 @@
"triggered-event": "Өдөөсөн үйлдэл",
"unauthorized": "Зөвшөөрөлгүй",
"user-deleted": "Хэрэглэгч устсан.",
"replay-min-duration-description": "Зөвхөн энэ эсвэл үүнээс их үргэлжлэх хугацаатай тоглуулалтуудыг харуул.",
"viewed-page": "Үзсэн хуудас",
"visitor-log": "<b>{country}</b> улсаас <b>{os}</b> <b>{device}</b> дээр <b>{browser}</b> хөтөч ашиглан орсон"
}
+2
View File
@@ -103,6 +103,7 @@
"download": "Muat turun",
"dropoff": "Tercicir",
"duration": "Tempoh",
"min-duration-seconds": "Tempoh minimum (saat)",
"edit": "Sunting",
"edit-member": "Sunting ahli",
"email": "E-mel",
@@ -430,6 +431,7 @@
"triggered-event": "Peristiwa yang dicetuskan",
"unauthorized": "Tidak dibenarkan",
"user-deleted": "Pengguna dipadamkan.",
"replay-min-duration-description": "Tunjukkan sahaja ulangan dengan tempoh ini atau lebih.",
"viewed-page": "Halaman dilihat",
"upgrade-required": "Ciri ini memerlukan langganan pelan {plan}.",
"visitor-log": "Pelawat dari <b>{country}</b> mengguna <b>{browser}</b> pada <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -102,6 +102,7 @@
"download": "ဒေါင်းလုဒ်လုပ်မည်",
"dropoff": "ထွက်ခွာမှု",
"duration": "ကြာချိန်",
"min-duration-seconds": "အနည်းဆုံး ကြာချိန် (စက္ကန့်)",
"edit": "ပြုပြင်မည်",
"edit-member": "အဖွဲ့ဝင် ပြင်ဆင်မည်",
"email": "အီးမေးလ်",
@@ -419,6 +420,7 @@
"triggered-event": "အစပျိုးလိုက်သော အဖြစ်အပျက်",
"unauthorized": "ခွင့်ပြုချက်မရှိပါ",
"user-deleted": "အသုံးပြုသူ ဖျက်ပြီးပါပြီ",
"replay-min-duration-description": "ဤကြာချိန် သို့မဟုတ် ၎င်းထက်ပိုသော ပြန်ဖွင့်မှုများကိုသာ ပြပါ။",
"viewed-page": "ကြည့်ရှုခဲ့သောစာမျက်နှာ",
"visitor-log": "<b>{country}</b> မှ <b>{browser}</b> ဖြင့် <b>{os}</b> <b>{device}</b> တွင် ဝင်ရောက်ကြည့်ရှုသူ"
}
+2
View File
@@ -103,6 +103,7 @@
"download": "Last ned",
"dropoff": "Frafall",
"duration": "Varighet",
"min-duration-seconds": "Minimumsvarighet (sekunder)",
"edit": "Rediger",
"edit-member": "Rediger bruker",
"email": "E-post",
@@ -430,6 +431,7 @@
"triggered-event": "Utløst hendelse",
"unauthorized": "Ikke autorisert",
"user-deleted": "Bruker slettet.",
"replay-min-duration-description": "Vis bare avspillinger med denne varigheten eller lenger.",
"viewed-page": "Vist side",
"upgrade-required": "Denne funksjonen krever et {plan}-abonnement.",
"visitor-log": "Besøkende fra <b>{country}</b> med <b>{browser}</b> på <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Downloaden",
"dropoff": "Uitval",
"duration": "Duur",
"min-duration-seconds": "Minimale duur (seconden)",
"edit": "Bewerken",
"edit-member": "Gebruiker aanpassen",
"email": "E-mail",
@@ -430,6 +431,7 @@
"triggered-event": "Getriggerde gebeurtenis",
"unauthorized": "Niet geautoriseerd",
"user-deleted": "Gebruiker verwijderd",
"replay-min-duration-description": "Toon alleen herhalingen met deze of een langere duur.",
"viewed-page": "Bekeken pagina",
"upgrade-required": "Deze functie vereist een {plan}-abonnement.",
"visitor-log": "Bezoeker uit <b>{country}</b> met <b>{browser}</b> op een <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Pobierz",
"dropoff": "Odpływ",
"duration": "Czas trwania",
"min-duration-seconds": "Minimalny czas trwania (sekundy)",
"edit": "Edytuj",
"edit-member": "Edytuj członka",
"email": "E-mail",
@@ -430,6 +431,7 @@
"triggered-event": "Zdarzenie wyzwalające",
"unauthorized": "Brak autoryzacji",
"user-deleted": "Użytkownik usunięty.",
"replay-min-duration-description": "Pokazuj tylko nagrania o tej lub dłuższej długości.",
"viewed-page": "Obejrzana strona",
"upgrade-required": "Ta funkcja wymaga subskrypcji planu {plan}.",
"visitor-log": "Odwiedzający z <b>{country}</b> używa <b>{browser}</b> na <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Download",
"dropoff": "Abandono",
"duration": "Duração",
"min-duration-seconds": "Duração mínima (segundos)",
"edit": "Editar",
"edit-member": "Editar membro",
"email": "E-mail",
@@ -430,6 +431,7 @@
"triggered-event": "Evento disparado",
"unauthorized": "Não autorizado",
"user-deleted": "Usuário excluído.",
"replay-min-duration-description": "Mostrar apenas repetições com esta duração ou superior.",
"viewed-page": "Página visualizada",
"upgrade-required": "Este recurso requer uma assinatura do plano {plan}.",
"visitor-log": "Visitante de <b>{country}</b> usando o navegador <b>{browser}</b> em um <b>{device}</b> com sistema operacional <b>{os}</b>."
+2
View File
@@ -103,6 +103,7 @@
"download": "Transferir",
"dropoff": "Abandono",
"duration": "Duração",
"min-duration-seconds": "Duração mínima (segundos)",
"edit": "Editar",
"edit-member": "Editar membro",
"email": "E-mail",
@@ -430,6 +431,7 @@
"triggered-event": "Evento acionado",
"unauthorized": "Não autorizado",
"user-deleted": "Utilizador eliminado.",
"replay-min-duration-description": "Mostrar apenas repetições com esta duração ou superior.",
"viewed-page": "Página visualizada",
"upgrade-required": "Esta funcionalidade requer uma subscrição do plano {plan}.",
"visitor-log": "Visitante de <b>{country}</b> a usar <b>{browser}</b> no <b>{device}</b> <b>{os}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Descarcă",
"dropoff": "Rată de abandon",
"duration": "Durată",
"min-duration-seconds": "Durată minimă (secunde)",
"edit": "Editare",
"edit-member": "Editare membru",
"email": "Email",
@@ -430,6 +431,7 @@
"triggered-event": "Eveniment declanșat",
"unauthorized": "Neautorizat",
"user-deleted": "Utilizator șters.",
"replay-min-duration-description": "Afișează doar reluările cu această durată sau mai mare.",
"viewed-page": "Pagină vizualizată",
"upgrade-required": "Această funcție necesită un abonament {plan}.",
"visitor-log": "Vizitator din <b>{country}</b> folosind <b>{browser}</b> pe <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -102,6 +102,7 @@
"download": "Скачать",
"dropoff": "Высадка",
"duration": "Длительность",
"min-duration-seconds": "Минимальная продолжительность (секунды)",
"edit": "Изменить",
"edit-member": "Редактировать участника",
"email": "Электронная почта",
@@ -419,6 +420,7 @@
"triggered-event": "Запущенное событие",
"unauthorized": "Не авторизован",
"user-deleted": "Пользователь удален.",
"replay-min-duration-description": "Показывать только воспроизведения с такой или большей продолжительностью.",
"viewed-page": "Просмотренная страница",
"visitor-log": "Посетитель из <b>{country}</b> используя <b>{browser}</b> на <b>{os}</b> <b>{device}</b>"
}
+2
View File
@@ -102,6 +102,7 @@
"download": "බාගන්න",
"dropoff": "අතහැර යෑම",
"duration": "කාලය",
"min-duration-seconds": "අවම කාලය (තත්පර)",
"edit": "සංස්කරණය කරන්න",
"edit-member": "සාමාජිකයා සංස්කරණය",
"email": "විද්‍යුත් තැපෑල",
@@ -419,6 +420,7 @@
"triggered-event": "අවුලුවන ලද සිදුවීම",
"unauthorized": "අනවසරයි",
"user-deleted": "පරිශීලකයා මකා දමන ලදි.",
"replay-min-duration-description": "මෙම කාලය හෝ ඊට වඩා වැඩි රිප්ලේ පමණක් පෙන්වන්න.",
"viewed-page": "නැරඹූ පිටුව",
"visitor-log": "<b>{country}</b> සිට <b>{os}</b> <b>{device}</b> හි <b>{browser}</b> භාවිතා කරන නරඹන්නා"
}
+2
View File
@@ -103,6 +103,7 @@
"download": "Stiahnuť",
"dropoff": "Odchod",
"duration": "Trvanie",
"min-duration-seconds": "Minimálne trvanie (sekundy)",
"edit": "Upraviť",
"edit-member": "Upraviť člena",
"email": "E-mail",
@@ -430,6 +431,7 @@
"triggered-event": "Spustená udalosť",
"unauthorized": "Neautorizované",
"user-deleted": "Používateľ vymazaný.",
"replay-min-duration-description": "Zobrazovať len nahrávky s touto alebo dlhšou dĺžkou.",
"viewed-page": "Zobrazená stránka",
"upgrade-required": "Táto funkcia vyžaduje predplatné plánu {plan}.",
"visitor-log": "Návštevník z <b>{country}</b> s prehliadačom <b>{browser}</b> na <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -103,6 +103,7 @@
"download": "Prenesi",
"dropoff": "Zapustitev",
"duration": "Trajanje",
"min-duration-seconds": "Minimalno trajanje (sekunde)",
"edit": "Uredi",
"edit-member": "Uredi člana",
"email": "E-pošta",
@@ -433,6 +434,7 @@
"triggered-event": "Sprožen dogodek",
"unauthorized": "Nepooblaščen dostop",
"user-deleted": "Uporabnik je izbrisan.",
"replay-min-duration-description": "Prikaži samo posnetke s tem ali daljšim trajanjem.",
"viewed-page": "Ogledana stran",
"upgrade-required": "Ta funkcija zahteva naročnino na paket {plan}.",
"visitor-log": "Obiskovalec iz <b>{country}</b> uporablja <b>{browser}</b> na <b>{os}</b> <b>{device}</b>",
+2
View File
@@ -103,6 +103,7 @@
"download": "Ladda ner",
"dropoff": "Bortfall",
"duration": "Varaktighet",
"min-duration-seconds": "Minsta varaktighet (sekunder)",
"edit": "Redigera",
"edit-member": "Redigera medlem",
"email": "E-post",
@@ -430,6 +431,7 @@
"triggered-event": "Utlöst händelse",
"unauthorized": "Inte auktoriserad",
"user-deleted": "Användaren har raderats.",
"replay-min-duration-description": "Visa bara uppspelningar med den här varaktigheten eller längre.",
"viewed-page": "Visad sida",
"upgrade-required": "Den här funktionen kräver en {plan}-prenumeration.",
"visitor-log": "Besökare från <b>{country}</b> med <b>{browser}</b> på <b>{os}</b> <b>{device}</b>"
+2
View File
@@ -102,6 +102,7 @@
"download": "பதிவிறக்கு",
"dropoff": "விலகல்",
"duration": "கால அளவு",
"min-duration-seconds": "குறைந்தபட்ச கால அளவு (விநாடிகள்)",
"edit": "திருத்துதல்",
"edit-member": "உறுப்பினரைத் திருத்து",
"email": "மின்னஞ்சல்",
@@ -419,6 +420,7 @@
"triggered-event": "தூண்டப்பட்ட நிகழ்வு",
"unauthorized": "அங்கீகரிக்கப்படவில்லை",
"user-deleted": "பயனர் நீக்கப்பட்டார்.",
"replay-min-duration-description": "இந்த காலவரையறை அல்லது அதற்கும் அதிகமான மறுஒலிப்புகளை மட்டும் காட்டு.",
"viewed-page": "பார்வையிட்ட பக்கம்",
"visitor-log": "<b>{country}</b>வில் இருந்து பார்வையாளர் <b>{browser}</b> ஐ <b>{os}</b> <b>{device}</b>லில் பயன்படுத்துகிறார்"
}
+2
View File
@@ -102,6 +102,7 @@
"download": "ดาวน์โหลด",
"dropoff": "การออกจากระบบ",
"duration": "ระยะเวลา",
"min-duration-seconds": "ระยะเวลาขั้นต่ำ (วินาที)",
"edit": "แก้ไข",
"edit-member": "แก้ไขสมาชิก",
"email": "อีเมล",
@@ -419,6 +420,7 @@
"triggered-event": "เหตุการณ์ที่ถูกเรียก",
"unauthorized": "ไม่ได้รับอนุญาต",
"user-deleted": "ผู้ใช้ถูกลบแล้ว",
"replay-min-duration-description": "แสดงเฉพาะการเล่นซ้ำที่มีระยะเวลาเท่ากับหรือมากกว่านี้",
"viewed-page": "หน้าที่ดู",
"visitor-log": "ผู้เข้าชมจาก <b>{country}</b> กำลังใช้งานผ่าน <b>{browser}</b> บน <b>{os}</b> <b>{device}</b>"
}
+2
View File
@@ -103,6 +103,7 @@
"download": "İndir",
"dropoff": "Bırakma",
"duration": "Süre",
"min-duration-seconds": "Minimum süre (saniye)",
"edit": "Düzenle",
"edit-member": "Üyeyi düzenle",
"email": "E-posta",
@@ -430,6 +431,7 @@
"triggered-event": "Tetiklenen olay",
"unauthorized": "Yetkisiz",
"user-deleted": "Kullanıcı silindi.",
"replay-min-duration-description": "Yalnızca bu süre veya daha uzun süren yeniden oynatmaları göster.",
"viewed-page": "Görüntülenen sayfa",
"upgrade-required": "Bu özellik {plan} plan aboneliği gerektirir.",
"visitor-log": "Yeni ziyaretçi: <b>{country}</b>, <b>{os}</b>, <b>{device}</b>, <b>{browser}</b>"
+2
View File
@@ -102,6 +102,7 @@
"download": "Завантажити",
"dropoff": "Відсів",
"duration": "Тривалість",
"min-duration-seconds": "Мінімальна тривалість (секунди)",
"edit": "Редагувати",
"edit-member": "Редагувати учасника",
"email": "Електронна пошта",
@@ -419,6 +420,7 @@
"triggered-event": "Подія, що спрацювала",
"unauthorized": "Не авторизовано",
"user-deleted": "Користувача видалено.",
"replay-min-duration-description": "Показувати лише відтворення з такою або більшою тривалістю.",
"viewed-page": "Переглянута сторінка",
"visitor-log": "Відвідувач з <b>{country}</b> використовуючи <b>{browser}</b> на <b>{os}</b> <b>{device}</b>"
}
+2
View File
@@ -102,6 +102,7 @@
"download": "ڈاؤن لوڈ",
"dropoff": "ڈراپ آف",
"duration": "مدت",
"min-duration-seconds": "کم از کم مدت (سیکنڈ)",
"edit": "ترمیم",
"edit-member": "رکن میں ترمیم",
"email": "ای میل",
@@ -419,6 +420,7 @@
"triggered-event": "متحرک واقعہ",
"unauthorized": "غیر مجاز",
"user-deleted": "صارف حذف ہو گیا۔",
"replay-min-duration-description": "صرف وہ ری پلے دکھائیں جو اس مدت یا اس سے زیادہ ہوں۔",
"viewed-page": "دیکھا گیا صفحہ",
"visitor-log": "<b>{os}</b> <b>{device}</b> پر <b>{browser}</b> کا استعمال کرتے ہوئے <b>{country}</b> سے آنے والا"
}
+2
View File
@@ -103,6 +103,7 @@
"download": "Yuklab olish",
"dropoff": "Tashlab ketish",
"duration": "Davomiylik",
"min-duration-seconds": "Minimal davomiylik (soniya)",
"edit": "Tahrirlash",
"edit-member": "A'zoni tahrirlash",
"email": "Elektron pochta",
@@ -435,6 +436,7 @@
"triggered-event": "Hodisa ishga tushirildi",
"unauthorized": "Ruxsatsiz",
"user-deleted": "Foydalanuvchi oʻchirildi.",
"replay-min-duration-description": "Faqat shu yoki undan yuqori davomiylikdagi takrorlarni ko'rsatish.",
"viewed-page": "Sahifa koʻrildi",
"upgrade-required": "Bu xususiyat {plan} tarif obunasini talab qiladi.",
"visitor-log": "<b>{os}</b> <b>{device}</b> da <b>{browser}</b> dan foydalanayotgan <b>{country}</b> dan tashrif buyuruvchi",
+2
View File
@@ -102,6 +102,7 @@
"download": "Tải xuống",
"dropoff": "Tỷ lệ bỏ qua",
"duration": "Thời lượng",
"min-duration-seconds": "Thời lượng tối thiểu (giây)",
"edit": "Chỉnh sửa",
"edit-member": "Chỉnh sửa thành viên",
"email": "Email",
@@ -424,6 +425,7 @@
"triggered-event": "Sự kiện được kích hoạt",
"unauthorized": "Chưa được xác thực",
"user-deleted": "Người dùng đã bị xóa.",
"replay-min-duration-description": "Chỉ hiển thị các lần phát lại có thời lượng bằng hoặc trên mức này.",
"viewed-page": "Đã xem trang",
"visitor-log": "Khách từ <b>{country}</b> đang sử dụng <b>{browser}</b> trên <b>{os}</b> <b>{device}</b>",
"visitors-dropped-off": "Khách truy cập đã rời đi"
+2
View File
@@ -102,6 +102,7 @@
"download": "下载",
"dropoff": "丢弃",
"duration": "持续时间",
"min-duration-seconds": "最短时长(秒)",
"edit": "编辑",
"edit-member": "编辑成员",
"email": "邮箱",
@@ -419,6 +420,7 @@
"triggered-event": "触发事件",
"unauthorized": "未授权",
"user-deleted": "用户已删除。",
"replay-min-duration-description": "只显示时长达到或超过此值的回放。",
"viewed-page": "已浏览页面",
"visitor-log": "来自 <b>{country}</b> 的访客在搭载 <b>{os}</b> 的 <b>{device}</b> 上使用 <b>{browser}</b> 浏览器进行访问。"
}
+2
View File
@@ -102,6 +102,7 @@
"download": "下載",
"dropoff": "離開",
"duration": "持續時間",
"min-duration-seconds": "最短時長(秒)",
"edit": "編輯",
"edit-member": "編輯成員",
"email": "電子郵件",
@@ -419,6 +420,7 @@
"triggered-event": "已觸發的事件",
"unauthorized": "未經授權",
"user-deleted": "使用者已刪除。",
"replay-min-duration-description": "只顯示時長達到或超過此值的回放。",
"viewed-page": "已瀏覽的網頁",
"visitor-log": "來自 <b>{country}</b> 的訪客在 <b>{device}</b> 上的 <b>{os}</b> 使用 <b>{browser}</b> 瀏覽。"
}
@@ -286,8 +286,9 @@ function ClickHeatmapView({
: '100%';
const overlayPageW = snapshot?.pageW ?? viewport?.pageW ?? baseWidth;
const overlayPageH = snapshot?.pageH ?? viewport?.pageH ?? baseHeight;
const showSnapshot = renderWidth > 0 && showPage && hasSnapshot;
const showOverlay = !showSnapshot || snapshotReady;
const shouldRenderSnapshot = renderWidth > 0 && hasSnapshot;
const showSnapshot = shouldRenderSnapshot && showPage;
const showOverlay = !showPage || !shouldRenderSnapshot || snapshotReady;
const totalClicks = visible.reduce((sum, point) => sum + point.count, 0);
const showLoading = isLoading;
@@ -345,12 +346,14 @@ function ClickHeatmapView({
<>
<div className={styles.snapshotClip}>
{showSnapshot && !snapshotReady && <CanvasLoading />}
{showSnapshot && snapshot && (
<SnapshotPreview
websiteId={websiteId}
snapshot={snapshot}
onReady={handleSnapshotReady}
/>
{shouldRenderSnapshot && snapshot && (
<div hidden={!showPage}>
<SnapshotPreview
websiteId={websiteId}
snapshot={snapshot}
onReady={handleSnapshotReady}
/>
</div>
)}
</div>
{showOverlay && (
@@ -445,8 +448,9 @@ function ScrollHeatmapView({
? `${renderWidth}px`
: `min(100%, ${renderWidth}px)`
: '100%';
const showSnapshot = renderWidth > 0 && showPage && hasSnapshot;
const showOverlay = !showSnapshot || snapshotReady;
const shouldRenderSnapshot = renderWidth > 0 && hasSnapshot;
const showSnapshot = shouldRenderSnapshot && showPage;
const showOverlay = !showPage || !shouldRenderSnapshot || snapshotReady;
const hasScrollData = Boolean(scroll && totalSessions > 0 && pageW && pageH && viewportW);
const showLoading = isLoading;
@@ -520,12 +524,14 @@ function ScrollHeatmapView({
) : (
<div className={styles.canvasClip}>
{showSnapshot && !snapshotReady && <CanvasLoading />}
{showSnapshot && snapshot && (
<SnapshotPreview
websiteId={websiteId}
snapshot={snapshot}
onReady={handleSnapshotReady}
/>
{shouldRenderSnapshot && snapshot && (
<div hidden={!showPage}>
<SnapshotPreview
websiteId={websiteId}
snapshot={snapshot}
onReady={handleSnapshotReady}
/>
</div>
)}
{showOverlay && (
<div className={styles.overlay}>
@@ -0,0 +1,96 @@
'use client';
import { Button, Column, Label, Row, Text, TextField } from '@umami/react-zen';
import { useState } from 'react';
import { useMessages, useNavigation } from '@/components/hooks';
import { ListFilter } from '@/components/icons';
import { DialogButton } from '@/components/input/DialogButton';
const DEFAULT_MIN_DURATION = '5';
function getMinDurationValue(value: unknown) {
if (value === '0') {
return '';
}
if (typeof value !== 'string' || !/^\d+$/.test(value)) {
return DEFAULT_MIN_DURATION;
}
return Number(value) > 0 ? value : DEFAULT_MIN_DURATION;
}
function ReplayFilterForm({
minDuration,
onClose,
}: {
minDuration: string;
onClose?: () => void;
}) {
const { t, labels, messages } = useMessages();
const { router, updateParams } = useNavigation();
const [value, setValue] = useState(minDuration);
const handleChange = (nextValue: string) => {
if (/^\d*$/.test(nextValue)) {
setValue(nextValue);
}
};
const handleReset = () => {
setValue(DEFAULT_MIN_DURATION);
};
const handleApply = () => {
const nextValue = value ? Number(value) : 0;
router.push(
updateParams({
minDuration: nextValue > 0 ? nextValue : 0,
page: 1,
}),
);
onClose?.();
};
return (
<Column width="320px" gap="4">
<Column gap="2">
<Label>{t(labels.minDurationSeconds)}</Label>
<Text color="muted">{t(messages.replayMinDurationDescription)}</Text>
<TextField
value={value}
onChange={handleChange}
autoFocus
autoComplete="off"
inputMode="numeric"
placeholder="10"
/>
</Column>
<Row alignItems="center" justifyContent="space-between" gap>
<Button onPress={handleReset}>{t(labels.reset)}</Button>
<Row alignItems="center" justifyContent="flex-end" gap>
<Button onPress={onClose}>{t(labels.cancel)}</Button>
<Button variant="primary" onPress={handleApply}>
{t(labels.apply)}
</Button>
</Row>
</Row>
</Column>
);
}
export function ReplayFilterButton() {
const { t, labels } = useMessages();
const { query } = useNavigation();
const minDuration = getMinDurationValue(query.minDuration);
const title = `${t(labels.replay)} ${t(labels.filter)}`;
const label = minDuration ? `${title} (${minDuration}s+)` : title;
return (
<DialogButton icon={<ListFilter />} label={label} title={title} variant="outline">
{({ close }) => <ReplayFilterForm minDuration={minDuration} onClose={close} />}
</DialogButton>
);
}
@@ -1,12 +1,25 @@
import { DataGrid } from '@/components/common/DataGrid';
import { useReplaysQuery } from '@/components/hooks';
import { useNavigation, useReplaysQuery } from '@/components/hooks';
import { ReplayFilterButton } from './ReplayFilterButton';
import { ReplaysTable } from './ReplaysTable';
const DEFAULT_MIN_DURATION = 5;
export function ReplaysDataTable({ websiteId }: { websiteId: string }) {
const queryResult = useReplaysQuery(websiteId);
const { query } = useNavigation();
const minDuration =
typeof query.minDuration === 'string' && /^\d+$/.test(query.minDuration)
? query.minDuration
: String(DEFAULT_MIN_DURATION);
const queryResult = useReplaysQuery(websiteId, { minDuration });
return (
<DataGrid query={queryResult} allowPaging allowSearch>
<DataGrid
query={queryResult}
allowPaging
allowSearch
renderActions={() => <ReplayFilterButton />}
>
{({ data }) => {
return <ReplaysTable data={data} />;
}}
@@ -1,6 +1,6 @@
import { getQueryFilters, parseRequest } from '@/lib/request';
import { json, unauthorized } from '@/lib/response';
import { filterParams, pagingParams, searchParams, withDateRange } from '@/lib/schema';
import { filterParams, pagingParams, replayParams, searchParams, withDateRange } from '@/lib/schema';
import { canViewAuthenticatedWebsite } from '@/permissions';
import { getSessionReplays } from '@/queries/sql';
@@ -10,6 +10,7 @@ export async function GET(
) {
const schema = withDateRange({
...filterParams,
...replayParams,
...pagingParams,
...searchParams,
});
+2
View File
@@ -385,6 +385,7 @@ export const labels: Record<string, string> = {
replayEnabled: 'label.replay-enabled',
recorderCode: 'label.recorder-code',
sampleRate: 'label.sample-rate',
minDurationSeconds: 'label.min-duration-seconds',
maskLevel: 'label.mask-level',
maxDuration: 'label.max-duration',
blockSelector: 'label.block-selector',
@@ -442,4 +443,5 @@ export const messages: Record<string, string> = {
notFound: 'message.not-found',
serverError: 'message.sever-error',
upgradeRequired: 'message.upgrade-required',
replayMinDurationDescription: 'message.replay-min-duration-description',
};
-348
View File
@@ -1,348 +0,0 @@
{
"label.access-code": "Pristupni kod",
"label.actions": "Akcije",
"label.activity": "Dnevnik aktivnosti",
"label.add": "Dodaj",
"label.add-board": "Dodaj ploču",
"label.add-description": "Dodaj opis",
"label.add-member": "Dodaj člana",
"label.add-step": "Dodaj korak",
"label.add-website": "Dodaj web stranicu",
"label.admin": "Administrator",
"label.affiliate": "Partner",
"label.after": "Nakon",
"label.all": "Sve",
"label.all-time": "Svo vrijeme",
"label.analytics": "Analitika",
"label.apply": "Primijeni",
"label.attribution": "Atribucija",
"label.attribution-description": "Pogledajte kako korisnici komuniciraju s vašim marketingom i što dovodi do konverzija.",
"label.average": "Prosjek",
"label.back": "Natrag",
"label.before": "Prije",
"label.behavior": "Ponašanje",
"label.boards": "Ploče",
"label.bounce-rate": "Stopa napuštanja",
"label.breakdown": "Raščlamba",
"label.browser": "Preglednik",
"label.browsers": "Preglednici",
"label.campaigns": "Kampanje",
"label.cancel": "Odustani",
"label.change-password": "Promijeni lozinku",
"label.channel": "Kanal",
"label.channels": "Kanali",
"label.cities": "Gradovi",
"label.city": "Grad",
"label.clear-all": "Očisti sve",
"label.cohort": "Kohorta",
"label.cohorts": "Kohorte",
"label.compare": "Usporedi",
"label.compare-dates": "Usporedi datume",
"label.confirm": "Potvrdi",
"label.confirm-password": "Potvrdi lozinku",
"label.contains": "Sadrži",
"label.content": "Sadržaj",
"label.continue": "Nastavi",
"label.conversion": "Konverzija",
"label.conversion-rate": "Stopa konverzije",
"label.conversion-step": "Korak konverzije",
"label.count": "Broj",
"label.countries": "Države",
"label.country": "Država",
"label.create": "Kreiraj",
"label.create-report": "Kreiraj izvještaj",
"label.create-team": "Kreiraj tim",
"label.create-user": "Kreiraj korisnika",
"label.created": "Kreirano",
"label.created-by": "Kreirao",
"label.currency": "Valuta",
"label.current": "Trenutno",
"label.current-password": "Trenutna lozinka",
"label.custom-range": "Prilagođeni raspon",
"label.dashboard": "Nadzorna ploča",
"label.data": "Podaci",
"label.date": "Datum",
"label.date-range": "Raspon datuma",
"label.day": "Dan",
"label.default-date-range": "Zadani datumski raspon",
"label.delete": "Obriši",
"label.delete-report": "Obriši izvještaj",
"label.delete-team": "Obriši tim",
"label.delete-user": "Obriši korisnika",
"label.delete-website": "Obriši web stranicu",
"label.description": "Opis",
"label.desktop": "Stolno računalo",
"label.details": "Detalji",
"label.device": "Uređaj",
"label.devices": "Uređaji",
"label.direct": "Direktno",
"label.dismiss": "Odbaci",
"label.distinct-id": "Jedinstveni ID",
"label.does-not-contain": "Ne sadrži",
"label.does-not-include": "Ne uključuje",
"label.doest-not-exist": "Ne postoji",
"label.domain": "Domena",
"label.dropoff": "Odlazak",
"label.edit": "Uredi",
"label.edit-dashboard": "Uredi nadzornu ploču",
"label.edit-member": "Uredi člana",
"label.email": "E-mail",
"label.enable-share-url": "Omogući dijeljenje poveznice",
"label.end-step": "Završni korak",
"label.entry": "Ulazni URL",
"label.event": "Interakcija",
"label.event-data": "Podaci interakcije",
"label.event-name": "Naziv interakcije",
"label.events": "Interakcije",
"label.exists": "Postoji",
"label.exit": "Izlazni URL",
"label.false": "Netočno",
"label.field": "Polje",
"label.fields": "Polja",
"label.filter": "Filter",
"label.filter-combined": "Kombinirano",
"label.filter-raw": "Izvorno",
"label.filters": "Filteri",
"label.first-click": "Prvi klik",
"label.first-seen": "Prvi put viđeno",
"label.funnel": "Tok",
"label.funnel-description": "Razumijte stopu konverzije i odlaska korisnika.",
"label.funnels": "Tokovi",
"label.goal": "Cilj",
"label.goals": "Ciljevi",
"label.goals-description": "Pratite ciljeve za prikaze stranica i korisničke interakcije.",
"label.greater-than": "Veće od",
"label.greater-than-equals": "Veće ili jednako",
"label.grouped": "Grupirano",
"label.hostname": "Naziv hosta",
"label.includes": "Uključuje",
"label.insight": "Uvid",
"label.insights": "Uvidi",
"label.insights-description": "Dublje analizirajte svoje podatke pomoću segmenata i filtera.",
"label.is": "Je",
"label.is-false": "Je netočno",
"label.is-not": "Nije",
"label.is-not-set": "Nije postavljeno",
"label.is-set": "Postavljeno",
"label.is-true": "Je točno",
"label.join": "Pridruži se",
"label.join-team": "Pridruži se timu",
"label.journey": "Korisnički put",
"label.journey-description": "Razumijte kako se korisnici kreću kroz vašu web stranicu.",
"label.journeys": "Korisnički putevi",
"label.language": "Jezik",
"label.languages": "Jezici",
"label.laptop": "Laptop",
"label.last-click": "Zadnji klik",
"label.last-days": "Zadnjih {x} dana",
"label.last-hours": "Zadnjih {x} sati",
"label.last-months": "Zadnjih {x} mjeseci",
"label.last-seen": "Zadnji put viđeno",
"label.leave": "Napusti",
"label.leave-team": "Napusti tim",
"label.less-than": "Manje od",
"label.less-than-equals": "Manje ili jednako",
"label.links": "Poveznice",
"label.login": "Prijava",
"label.logout": "Odjava",
"label.manage": "Upravljaj",
"label.manager": "Upravitelj",
"label.max": "Maksimum",
"label.maximize": "Proširi",
"label.medium": "Srednje",
"label.member": "Član",
"label.members": "Članovi",
"label.min": "Minimum",
"label.mobile": "Mobitel",
"label.model": "Model",
"label.more": "Više",
"label.my-account": "Moj račun",
"label.my-websites": "Moje web stranice",
"label.name": "Ime",
"label.new-password": "Nova lozinka",
"label.none": "Nijedan",
"label.number-of-records": "{x} {x, plural, one {zapis} other {zapisa}}",
"label.ok": "OK",
"label.online": "Online",
"label.organic-search": "Organsko pretraživanje",
"label.organic-shopping": "Organska kupovina",
"label.organic-social": "Organska društvena mreža",
"label.organic-video": "Organski videozapis",
"label.os": "OS",
"label.other": "Ostalo",
"label.overview": "Pregled",
"label.owner": "Vlasnik",
"label.page": "Stranica",
"label.page-of": "Stranica {current} od {total}",
"label.page-views": "Pregledi stranica",
"label.pageTitle": "Naslov stranice",
"label.pages": "Stranice",
"label.paid-ads": "Plaćeni oglasi",
"label.paid-search": "Plaćeno pretraživanje",
"label.paid-shopping": "Plaćena kupovina",
"label.paid-social": "Plaćena društvena mreža",
"label.paid-video": "Plaćeni videozapis",
"label.password": "Lozinka",
"label.path": "Putanja",
"label.paths": "Putanje",
"label.pixels": "Pikseli",
"label.powered-by": "Pokreće {name}",
"label.previous": "Prethodno",
"label.previous-period": "Prethodno razdoblje",
"label.previous-year": "Prethodna godina",
"label.profile": "Profil",
"label.properties": "Svojstva",
"label.property": "Svojstvo",
"label.queries": "Upiti",
"label.query": "Upit",
"label.query-parameters": "Parametri upita",
"label.realtime": "Stvarno vrijeme",
"label.referral": "Preporuka",
"label.referrer": "Izvor",
"label.referrers": "Izvori",
"label.refresh": "Osvježi",
"label.regenerate": "Regeneriraj",
"label.region": "Regija",
"label.regions": "Regije",
"label.remaining": "Preostalo",
"label.remove": "Ukloni",
"label.remove-member": "Ukloni člana",
"label.reports": "Izvještaji",
"label.required": "Obavezno",
"label.reset": "Resetiraj",
"label.reset-website": "Resetiraj web stranicu",
"label.retention": "Zadržavanje",
"label.retention-description": "Pratite koliko se često korisnici vraćaju na vašu web stranicu.",
"label.revenue": "Prihod",
"label.revenue-description": "Pogledajte svoj prihod tijekom vremena.",
"label.role": "Uloga",
"label.run-query": "Pokreni upit",
"label.save": "Spremi",
"label.screen": "Ekran",
"label.screens": "Ekrani",
"label.search": "Pretraživanje",
"label.select": "Odaberi",
"label.select-date": "Odaberi datum",
"label.select-filter": "Odaberi filter",
"label.select-role": "Odaberi ulogu",
"label.select-website": "Odaberi web stranicu",
"label.session": "Sesija",
"label.session-data": "Podaci sesije",
"label.sessions": "Sesije",
"label.settings": "Postavke",
"label.share": "Podijeli",
"label.share-url": "Podijeli poveznicu",
"label.single-day": "Jedan dan",
"label.sms": "SMS",
"label.sources": "Izvori",
"label.start-step": "Početni korak",
"label.steps": "Koraci",
"label.sum": "Zbroj",
"label.tablet": "Tablet",
"label.tag": "Oznaka",
"label.tags": "Oznake",
"label.team": "Tim",
"label.team-id": "ID tima",
"label.team-manager": "Voditelj tima",
"label.team-member": "Član tima",
"label.team-name": "Naziv tima",
"label.team-owner": "Vlasnik tima",
"label.team-settings": "Postavke tima",
"label.team-view-only": "Tim (samo pregled)",
"label.team-websites": "Web stranice tima",
"label.teams": "Timovi",
"label.terms": "Pojmovi",
"label.theme": "Tema",
"label.this-month": "Ovaj mjesec",
"label.this-week": "Ovaj tjedan",
"label.this-year": "Ova godina",
"label.timezone": "Vremenska zona",
"label.title": "Naslov",
"label.today": "Danas",
"label.toggle-charts": "Prikaži/sakrij grafikone",
"label.total": "Ukupno",
"label.total-records": "Ukupno zapisa",
"label.tracking-code": "Kod za praćenje",
"label.transactions": "Transakcije",
"label.transfer": "Prenesi",
"label.transfer-website": "Prenesi web stranicu",
"label.true": "Da",
"label.type": "Vrsta",
"label.unique": "Jedinstveno",
"label.unique-visitors": "Jedinstveni posjetitelji",
"label.uniqueCustomers": "Jedinstveni kupci",
"label.unknown": "Nepoznato",
"label.untitled": "Bez naslova",
"label.update": "Ažuriraj",
"label.user": "Korisnik",
"label.username": "Korisničko ime",
"label.users": "Korisnici",
"label.utm": "UTM",
"label.utm-description": "Pratite svoje kampanje putem UTM parametara.",
"label.value": "Vrijednost",
"label.view": "Prikaži",
"label.view-details": "Pogledaj detalje",
"label.view-only": "Samo pregled",
"label.views": "Pregledi",
"label.views-per-visit": "Pregledi po posjetu",
"label.visit-duration": "Trajanje posjeta",
"label.visitors": "Posjetitelji",
"label.visits": "Posjeti",
"label.website": "Web stranica",
"label.website-id": "ID web stranice",
"label.websites": "Web stranice",
"label.window": "Prozor",
"label.yesterday": "Jučer",
"label.environment": "Okruženje",
"label.criteria": "Kriteriji",
"label.location": "Lokacija",
"label.segments": "Segmenti",
"label.traffic": "Promet",
"label.support": "Podrška",
"message.action-confirmation": "Upišite {confirmation} u polje ispod kako biste potvrdili.",
"message.active-users": "{x} Trenutno {x, plural, one {posjetitelj} other {posjetitelja}}",
"message.bad-request": "Neispravan zahtjev",
"message.collected-data": "Prikupljeni podaci",
"message.confirm-delete": "Jeste li sigurni da želite obrisati {target}?",
"message.confirm-leave": "Jeste li sigurni da želite napustiti {target}?",
"message.confirm-remove": "Jeste li sigurni da želite ukloniti {target}?",
"message.confirm-reset": "Jeste li sigurni da želite resetirati statistiku za {target}?",
"message.delete-team-warning": "Brisanjem tima brišu se i sve web stranice tog tima.",
"message.delete-website-warning": "Svi podaci web stranice bit će obrisani.",
"message.error": "Nešto je pošlo po zlu.",
"message.event-log": "{event} na {url}",
"message.forbidden": "Zabranjeno",
"message.go-to-settings": "Idi u postavke",
"message.incorrect-username-password": "Neispravno korisničke ime ili lozinka.",
"message.invalid-domain": "Neispravna domena. Nemojte unositi http/https.",
"message.min-password-length": "Minimalna duljina je {n} znakova",
"message.new-version-available": "Dostupna je nova verzija - Umami {version}!",
"message.no-data-available": "Nema dostupnih podataka.",
"message.no-event-data": "Nema dostupnih podataka o događajima.",
"message.no-match-password": "Lozinke se ne podudaraju.",
"message.no-results-found": "Nema pronađenih rezultata.",
"message.no-team-websites": "Ovaj tim nema nijednu web stranicu.",
"message.no-teams": "Niste kreirali nijedan tim.",
"message.no-users": "Nema korisnika.",
"message.no-websites-configured": "Nemate konfiguriranih web stranica.",
"message.not-found": "Nije pronađeno",
"message.nothing-selected": "Ništa nije odabrano.",
"message.page-not-found": "Stranica nije pronađena.",
"message.reset-website": "Za resetiranje ove web stranice upišite {confirmation} u polje ispod.",
"message.reset-website-warning": "Sve statistike ove web stranice bit će obrisane, ali postavke ostaju sačuvane.",
"message.saved": "Spremljeno.",
"message.sever-error": "Greška na poslužitelju",
"message.share-url": "Ovo je javno dijeljena poveznica za {target}.",
"message.team-already-member": "Već ste član ovog tima.",
"message.team-not-found": "Tim nije pronađen.",
"message.team-websites-info": "Web stranice su vidljive svim članovima tima.",
"message.tracking-code": "Za praćenje statistike ove web stranice postavite sljedeći kod u <head>...</head> dio vašeg HTMLa.",
"message.transfer-team-website-to-user": "Želite prenijeti ovu web stranicu na vaš račun?",
"message.transfer-user-website-to-team": "Odaberite tim kojem želite prenijeti ovu web stranicu.",
"message.transfer-website": "Prenesite vlasništvo nad web stranicom na svoj račun ili drugi tim.",
"message.triggered-event": "Izvršen (triggered) događaj",
"message.unauthorized": "Nedozvoljen pristup",
"message.user-deleted": "Korisnik obrisan.",
"message.viewed-page": "Pregledana stranica",
"message.visitor-log": "Posjetitelj iz {country} koristi {browser} na {os} ({device})"
}
+1
View File
@@ -168,6 +168,7 @@ export async function getQueryFilters(
...dateRange,
...filters,
match,
minDuration: params?.minDuration,
page: params?.page,
pageSize: params?.pageSize ? params?.pageSize || DEFAULT_PAGE_SIZE : undefined,
orderBy: params?.orderBy,
+4
View File
@@ -74,6 +74,10 @@ export const searchParams = {
search: z.string().optional(),
};
export const replayParams = {
minDuration: z.coerce.number().int().nonnegative().optional(),
};
export const pagingParams = {
page: z.coerce.number().int().positive().optional(),
pageSize: z.coerce.number().int().positive().optional(),
+1
View File
@@ -124,6 +124,7 @@ export interface QueryFilters
SortParams,
PageParams,
SegmentParams {
minDuration?: number;
cohortFilters?: QueryFilters;
}
+16 -4
View File
@@ -16,7 +16,8 @@ export function getSessionReplays(
async function relationalQuery(websiteId: string, filters: QueryFilters, sessionId?: string) {
const { pagedRawQuery, parseFilters } = prisma;
const { search } = filters;
const { search, minDuration } = filters;
const minDurationMs = minDuration && minDuration > 0 ? minDuration * 1000 : undefined;
const { filterQuery, cohortQuery, queryParams, joinSessionQuery } = parseFilters({
...filters,
websiteId,
@@ -47,6 +48,10 @@ async function relationalQuery(websiteId: string, filters: QueryFilters, session
or session.device ilike {{search}})`
: '';
const havingQuery = minDurationMs
? `having sum(extract(epoch from sr.ended_at - sr.started_at) * 1000) >= {{minDurationMs}}`
: '';
return pagedRawQuery(
`
select
@@ -80,9 +85,10 @@ async function relationalQuery(websiteId: string, filters: QueryFilters, session
session.device,
session.country,
session.city
${havingQuery}
order by max(sr.created_at) desc
`,
{ ...queryParams, sessionId },
{ ...queryParams, sessionId, minDurationMs },
filters,
FUNCTION_NAME,
);
@@ -90,7 +96,8 @@ async function relationalQuery(websiteId: string, filters: QueryFilters, session
async function clickhouseQuery(websiteId: string, filters: QueryFilters, sessionId?: string) {
const { pagedRawQuery, parseFilters } = clickhouse;
const { search } = filters;
const { search, minDuration } = filters;
const minDurationMs = minDuration && minDuration > 0 ? minDuration * 1000 : undefined;
const { queryParams, cohortQuery, filterQuery } = parseFilters({
...filters,
websiteId,
@@ -106,6 +113,10 @@ async function clickhouseQuery(websiteId: string, filters: QueryFilters, session
or (positionCaseInsensitive(device, {search:String}) > 0))`
: '';
const havingQuery = minDurationMs
? `having toInt64(sum(dateDiff('millisecond', session_replay.started_at, session_replay.ended_at))) >= {minDurationMs:Int64}`
: '';
return pagedRawQuery(
`
select
@@ -140,9 +151,10 @@ async function clickhouseQuery(websiteId: string, filters: QueryFilters, session
and session_replay.created_at between {startDate:DateTime64} and {endDate:DateTime64}
${sessionFilter}
group by session_replay.visit_id, session_replay.session_id, session_replay.website_id, website_event.browser, website_event.os, website_event.device, website_event.country, website_event.city
${havingQuery}
order by max(created_at) desc
`,
{ ...queryParams, sessionId },
{ ...queryParams, sessionId, minDurationMs },
filters,
FUNCTION_NAME,
);