Merge pull request #1021 from openreplay/fix-clickmaps

fix(ui) - clickmaps
This commit is contained in:
Shekar Siri 2023-03-08 16:59:08 +01:00 committed by GitHub
commit a1e35083d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 27 additions and 34 deletions

View file

@ -20,6 +20,7 @@ function ClickMapCard({
const onMarkerClick = (s: string, innerText: string) => {
metricStore.changeClickMapSearch(s, innerText)
}
const mapUrl = metricStore.instance.series[0].filter.filters[0].value[0]
React.useEffect(() => {
return () => clearCurrentSession()
@ -32,12 +33,10 @@ function ClickMapCard({
React.useEffect(() => {
if (visitedEvents.length) {
const urlOptions = visitedEvents.map(({ url, host }: any) => ({ label: url, value: url, host }))
const url = insightsFilters.url ? insightsFilters.url : host + urlOptions[0].value;
const rangeValue = dashboardStore.drillDownPeriod.rangeValue
const startDate = dashboardStore.drillDownPeriod.start
const endDate = dashboardStore.drillDownPeriod.end
fetchInsights({ ...insightsFilters, url, startDate, endDate, rangeValue, clickRage: metricStore.clickMapFilter })
fetchInsights({ ...insightsFilters, url: mapUrl || '/', startDate, endDate, rangeValue, clickRage: metricStore.clickMapFilter })
}
}, [visitedEvents, metricStore.clickMapFilter])
@ -62,9 +61,8 @@ function ClickMapCard({
return <div className="py-2">Loading session</div>
}
const searchUrl = metricStore.instance.series[0].filter.filters[0].value[0]
const jumpToEvent = metricStore.instance.data.events.find((evt: Record<string, any>) => {
if (searchUrl) return evt.path.includes(searchUrl)
if (mapUrl) return evt.path.includes(mapUrl)
return evt
}) || { timestamp: metricStore.instance.data.startTs }

View file

@ -16,7 +16,6 @@ function Player() {
}
}, []);
if (!playerContext.player) return null;
return (

View file

@ -3,7 +3,6 @@ import Cursor from './Cursor'
import type { Point, Dimensions } from './types';
export type State = Dimensions
export const INITIAL_STATE: State = {
@ -182,7 +181,7 @@ export default class Screen {
getElementBySelector(selector: string) {
if (!selector) return null;
try {
const safeSelector = selector.replace(/:/g, '\\\\3A ').replace(/\//g, '\\/');
const safeSelector = selector.replace(/\//g, '\\/');
return this.document?.querySelector<HTMLElement>(safeSelector) || null;
} catch (e) {
console.error("Can not select element. ", e)
@ -218,7 +217,7 @@ export default class Screen {
case ScaleMode.AdjustParentHeight:
this.scaleRatio = offsetWidth / width
translate = "translate(-50%, 0)"
posStyles = { top: 0, height: this.document!.documentElement.getBoundingClientRect().height + 'px', }
posStyles = { top: 0, height: height + 'px', }
break;
}

View file

@ -240,7 +240,7 @@ export default class TargetMarker {
})
}
Object.assign(smallClicksBubble.style, clickmapStyles.clicks({ top, height, isRage: s.clickRage }))
Object.assign(smallClicksBubble.style, clickmapStyles.clicks({ top, height, isRage: s.clickRage, left }))
border.appendChild(smallClicksBubble)
overlay.appendChild(bubbleContainer)

View file

@ -16,7 +16,7 @@ export const clickmapStyles = {
},
bubbleContainer: ({ top, left, height }: { top: number; left: number, height: number }) => ({
position: 'absolute',
top: top > 20 ? top + 'px' : height + 2 + 'px',
top: top > 75 ? top + 'px' : height+75 + 'px',
width: '250px',
left: `${left}px`,
padding: '10px',
@ -51,9 +51,9 @@ export const clickmapStyles = {
position: 'absolute',
zIndex,
}),
clicks: ({ top, height, isRage }: { top: number; height: number, isRage?: boolean }) => ({
clicks: ({ top, height, isRage, left }: { top: number; height: number, isRage?: boolean, left: number }) => ({
top: top > 20 ? 0 : `${height}px`,
left: 0,
left: left < 5 ? '100%' : 0,
position: 'absolute',
borderRadius: '999px',
padding: '6px',

View file

@ -115,4 +115,4 @@ Below is the list of dependencies used in OpenReplay software. Licenses may chan
| yq | MIT | Infrastructure |
| html2canvas | MIT | JavaScript |
| eget | MIT | Infrastructure |
| @medv/finder | MIT | JavaScript |

View file

@ -1,4 +1,7 @@
## 5.0.0
## 5.0.1
- Default text input mode is now Obscured
- Use `@medv/finder` instead of our own implementation of `getSelector` for better clickmaps experience
- Added "tel" to supported input types
- Added `{ withCurrentTime: true }` to `tracker.getSessionURL` method which will return sessionURL with current session's timestamp

View file

@ -1,7 +1,7 @@
{
"name": "@openreplay/tracker",
"description": "The OpenReplay tracker main package",
"version": "5.0.0",
"version": "5.0.1-beta.2",
"keywords": [
"logging",
"replay"
@ -47,6 +47,7 @@
"typescript": "^4.9.4"
},
"dependencies": {
"@medv/finder": "^3.0.0",
"error-stack-parser": "^2.0.6"
},
"engines": {

View file

@ -3,26 +3,17 @@ import { hasTag, isSVGElement, isDocument } from '../app/guards.js'
import { normSpaces, hasOpenreplayAttribute, getLabelAttribute } from '../utils.js'
import { MouseMove, MouseClick } from '../app/messages.gen.js'
import { getInputLabel } from './input.js'
import { finder } from '@medv/finder'
function _getSelector(target: Element, document: Document): string {
let el: Element | null = target
let selector: string | null = null
do {
if (el.id) {
return `#${el.id}` + (selector ? ` > ${selector}` : '')
}
selector =
el.className
.split(' ')
.map((cn) => cn.trim())
.filter((cn) => cn !== '')
.reduce((sel, cn) => `${sel}.${cn}`, el.tagName.toLowerCase()) +
(selector ? ` > ${selector}` : '')
if (el === document.body) {
return selector
}
el = el.parentElement
} while (el !== document.body && el !== null)
const selector = finder(target, {
root: document.body,
seedMinLength: 3,
optimizedMinLength: 2,
threshold: 1000,
maxNumberOfTries: 10_000,
})
return selector
}
@ -33,6 +24,8 @@ function isClickable(element: Element): boolean {
tag === 'A' ||
tag === 'LI' ||
tag === 'SELECT' ||
tag === 'TR' ||
tag === 'TH' ||
(element as HTMLElement).onclick != null ||
element.getAttribute('role') === 'button'
)