From c61c01e3bbeae718991d6f8003c5863e7f4731fc Mon Sep 17 00:00:00 2001 From: Francis Cao Date: Wed, 17 Jun 2026 11:38:57 -0700 Subject: [PATCH] implement session replay filters --- public/intl/messages/ar-SA.json | 2 + public/intl/messages/be-BY.json | 2 + public/intl/messages/bg-BG.json | 2 + public/intl/messages/bn-BD.json | 2 + public/intl/messages/bs-BA.json | 2 + public/intl/messages/ca-ES.json | 2 + public/intl/messages/cs-CZ.json | 2 + public/intl/messages/da-DK.json | 2 + public/intl/messages/de-CH.json | 2 + public/intl/messages/de-DE.json | 2 + public/intl/messages/el-GR.json | 2 + public/intl/messages/en-GB.json | 2 + public/intl/messages/en-US.json | 2 + public/intl/messages/es-ES.json | 2 + public/intl/messages/fa-IR.json | 2 + public/intl/messages/fi-FI.json | 2 + public/intl/messages/fo-FO.json | 2 + public/intl/messages/fr-FR.json | 2 + public/intl/messages/ga-ES.json | 2 + public/intl/messages/he-IL.json | 2 + public/intl/messages/hi-IN.json | 2 + public/intl/messages/hr-HR.json | 2 + public/intl/messages/hu-HU.json | 2 + public/intl/messages/id-ID.json | 2 + public/intl/messages/it-IT.json | 2 + public/intl/messages/ja-JP.json | 2 + public/intl/messages/km-KH.json | 2 + public/intl/messages/ko-KR.json | 2 + public/intl/messages/lt-LT.json | 2 + public/intl/messages/mn-MN.json | 2 + public/intl/messages/ms-MY.json | 2 + public/intl/messages/my-MM.json | 2 + public/intl/messages/nb-NO.json | 2 + public/intl/messages/nl-NL.json | 2 + public/intl/messages/pl-PL.json | 2 + public/intl/messages/pt-BR.json | 2 + public/intl/messages/pt-PT.json | 2 + public/intl/messages/ro-RO.json | 2 + public/intl/messages/ru-RU.json | 2 + public/intl/messages/si-LK.json | 2 + public/intl/messages/sk-SK.json | 2 + public/intl/messages/sl-SI.json | 2 + public/intl/messages/sv-SE.json | 2 + public/intl/messages/ta-IN.json | 2 + public/intl/messages/th-TH.json | 2 + public/intl/messages/tr-TR.json | 2 + public/intl/messages/uk-UA.json | 2 + public/intl/messages/ur-PK.json | 2 + public/intl/messages/uz-UZ.json | 2 + public/intl/messages/vi-VN.json | 2 + public/intl/messages/zh-CN.json | 2 + public/intl/messages/zh-TW.json | 2 + .../(reports)/heatmaps/Heatmap.tsx | 38 +- .../replays/ReplayFilterButton.tsx | 96 +++++ .../[websiteId]/replays/ReplaysDataTable.tsx | 19 +- .../api/websites/[websiteId]/replays/route.ts | 3 +- src/components/messages.ts | 2 + src/lang/hr-HR.json | 348 ------------------ src/lib/request.ts | 1 + src/lib/schema.ts | 4 + src/lib/types.ts | 1 + src/queries/sql/replays/getSessionReplays.ts | 20 +- 62 files changed, 264 insertions(+), 372 deletions(-) create mode 100644 src/app/(main)/websites/[websiteId]/replays/ReplayFilterButton.tsx delete mode 100644 src/lang/hr-HR.json diff --git a/public/intl/messages/ar-SA.json b/public/intl/messages/ar-SA.json index 6afb0ca2a..493bad789 100644 --- a/public/intl/messages/ar-SA.json +++ b/public/intl/messages/ar-SA.json @@ -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": "زائر من {country} يستخدم {browser} على {os} {device}" } diff --git a/public/intl/messages/be-BY.json b/public/intl/messages/be-BY.json index aefea288a..95ec22916 100644 --- a/public/intl/messages/be-BY.json +++ b/public/intl/messages/be-BY.json @@ -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": "Наведвальнік з {country} праз {browser} на {os} {device}" } diff --git a/public/intl/messages/bg-BG.json b/public/intl/messages/bg-BG.json index 2ff3a3122..0e48e4c6b 100644 --- a/public/intl/messages/bg-BG.json +++ b/public/intl/messages/bg-BG.json @@ -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": "Посетител от {country}, използващ {browser} на {os} {device}" } diff --git a/public/intl/messages/bn-BD.json b/public/intl/messages/bn-BD.json index 44764efe3..b30a21887 100644 --- a/public/intl/messages/bn-BD.json +++ b/public/intl/messages/bn-BD.json @@ -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": "{country} থেকে একজন ভিসিটর {ব্রাউজার}, ব্যবহার করছেন {os} {device} এর মধ্যে।" } diff --git a/public/intl/messages/bs-BA.json b/public/intl/messages/bs-BA.json index 9badc1eba..69474c7c9 100644 --- a/public/intl/messages/bs-BA.json +++ b/public/intl/messages/bs-BA.json @@ -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 {country} koristi {browser} na {os} {device}" diff --git a/public/intl/messages/ca-ES.json b/public/intl/messages/ca-ES.json index 24c183963..c5c556ee9 100644 --- a/public/intl/messages/ca-ES.json +++ b/public/intl/messages/ca-ES.json @@ -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 {country} usant {browser} a {os} {device}" diff --git a/public/intl/messages/cs-CZ.json b/public/intl/messages/cs-CZ.json index e9c155671..9d92813d9 100644 --- a/public/intl/messages/cs-CZ.json +++ b/public/intl/messages/cs-CZ.json @@ -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 {country} s prohlížečem {browser} na {os} {device}" diff --git a/public/intl/messages/da-DK.json b/public/intl/messages/da-DK.json index 5074a3604..4ba211f1a 100644 --- a/public/intl/messages/da-DK.json +++ b/public/intl/messages/da-DK.json @@ -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 {country} bruger {browser}{os} {device}" diff --git a/public/intl/messages/de-CH.json b/public/intl/messages/de-CH.json index 492399dbb..634305e39 100644 --- a/public/intl/messages/de-CH.json +++ b/public/intl/messages/de-CH.json @@ -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 {country} nutzt {browser} uf {os} {device}" diff --git a/public/intl/messages/de-DE.json b/public/intl/messages/de-DE.json index d91b39e29..2e409c152 100644 --- a/public/intl/messages/de-DE.json +++ b/public/intl/messages/de-DE.json @@ -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 {country} benutzt {browser} auf {os} {device}" diff --git a/public/intl/messages/el-GR.json b/public/intl/messages/el-GR.json index 056221704..f7680c38a 100644 --- a/public/intl/messages/el-GR.json +++ b/public/intl/messages/el-GR.json @@ -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": "Επισκέπτης από {country} χρησιμοποιώντας {browser} σε {os} {device}" } diff --git a/public/intl/messages/en-GB.json b/public/intl/messages/en-GB.json index ded4e0321..905df7987 100644 --- a/public/intl/messages/en-GB.json +++ b/public/intl/messages/en-GB.json @@ -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 {country} using {browser} on {os} {device}" diff --git a/public/intl/messages/en-US.json b/public/intl/messages/en-US.json index d4a150ead..0bed55aa6 100644 --- a/public/intl/messages/en-US.json +++ b/public/intl/messages/en-US.json @@ -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 {country} using {browser} on {os} {device}" diff --git a/public/intl/messages/es-ES.json b/public/intl/messages/es-ES.json index 1105468ff..4a14bb526 100644 --- a/public/intl/messages/es-ES.json +++ b/public/intl/messages/es-ES.json @@ -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 {country} usando {browser} en {os} {device}" diff --git a/public/intl/messages/fa-IR.json b/public/intl/messages/fa-IR.json index 776da45fe..62d280d24 100644 --- a/public/intl/messages/fa-IR.json +++ b/public/intl/messages/fa-IR.json @@ -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": "بازدیدکننده از کشور {country} با مروگر {browser} در {os} {device}" } diff --git a/public/intl/messages/fi-FI.json b/public/intl/messages/fi-FI.json index 4a0b4dd75..4c6ab8fb4 100644 --- a/public/intl/messages/fi-FI.json +++ b/public/intl/messages/fi-FI.json @@ -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 {country} selaimella {browser} laitteella {os} {device}" diff --git a/public/intl/messages/fo-FO.json b/public/intl/messages/fo-FO.json index 962f11294..5266b3d00 100644 --- a/public/intl/messages/fo-FO.json +++ b/public/intl/messages/fo-FO.json @@ -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á {country} brúkar {browser} á {os} {device}" diff --git a/public/intl/messages/fr-FR.json b/public/intl/messages/fr-FR.json index 2716b13f7..465d4fd72 100644 --- a/public/intl/messages/fr-FR.json +++ b/public/intl/messages/fr-FR.json @@ -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 {country} utilisant {browser} sur {os} {device}" } diff --git a/public/intl/messages/ga-ES.json b/public/intl/messages/ga-ES.json index 636c37577..f525961f5 100644 --- a/public/intl/messages/ga-ES.json +++ b/public/intl/messages/ga-ES.json @@ -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 {country} usando {browser} en {os} {device}" diff --git a/public/intl/messages/he-IL.json b/public/intl/messages/he-IL.json index 1853dad30..ff3daa0a1 100644 --- a/public/intl/messages/he-IL.json +++ b/public/intl/messages/he-IL.json @@ -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": "מבקר ממדינת {country} משתמבש בדפדפן {browser} ב-{os} {device}" } diff --git a/public/intl/messages/hi-IN.json b/public/intl/messages/hi-IN.json index d512983dc..8b3a9ff6e 100644 --- a/public/intl/messages/hi-IN.json +++ b/public/intl/messages/hi-IN.json @@ -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": "{country} का आगंतुक, जो {browser} का उपयोग करता है, {os} यन्त्र पर" } diff --git a/public/intl/messages/hr-HR.json b/public/intl/messages/hr-HR.json index 39f88754f..0089df553 100644 --- a/public/intl/messages/hr-HR.json +++ b/public/intl/messages/hr-HR.json @@ -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 {country} koristi {browser} na {os} {device}" diff --git a/public/intl/messages/hu-HU.json b/public/intl/messages/hu-HU.json index 8d38c888c..d8dfc9712 100644 --- a/public/intl/messages/hu-HU.json +++ b/public/intl/messages/hu-HU.json @@ -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ó {country} területéről, {os} {device} eszközön, {browser} böngészőből." diff --git a/public/intl/messages/id-ID.json b/public/intl/messages/id-ID.json index f9d1490d2..829f54864 100644 --- a/public/intl/messages/id-ID.json +++ b/public/intl/messages/id-ID.json @@ -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 {country} dengan {browser} di {device} {os}" diff --git a/public/intl/messages/it-IT.json b/public/intl/messages/it-IT.json index 97640259c..4f9724df1 100644 --- a/public/intl/messages/it-IT.json +++ b/public/intl/messages/it-IT.json @@ -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 {country} tramite {browser} su {os} {device}" diff --git a/public/intl/messages/ja-JP.json b/public/intl/messages/ja-JP.json index 758883939..c7c46f867 100644 --- a/public/intl/messages/ja-JP.json +++ b/public/intl/messages/ja-JP.json @@ -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": "{os}({device})で{browser}を使用している{country}からの訪問者" } diff --git a/public/intl/messages/km-KH.json b/public/intl/messages/km-KH.json index b93ec72ba..617bd6b96 100644 --- a/public/intl/messages/km-KH.json +++ b/public/intl/messages/km-KH.json @@ -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": "អ្នកមើលពីប្រទេស {country} ប្រើប្រាស់កម្មវិធី {browser} លើឧបករណ៍ {os} {device}" } diff --git a/public/intl/messages/ko-KR.json b/public/intl/messages/ko-KR.json index d7ebc68ff..b9d2e8669 100644 --- a/public/intl/messages/ko-KR.json +++ b/public/intl/messages/ko-KR.json @@ -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": "{os} {device}에서 {browser}을(를) 사용하는 {country}의 방문자" } diff --git a/public/intl/messages/lt-LT.json b/public/intl/messages/lt-LT.json index 0db00631b..1940d3caf 100644 --- a/public/intl/messages/lt-LT.json +++ b/public/intl/messages/lt-LT.json @@ -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š {country}, naudojantis {browser} sistemoje {os} {device}" diff --git a/public/intl/messages/mn-MN.json b/public/intl/messages/mn-MN.json index 7d9358a57..d4c7f2b28 100644 --- a/public/intl/messages/mn-MN.json +++ b/public/intl/messages/mn-MN.json @@ -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": "{country} улсаас {os} {device} дээр {browser} хөтөч ашиглан орсон" } diff --git a/public/intl/messages/ms-MY.json b/public/intl/messages/ms-MY.json index a1123d6e0..b14b36f43 100644 --- a/public/intl/messages/ms-MY.json +++ b/public/intl/messages/ms-MY.json @@ -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 {country} mengguna {browser} pada {os} {device}" diff --git a/public/intl/messages/my-MM.json b/public/intl/messages/my-MM.json index 5601c3aba..97b6dd3c2 100644 --- a/public/intl/messages/my-MM.json +++ b/public/intl/messages/my-MM.json @@ -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": "{country} မှ {browser} ဖြင့် {os} {device} တွင် ဝင်ရောက်ကြည့်ရှုသူ" } diff --git a/public/intl/messages/nb-NO.json b/public/intl/messages/nb-NO.json index 15c01af75..a0b01a98b 100644 --- a/public/intl/messages/nb-NO.json +++ b/public/intl/messages/nb-NO.json @@ -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 {country} med {browser}{os} {device}" diff --git a/public/intl/messages/nl-NL.json b/public/intl/messages/nl-NL.json index bea2bf0bc..39b062093 100644 --- a/public/intl/messages/nl-NL.json +++ b/public/intl/messages/nl-NL.json @@ -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 {country} met {browser} op een {os} {device}" diff --git a/public/intl/messages/pl-PL.json b/public/intl/messages/pl-PL.json index e18c84b61..67439d40c 100644 --- a/public/intl/messages/pl-PL.json +++ b/public/intl/messages/pl-PL.json @@ -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 {country} używa {browser} na {os} {device}" diff --git a/public/intl/messages/pt-BR.json b/public/intl/messages/pt-BR.json index 6a60dec60..990b9f8ca 100644 --- a/public/intl/messages/pt-BR.json +++ b/public/intl/messages/pt-BR.json @@ -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 {country} usando o navegador {browser} em um {device} com sistema operacional {os}." diff --git a/public/intl/messages/pt-PT.json b/public/intl/messages/pt-PT.json index 69ff702de..814e4a8a0 100644 --- a/public/intl/messages/pt-PT.json +++ b/public/intl/messages/pt-PT.json @@ -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 {country} a usar {browser} no {device} {os}" diff --git a/public/intl/messages/ro-RO.json b/public/intl/messages/ro-RO.json index 5172eed08..8b3de7c88 100644 --- a/public/intl/messages/ro-RO.json +++ b/public/intl/messages/ro-RO.json @@ -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 {country} folosind {browser} pe {os} {device}" diff --git a/public/intl/messages/ru-RU.json b/public/intl/messages/ru-RU.json index 3e3b016e1..37b443086 100644 --- a/public/intl/messages/ru-RU.json +++ b/public/intl/messages/ru-RU.json @@ -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": "Посетитель из {country} используя {browser} на {os} {device}" } diff --git a/public/intl/messages/si-LK.json b/public/intl/messages/si-LK.json index 88fd3bf23..57d5f37a9 100644 --- a/public/intl/messages/si-LK.json +++ b/public/intl/messages/si-LK.json @@ -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": "{country} සිට {os} {device} හි {browser} භාවිතා කරන නරඹන්නා" } diff --git a/public/intl/messages/sk-SK.json b/public/intl/messages/sk-SK.json index efe69bba5..0efd8ac66 100644 --- a/public/intl/messages/sk-SK.json +++ b/public/intl/messages/sk-SK.json @@ -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 {country} s prehliadačom {browser} na {os} {device}" diff --git a/public/intl/messages/sl-SI.json b/public/intl/messages/sl-SI.json index 23d5d9abc..d43a37a15 100644 --- a/public/intl/messages/sl-SI.json +++ b/public/intl/messages/sl-SI.json @@ -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 {country} uporablja {browser} na {os} {device}", diff --git a/public/intl/messages/sv-SE.json b/public/intl/messages/sv-SE.json index b468050ca..47936592e 100644 --- a/public/intl/messages/sv-SE.json +++ b/public/intl/messages/sv-SE.json @@ -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 {country} med {browser}{os} {device}" diff --git a/public/intl/messages/ta-IN.json b/public/intl/messages/ta-IN.json index cd8e6c58b..14380e89d 100644 --- a/public/intl/messages/ta-IN.json +++ b/public/intl/messages/ta-IN.json @@ -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": "{country}வில் இருந்து பார்வையாளர் {browser}{os} {device}லில் பயன்படுத்துகிறார்" } diff --git a/public/intl/messages/th-TH.json b/public/intl/messages/th-TH.json index ffa236483..9334629e3 100644 --- a/public/intl/messages/th-TH.json +++ b/public/intl/messages/th-TH.json @@ -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": "ผู้เข้าชมจาก {country} กำลังใช้งานผ่าน {browser} บน {os} {device}" } diff --git a/public/intl/messages/tr-TR.json b/public/intl/messages/tr-TR.json index 7f5fa2530..b68df7843 100644 --- a/public/intl/messages/tr-TR.json +++ b/public/intl/messages/tr-TR.json @@ -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: {country}, {os}, {device}, {browser}" diff --git a/public/intl/messages/uk-UA.json b/public/intl/messages/uk-UA.json index 89b1e95f2..467b744c5 100644 --- a/public/intl/messages/uk-UA.json +++ b/public/intl/messages/uk-UA.json @@ -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": "Відвідувач з {country} використовуючи {browser} на {os} {device}" } diff --git a/public/intl/messages/ur-PK.json b/public/intl/messages/ur-PK.json index 80b924b5c..511995ba4 100644 --- a/public/intl/messages/ur-PK.json +++ b/public/intl/messages/ur-PK.json @@ -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": "{os} {device} پر {browser} کا استعمال کرتے ہوئے {country} سے آنے والا" } diff --git a/public/intl/messages/uz-UZ.json b/public/intl/messages/uz-UZ.json index aaeccd3f8..134614492 100644 --- a/public/intl/messages/uz-UZ.json +++ b/public/intl/messages/uz-UZ.json @@ -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": "{os} {device} da {browser} dan foydalanayotgan {country} dan tashrif buyuruvchi", diff --git a/public/intl/messages/vi-VN.json b/public/intl/messages/vi-VN.json index ee1d78afd..1cef1d9a9 100644 --- a/public/intl/messages/vi-VN.json +++ b/public/intl/messages/vi-VN.json @@ -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ừ {country} đang sử dụng {browser} trên {os} {device}", "visitors-dropped-off": "Khách truy cập đã rời đi" diff --git a/public/intl/messages/zh-CN.json b/public/intl/messages/zh-CN.json index b3c4a37a1..5e6111f72 100644 --- a/public/intl/messages/zh-CN.json +++ b/public/intl/messages/zh-CN.json @@ -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": "来自 {country} 的访客在搭载 {os}{device} 上使用 {browser} 浏览器进行访问。" } diff --git a/public/intl/messages/zh-TW.json b/public/intl/messages/zh-TW.json index 1be610a48..ab8b5fd4a 100644 --- a/public/intl/messages/zh-TW.json +++ b/public/intl/messages/zh-TW.json @@ -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": "來自 {country} 的訪客在 {device} 上的 {os} 使用 {browser} 瀏覽。" } diff --git a/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.tsx b/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.tsx index 44f581568..f94790a02 100644 --- a/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.tsx +++ b/src/app/(main)/websites/[websiteId]/(reports)/heatmaps/Heatmap.tsx @@ -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({ <>
{showSnapshot && !snapshotReady && } - {showSnapshot && snapshot && ( - + {shouldRenderSnapshot && snapshot && ( + )}
{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({ ) : (
{showSnapshot && !snapshotReady && } - {showSnapshot && snapshot && ( - + {shouldRenderSnapshot && snapshot && ( + )} {showOverlay && (
diff --git a/src/app/(main)/websites/[websiteId]/replays/ReplayFilterButton.tsx b/src/app/(main)/websites/[websiteId]/replays/ReplayFilterButton.tsx new file mode 100644 index 000000000..da9b1d8b0 --- /dev/null +++ b/src/app/(main)/websites/[websiteId]/replays/ReplayFilterButton.tsx @@ -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 ( + + + + {t(messages.replayMinDurationDescription)} + + + + + + + + + + + ); +} + +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 ( + } label={label} title={title} variant="outline"> + {({ close }) => } + + ); +} diff --git a/src/app/(main)/websites/[websiteId]/replays/ReplaysDataTable.tsx b/src/app/(main)/websites/[websiteId]/replays/ReplaysDataTable.tsx index 6d047081d..3047b0b73 100644 --- a/src/app/(main)/websites/[websiteId]/replays/ReplaysDataTable.tsx +++ b/src/app/(main)/websites/[websiteId]/replays/ReplaysDataTable.tsx @@ -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 ( - + } + > {({ data }) => { return ; }} diff --git a/src/app/api/websites/[websiteId]/replays/route.ts b/src/app/api/websites/[websiteId]/replays/route.ts index d464fc42b..324aa9920 100644 --- a/src/app/api/websites/[websiteId]/replays/route.ts +++ b/src/app/api/websites/[websiteId]/replays/route.ts @@ -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, }); diff --git a/src/components/messages.ts b/src/components/messages.ts index caa56ef54..401284b34 100644 --- a/src/components/messages.ts +++ b/src/components/messages.ts @@ -385,6 +385,7 @@ export const labels: Record = { 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 = { notFound: 'message.not-found', serverError: 'message.sever-error', upgradeRequired: 'message.upgrade-required', + replayMinDurationDescription: 'message.replay-min-duration-description', }; diff --git a/src/lang/hr-HR.json b/src/lang/hr-HR.json deleted file mode 100644 index f560caa8c..000000000 --- a/src/lang/hr-HR.json +++ /dev/null @@ -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 ... dio vašeg HTML‑a.", - "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})" -} diff --git a/src/lib/request.ts b/src/lib/request.ts index 4aa2e8a7a..ddf7b7614 100644 --- a/src/lib/request.ts +++ b/src/lib/request.ts @@ -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, diff --git a/src/lib/schema.ts b/src/lib/schema.ts index 25a5f4726..a58623850 100644 --- a/src/lib/schema.ts +++ b/src/lib/schema.ts @@ -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(), diff --git a/src/lib/types.ts b/src/lib/types.ts index 94a14fab7..9544263bd 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -124,6 +124,7 @@ export interface QueryFilters SortParams, PageParams, SegmentParams { + minDuration?: number; cohortFilters?: QueryFilters; } diff --git a/src/queries/sql/replays/getSessionReplays.ts b/src/queries/sql/replays/getSessionReplays.ts index 8678f21b1..22f59973c 100644 --- a/src/queries/sql/replays/getSessionReplays.ts +++ b/src/queries/sql/replays/getSessionReplays.ts @@ -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, );