add analytics CSV export
All checks were successful
deploy / deploy (push) Successful in 1m25s

Downloads a ZIP with one CSV per report (overview, trend, pages, entry/exit
pages, sources, referrers, countries, devices, funnel). Export button lives
next to the period selector and picks up the current period and any active
filters using a JS hook + JS.set_attribute, so the downloaded data always
matches what's on screen.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jamey
2026-02-24 09:37:45 +00:00
parent 01ff8decd5
commit 758e66db5c
4 changed files with 269 additions and 5 deletions

View File

@@ -509,6 +509,31 @@ const CardRadioScroll = {
}
}
// Analytics export: reads the current period and filters from the DOM at click time
// so the download URL is always correct, even if clicked before the LiveView re-render.
const AnalyticsExport = {
mounted() {
this.el.addEventListener("click", (e) => {
e.preventDefault()
const params = new URLSearchParams()
params.set("period", this.el.getAttribute("data-period") || "30d")
document.querySelectorAll("[data-filter-dimension]").forEach((span) => {
const dim = span.getAttribute("data-filter-dimension")
const val = span.getAttribute("data-filter-value")
if (dim && val) params.set(`filter[${dim}]`, val)
})
// Use a temporary anchor click so the download doesn't navigate away and
// kill the LiveView WebSocket.
const a = document.createElement("a")
a.href = `/admin/analytics/export?${params}`
a.download = ""
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
})
}
}
// Analytics: send screen width for device classification (Layer 3)
const AnalyticsInit = {
mounted() {
@@ -592,7 +617,7 @@ const ChartTooltip = {
const csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
const liveSocket = new LiveSocket("/live", Socket, {
params: {_csrf_token: csrfToken, screen_width: window.innerWidth},
hooks: {...colocatedHooks, ColorSync, Lightbox, CartPersist, CartDrawer, ProductImageScroll, SearchModal, CollectionFilters, CardRadioScroll, AnalyticsInit, ChartTooltip},
hooks: {...colocatedHooks, ColorSync, Lightbox, CartPersist, CartDrawer, ProductImageScroll, SearchModal, CollectionFilters, CardRadioScroll, AnalyticsInit, AnalyticsExport, ChartTooltip},
})
// Show progress bar on live navigation and form submits