Skip to content
32 changes: 26 additions & 6 deletions assets/js/dashboard/stats/graph/top-stats.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useState, useEffect, useRef } from 'react'

Check failure on line 1 in assets/js/dashboard/stats/graph/top-stats.js

View workflow job for this annotation

GitHub Actions / Build and test

'useRef' is defined but never used. Allowed unused vars must match /^_/u

Check failure on line 1 in assets/js/dashboard/stats/graph/top-stats.js

View workflow job for this annotation

GitHub Actions / Build and test

'useEffect' is defined but never used. Allowed unused vars must match /^_/u

Check failure on line 1 in assets/js/dashboard/stats/graph/top-stats.js

View workflow job for this annotation

GitHub Actions / Build and test

'useState' is defined but never used. Allowed unused vars must match /^_/u
import { Tooltip } from '../../util/tooltip'
import { SecondsSinceLastLoad } from '../../util/seconds-since-last-load'
import classNames from 'classnames'
Expand All @@ -8,6 +8,7 @@
import { useSiteContext } from '../../site-context'
import { useLastLoadContext } from '../../last-load-context'
import { ChangeArrow } from '../reports/change-arrow'
import { LiveViewIframe } from '../liveview-iframe'
import {
MetricFormatterShort,
MetricFormatterLong
Expand All @@ -26,6 +27,7 @@
export default function TopStats({
data,
onMetricUpdate,
setTopStatsLoading,
tooltipBoundary,
graphableMetrics
}) {
Expand Down Expand Up @@ -99,11 +101,11 @@
return graphableMetrics.includes(stat.graph_metric)
}

function maybeUpdateMetric(stat) {
if (canMetricBeGraphed(stat)) {
storage.setItem(`metric__${site.domain}`, stat.graph_metric)
onMetricUpdate(stat.graph_metric)
}
function maybeUpdateMetric(metric) {
// if (canMetricBeGraphed(stat)) {
storage.setItem(`metric__${site.domain}`, metric)
onMetricUpdate(metric)
// }
}

function blinkingDot() {
Expand Down Expand Up @@ -208,6 +210,24 @@
)
}

const onMessage = (data) => {
if (data.type === "EMBEDDED_LV_TOP_STATS_SELECT") {
maybeUpdateMetric(data.metric)
} else if (data.type === "EMBEDDED_LV_TOP_STATS_LOADING_SUCCESS") {
setTopStatsLoading(false)
}
}

if (true) {

Check failure on line 221 in assets/js/dashboard/stats/graph/top-stats.js

View workflow job for this annotation

GitHub Actions / Build and test

Unexpected constant condition
return (
<LiveViewIframe
className="w-full h-full border-0 overflow-hidden"
onMessage={onMessage}
src={`${window.location.pathname}/live/top_stats?date_range=${query.period}&filters=${JSON.stringify(query.filters)}`}
/>
)
}

const stats =
data && data.top_stats.filter((stat) => stat.value !== null).map(renderStat)

Expand Down
60 changes: 21 additions & 39 deletions assets/js/dashboard/stats/graph/visitor-graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import { useQueryContext } from '../../query-context'
import { useSiteContext } from '../../site-context'

function fetchTopStats(site, query) {

Check failure on line 17 in assets/js/dashboard/stats/graph/visitor-graph.js

View workflow job for this annotation

GitHub Actions / Build and test

'fetchTopStats' is defined but never used. Allowed unused vars must match /^_/u
const q = { ...query }

if (!isComparisonEnabled(q.comparison) && query.period !== 'realtime') {
Expand All @@ -29,7 +29,7 @@
return api.get(url.apiPath(site, '/main-graph'), query, params)
}

export default function VisitorGraph({ updateImportedDataInView }) {

Check failure on line 32 in assets/js/dashboard/stats/graph/visitor-graph.js

View workflow job for this annotation

GitHub Actions / Build and test

'updateImportedDataInView' is defined but never used. Allowed unused args must match /^_/u
const { query } = useQueryContext()
const site = useSiteContext()

Expand Down Expand Up @@ -84,31 +84,31 @@
}
}, [query])

useEffect(() => {
if (topStatData) {
storeTopStatsContainerHeight()
}
}, [topStatData])
// useEffect(() => {
// if (topStatData) {
// storeTopStatsContainerHeight()
// }
// }, [topStatData])

async function fetchTopStatsAndGraphData() {
const response = await fetchTopStats(site, query)
// const response = await fetchTopStats(site, query)

let metric = getStoredMetric()
const availableMetrics = response.graphable_metrics
let metric = getStoredMetric() || 'visitors'
// const availableMetrics = response.graphable_metrics

if (!availableMetrics.includes(metric)) {
metric = availableMetrics[0]
storage.setItem(`metric__${site.domain}`, metric)
}
// if (!availableMetrics.includes(metric)) {
// metric = availableMetrics[0]
// storage.setItem(`metric__${site.domain}`, metric)
// }

const interval = getCurrentInterval(site, query)

if (response.updateImportedDataInView) {
updateImportedDataInView(response.includes_imported)
}

setTopStatData(response)
setTopStatsLoading(false)
// if (response.updateImportedDataInView) {
// updateImportedDataInView(response.includes_imported)
// }
//
// setTopStatData(response)
// setTopStatsLoading(false)

fetchGraphData(metric, interval)
}
Expand All @@ -125,25 +125,6 @@
return storage.getItem(`metric__${site.domain}`)
}

