diff --git a/assets/js/liveview/dashboard_root.js b/assets/js/liveview/dashboard_root.js
index 769044bc4423..b7b25ad6e391 100644
--- a/assets/js/liveview/dashboard_root.js
+++ b/assets/js/liveview/dashboard_root.js
@@ -6,17 +6,25 @@
import { buildHook } from './hook_builder'
-function navigateWithLoader(url) {
- this.portalTargets.map((target) => {
- this.js().addClass(document.querySelector(target), 'phx-navigation-loading')
+const MODAL_ROUTES = {
+ '/pages': '#pages-breakdown-details-modal',
+ '/entry-pages': '#entry-pages-breakdown-details-modal',
+ '/exit-pages': '#exit-pages-breakdown-details-modal',
+ '/sources': '#sources-breakdown-details-modal',
+ '/channels': '#channels-breakdown-details-modal',
+ '/utm_medium': '#utm-mediums-breakdown-details-modal'
+}
- this.pushEvent('handle_dashboard_params', { url: url }, () => {
- this.js().removeClass(
- document.querySelector(target),
- 'phx-navigation-loading'
- )
- })
- })
+function routeModal(path) {
+ const modalId = MODAL_ROUTES[path]
+
+ if (modalId) {
+ const modal = document.querySelector(modalId)
+
+ if (modal) {
+ modal.dispatchEvent(new Event('prima:modal:open'))
+ }
+ }
}
export default buildHook({
@@ -26,39 +34,16 @@ export default buildHook({
this.url = window.location.href
this.addListener('click', document.body, (e) => {
- const type = e.target.dataset.type || null
+ const link = e.target.closest('[data-phx-link]')
+ const type = link && (link.dataset.type || null)
if (type === 'dashboard-link') {
- const uri = new URL(e.target.href)
+ const uri = new URL(link.href)
// Domain is dropped from URL prefix, because that's what react-dom-router
// expects.
const path = '/' + uri.pathname.split('/').slice(2).join('/')
- this.el.dispatchEvent(
- new CustomEvent('dashboard:live-navigate', {
- bubbles: true,
- detail: { path: path, search: uri.search }
- })
- )
-
- e.preventDefault()
- }
- })
-
- // Browser back and forward navigation triggers that event.
- this.addListener('popstate', window, () => {
- if (this.url !== window.location.href) {
- navigateWithLoader.bind(this)(window.location.href)
- }
- })
- // Navigation events triggered from liveview are propagated via this
- // handler.
- this.addListener('dashboard:live-navigate-back', window, (e) => {
- if (
- typeof e.detail.search === 'string' &&
- this.url !== window.location.href
- ) {
- navigateWithLoader.bind(this)(window.location.href)
+ routeModal(path)
}
})
}
diff --git a/lib/plausible/stats/dashboard/utils.ex b/lib/plausible/stats/dashboard/utils.ex
index e3911351f327..54ae75ceb93b 100644
--- a/lib/plausible/stats/dashboard/utils.ex
+++ b/lib/plausible/stats/dashboard/utils.ex
@@ -19,7 +19,7 @@ defmodule Plausible.Stats.Dashboard.Utils do
end
end
- def dashboard_route(%Site{} = site, %ParsedQueryParams{} = params, opts) do
+ def dashboard_route(%Site{} = site, %ParsedQueryParams{} = params, opts \\ []) do
path = Keyword.get(opts, :path, "")
params =
diff --git a/lib/plausible_web/live/components/dashboard/base.ex b/lib/plausible_web/live/components/dashboard/base.ex
index 096654daf98c..286f6aba7347 100644
--- a/lib/plausible_web/live/components/dashboard/base.ex
+++ b/lib/plausible_web/live/components/dashboard/base.ex
@@ -5,6 +5,8 @@ defmodule PlausibleWeb.Components.Dashboard.Base do
use PlausibleWeb, :component
+ alias Prima.Modal
+
attr :to, :string, required: true
attr :class, :string, default: ""
attr :rest, :global
@@ -48,4 +50,73 @@ defmodule PlausibleWeb.Components.Dashboard.Base do
"""
end
+
+ attr :id, :string, required: true
+ attr :on_close, JS, default: %JS{}
+ attr :show, :boolean, default: false
+ attr :ready, :boolean, default: true
+ slot :inner_block, required: true
+
+ def modal(assigns) do
+ ~H"""
+
+
+
+
+
+
+
+
+
+
+
+
"-panel"}
+ class="relative overflow-hidden rounded-lg bg-white dark:bg-gray-900 text-left shadow-xl sm:w-full sm:max-w-lg"
+ transition_enter={
+ {"ease-out duration-300", "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95",
+ "opacity-100 translate-y-0 sm:scale-100"}
+ }
+ transition_leave={
+ {"ease-in duration-200", "opacity-100 translate-y-0 sm:scale-100",
+ "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"}
+ }
+ >
+ {render_slot(@inner_block)}
+
+
+
+
+ """
+ end
+
+ slot :inner_block, required: true
+
+ def modal_title(assigns) do
+ ~H"""
+
+ {render_slot(@inner_block)}
+
+ """
+ end
end
diff --git a/lib/plausible_web/live/components/dashboard/tile.ex b/lib/plausible_web/live/components/dashboard/tile.ex
index 7268df71621e..a6965f099388 100644
--- a/lib/plausible_web/live/components/dashboard/tile.ex
+++ b/lib/plausible_web/live/components/dashboard/tile.ex
@@ -37,7 +37,7 @@ defmodule PlausibleWeb.Components.Dashboard.Tile do
>
{render_slot(@tabs)}
-
+
{render_slot(@warnings)}
@@ -45,7 +45,7 @@ defmodule PlausibleWeb.Components.Dashboard.Tile do
<%!-- reportbody --%>
@@ -55,7 +55,7 @@ defmodule PlausibleWeb.Components.Dashboard.Tile do
{render_slot(@inner_block)}
@@ -113,8 +113,11 @@ defmodule PlausibleWeb.Components.Dashboard.Tile do
defp details_link(assigns) do
~H"""
+ <.spinner class="group-has-[.phx-click-loading:not([data-skip-loader])]/dashboard:inline group-has-[.tile-tabs.phx-hook-loading]:inline w-4 h-4 hidden" />
+