openreplay/frontend/app/components/Dashboard/Widgets/CustomMetricsWidgets/ClickMapCard/ClickMapCard.tsx
Delirium 960da9f037
Tracker 14.x.x changes (#2240)
* feat tracker: add document titles to tabs

* feat: titles for tabs

* feat tracker: send initial title, parse titles better

* feat ui: tab name styles

* feat tracker: update changelogs

* fix tracker: fix tests

* fix tracker: fix failing tests, add some coverage

* fix tracker: fix failing tests, add some coverage

* Heatmaps  (#2264)

* feat ui: start heatmaps ui and tracker update

* fix ui: drop clickmap from session

* fix ui: refactor heatmap painter

* fix ui: store click coords as int percent

* feat(backend): insert normalized x and y to PG

* feat(backend): insert normalized x and y to CH

* feat(connector): added missing import

* feat(backend): fixed different uint type issue

* fix tracker: use max scrollable size for doc

* fix gen files

* fix ui: fix random crash, remove demo data generator

* fix ui: rm some dead code

---------

Co-authored-by: Alexander <zavorotynskiy@pm.me>

* fix tracker: add heatmap changelog to tracker CHANGELOG.md

* fix tracker: fix peerjs version to 1.5.4 (was 1.5.1)

* fix document height calculation

* Crossdomain tracking (#2277)

* feat tracker: crossdomain tracking (start commit)

* catch crossdomain messages, add nodeid placeholder

* click scroll

* frame placeholder number -> dynamic

* click rewriter, fix scroll prop

* some docs

* some docs

* fix options merging

* CHANGELOG.md update

* checking that crossdomain will not fire automatically

* simplify func declaration

* update test data

* change clickmap document height calculation to scrollheight (which should be true height)

---------

Co-authored-by: Alexander <zavorotynskiy@pm.me>
2024-06-24 13:49:26 +02:00

90 lines
3.3 KiB
TypeScript

import React from 'react'
import { useStore } from 'App/mstore'
import { observer } from 'mobx-react-lite'
import ClickMapRenderer from 'App/components/Session/Player/ClickMapRenderer'
import { connect } from 'react-redux'
import { fetchInsights } from 'App/duck/sessions'
import { NoContent, Icon } from 'App/components/ui'
function ClickMapCard({
insights,
fetchInsights,
insightsFilters,
}: any) {
const [customSession, setCustomSession] = React.useState<any>(null)
const { metricStore, dashboardStore } = useStore();
const onMarkerClick = (s: string, innerText: string) => {
metricStore.changeClickMapSearch(s, innerText)
}
const mapUrl = metricStore.instance.series[0].filter.filters[0].value[0]
React.useEffect(() => {
return () => setCustomSession(null)
}, [])
React.useEffect(() => {
if (metricStore.instance.data.domURL) {
setCustomSession(null)
setTimeout(() => {
setCustomSession(metricStore.instance.data)
}, 100)
}
}, [metricStore.instance])
React.useEffect(() => {
const rangeValue = dashboardStore.drillDownPeriod.rangeValue
const startDate = dashboardStore.drillDownPeriod.start
const endDate = dashboardStore.drillDownPeriod.end
fetchInsights({ ...insightsFilters, url: mapUrl || '/', startDate, endDate, rangeValue, clickRage: metricStore.clickMapFilter })
}, [dashboardStore.drillDownPeriod.start, dashboardStore.drillDownPeriod.end, dashboardStore.drillDownPeriod.rangeValue, metricStore.clickMapFilter])
if (!metricStore.instance.data.domURL || insights.size === 0) {
return (
<NoContent
style={{ minHeight: 220 }}
title={
<div className="flex items-center relative">
<Icon name="info-circle" className="mr-2" size="18" />
No data for selected period or URL
<div style={{ position: 'absolute', right: -240, top: -110 }}>
<Icon name="pointer-sessions-search" size={250} width={240} />
</div>
</div>
}
show={true}
/>
)
}
if (!metricStore.instance.data || !customSession) {
return <div className="py-2">Loading session</div>
}
const jumpToEvent = metricStore.instance.data.events.find((evt: Record<string, any>) => {
if (mapUrl) return evt.path.includes(mapUrl)
return evt
}) || { timestamp: metricStore.instance.data.startTs }
const jumpTimestamp = (jumpToEvent.timestamp - metricStore.instance.data.startTs) + jumpToEvent.domBuildingTime + 99 // 99ms safety margin to give some time for the DOM to load
return (
<div id="clickmap-render">
<ClickMapRenderer
session={customSession}
jumpTimestamp={jumpTimestamp}
onMarkerClick={onMarkerClick}
/>
</div>
)
}
export default connect(
(state: any) => ({
insightsFilters: state.getIn(['sessions', 'insightFilters']),
visitedEvents: state.getIn(['sessions', 'visitedEvents']),
insights: state.getIn(['sessions', 'insights']),
host: state.getIn(['sessions', 'host']),
}),
{ fetchInsights, }
)
(observer(ClickMapCard))