function storeTopStatsContainerHeight() {
storage.setItem(
`topStatsHeight__${site.domain}`,
document.getElementById('top-stats-container').clientHeight
)
}

// This function is used for maintaining the main-graph/top-stats container height in the
// loading process. The container height depends on how many top stat metrics are returned
// from the API, but in the loading state, we don't know that yet. We can use localStorage
// to keep track of the Top Stats container height.
function getTopStatsHeight() {
if (topStatData) {
return 'auto'
} else {
return `${storage.getItem(`topStatsHeight__${site.domain}`) || 89}px`
}
}

function importedSwitchVisible() {
return (
!!topStatData?.with_imported_switch &&
Expand Down Expand Up @@ -176,12 +157,13 @@
<div
id="top-stats-container"
className="flex flex-wrap"
ref={topStatsBoundary}
style={{ height: getTopStatsHeight() }}
// style={{ height: getTopStatsHeight() }}
>
<TopStats
graphableMetrics={topStatData?.graphable_metrics || []}
ref={topStatsBoundary}
data={topStatData}
setTopStatsLoading={setTopStatsLoading}
onMetricUpdate={onMetricUpdate}
tooltipBoundary={topStatsBoundary.current}
/>
Expand Down
35 changes: 35 additions & 0 deletions assets/js/dashboard/stats/liveview-iframe.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { useEffect, useRef, useState } from "react";

type LiveViewIframeProps = {
src: string;
className?: string;
onMessage: (data: object) => void;
minHeight?: number; // fallback height
};

export function LiveViewIframe({ src, className, onMessage, minHeight = 85 }: LiveViewIframeProps) {
const ref = useRef<HTMLIFrameElement>(null);
const [height, setHeight] = useState(minHeight);

useEffect(() => {
const handleMessage = (ev: MessageEvent) => {
if (ev.data?.type === "EMBEDDED_LV_SIZE") {
setHeight(Math.max(minHeight, Number(ev.data.height) || minHeight));
} else if (ev.data?.type?.startsWith('EMBEDDED_LV')) {
onMessage(ev.data)
}
};
window.addEventListener("message", handleMessage);
return () => window.removeEventListener("message", handleMessage);
}, [minHeight]);

Check warning on line 24 in assets/js/dashboard/stats/liveview-iframe.tsx

View workflow job for this annotation

GitHub Actions / Build and test

React Hook useEffect has a missing dependency: 'onMessage'. Either include it or remove the dependency array. If 'onMessage' changes too often, find the parent component that defines it and wrap that definition in useCallback

return (
<iframe
ref={ref}
src={src}
style={{ width: "100%", border: "0", height }}
className={className}
title="LiveView Widget"
/>
);
}
33 changes: 25 additions & 8 deletions assets/js/liveview/live_socket.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
These 3 modules are resolved from '../deps' folder,
which does not exist when running the lint command in Github CI
These 3 modules are resolved from '../deps' folder,
which does not exist when running the lint command in Github CI
*/
/* eslint-disable import/no-unresolved */
import 'phoenix_html'
Expand Down Expand Up @@ -62,13 +62,30 @@
}
})

topbar.config({
barColors: { 0: '#303f9f' },
shadowColor: 'rgba(0, 0, 0, .3)',
barThickness: 4
if (!document.currentScript.hasAttribute('skip-topbar')) {
topbar.config({
barColors: { 0: '#303f9f' },
shadowColor: 'rgba(0, 0, 0, .3)',
barThickness: 4
})
window.addEventListener('phx:page-loading-start', (_info) => topbar.show())
window.addEventListener('phx:page-loading-stop', (_info) => topbar.hide())
}

window.addEventListener('plausible:top_stats:select', (e) => {
top.postMessage(
{ type: "EMBEDDED_LV_TOP_STATS_SELECT", metric: e.target.dataset.metric },
"*"
);
})
window.addEventListener('phx:page-loading-start', (_info) => topbar.show())
window.addEventListener('phx:page-loading-stop', (_info) => topbar.hide())

window.addEventListener('plausible:top_stats:loading:success', (e) => {

Check failure on line 82 in assets/js/liveview/live_socket.js

View workflow job for this annotation

GitHub Actions / Build and test

'e' is defined but never used. Allowed unused args must match /^_/u
top.postMessage(
{ type: "EMBEDDED_LV_TOP_STATS_LOADING_SUCCESS"},
"*"
);
})


liveSocket.connect()
window.liveSocket = liveSocket
Expand Down
Loading
Loading