mirror of
https://github.com/plausible/analytics.git
synced 2024-12-27 03:21:37 +03:00
e5b56dbe62
* Give a more semantic name to a function * Make the LineGraph component thinner * Move LineGraph into a separate file * Move interval logic into interval-picker.js This commit also fixes a bug where the interval name displayed inside the picker component flickers the default interval when the graph is loading. The problem was that we were counting on graphData for returning us the current interval: `let currentInterval = graphData?.interval` We should always know the default interval before making the main-graph request. Sending graphData to IntervalPicker component does not make sense anyway. * extract data fetching functions out of VisitorGraph component * Return graph_metric key from Top Stats API This commit introduces no behavioral changes - only starts returning an additional field, allowing us to avoid the following logic in React: 1. Finding the metric names, given a stat display name. E.g. `Unique visitors (last 30 min) -> visitors` 2. Checking if a metric is graphable or not * Move metric state into localStorage This commit gets rid of the internal `metric` state in the VisitorGraph component and starts using localStorage for that instead. This commit also chains the main-graph request into the top-stats request callback - meaning that we'll always fetch new graph data after top stats are updated. And we do it all in a single function. Doing so simplifies the loading state significantly, and also helps to make it clear, that at all times, existing top stats are required before we can fetch the graph. That's because the metric is determined by which Top stats are returned (for example, we can't be sure whether revenue metrics will be returned or not). * Make sure graph tooltip says "Converted Visitors" * Extract a StatsExport function component Again, instead of relying on `graphData?.interval` we can read it from localStorage, or default to the largest interval available. The export should not be dependant on the graph. * Extract SamplingNotice function component * Extract WithImportedSwitch function component * Stop "lazy-loading" the graph and top stats Since the container is always on top on the page, it will be visible on the first render in any case - no matter the screen size. * Turn VisitorGraph into a function component * Display empty container until everything has loaded * Do not display loading spinner on realtime ticks * Turn Top Stats into a fn component * fetch top stats and graph async * Make sure revenue metrics can remain on the graph * Add an extra check to canMetricBeGraphed * fix typo * remove redundant double negation
77 lines
3.4 KiB
Plaintext
77 lines
3.4 KiB
Plaintext
<div class={stats_container_class(@conn)} data-site-domain={@site.domain}>
|
|
<PlausibleWeb.Components.FirstDashboardLaunchBanner.render site={@site} />
|
|
|
|
<%= if @site.locked do %>
|
|
<div
|
|
class="w-full px-4 py-4 text-sm font-bold text-center text-yellow-800 bg-yellow-100 rounded transition"
|
|
style="top: 91px"
|
|
role="alert"
|
|
>
|
|
<p>This dashboard is actually locked. You are viewing it with super-admin access</p>
|
|
</div>
|
|
<% end %>
|
|
|
|
<div class="pt-6"></div>
|
|
<div
|
|
id="stats-react-container"
|
|
style="overflow-anchor: none;"
|
|
data-domain={@site.domain}
|
|
data-offset={Plausible.Site.tz_offset(@site)}
|
|
data-has-goals={to_string(@has_goals)}
|
|
data-conversions-opted-out={to_string(Plausible.Billing.Feature.Goals.opted_out?(@site))}
|
|
data-funnels-opted-out={to_string(Plausible.Billing.Feature.Funnels.opted_out?(@site))}
|
|
data-props-opted-out={to_string(Plausible.Billing.Feature.Props.opted_out?(@site))}
|
|
data-funnels-available={
|
|
to_string(Plausible.Billing.Feature.Funnels.check_availability(@site.owner) == :ok)
|
|
}
|
|
data-props-available={
|
|
to_string(Plausible.Billing.Feature.Props.check_availability(@site.owner) == :ok)
|
|
}
|
|
data-revenue-goals={Jason.encode!(@revenue_goals)}
|
|
data-funnels={Jason.encode!(@funnels)}
|
|
data-has-props={to_string(@has_props)}
|
|
data-logged-in={to_string(!!@conn.assigns[:current_user])}
|
|
data-stats-begin={@stats_start_date}
|
|
data-native-stats-begin={@native_stats_start_date}
|
|
data-shared-link-auth={assigns[:shared_link_auth]}
|
|
data-embedded={to_string(@conn.assigns[:embedded])}
|
|
data-background={@conn.assigns[:background]}
|
|
data-is-dbip={to_string(@is_dbip)}
|
|
data-current-user-role={@conn.assigns[:current_user_role]}
|
|
data-flags={Jason.encode!(@flags)}
|
|
data-valid-intervals-by-period={
|
|
Plausible.Stats.Interval.valid_by_period(site: @site) |> Jason.encode!()
|
|
}
|
|
>
|
|
</div>
|
|
<div id="modal_root"></div>
|
|
<%= if !@conn.assigns[:current_user] && @conn.assigns[:demo] do %>
|
|
<div class="bg-gray-50 dark:bg-gray-850">
|
|
<div class="py-12 lg:py-16 lg:flex lg:items-center lg:justify-between">
|
|
<h2 class="text-3xl font-extrabold tracking-tight text-gray-900 leading-9 sm:text-4xl sm:leading-10 dark:text-gray-100">
|
|
Want these stats for your website? <br />
|
|
<span class="text-indigo-600">Start your free trial today.</span>
|
|
</h2>
|
|
<div class="flex mt-8 lg:flex-shrink-0 lg:mt-0">
|
|
<div class="inline-flex shadow rounded-md">
|
|
<a
|
|
href="/register"
|
|
class="inline-flex items-center justify-center px-5 py-3 text-base font-medium text-white bg-indigo-600 border border-transparent leading-6 rounded-md hover:bg-indigo-500 focus:outline-none focus:ring transition duration-150 ease-in-out"
|
|
>
|
|
Get started
|
|
</a>
|
|
</div>
|
|
<div class="inline-flex ml-3 shadow rounded-md">
|
|
<a
|
|
href="/"
|
|
class="inline-flex items-center justify-center px-5 py-3 text-base font-medium text-indigo-600 bg-white border border-transparent leading-6 rounded-md dark:text-gray-100 dark:bg-gray-800 hover:text-indigo-500 dark:hover:text-indigo-500 focus:outline-none focus:ring transition duration-150 ease-in-out"
|
|
>
|
|
Learn more
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<% end %>
|
|
</div>
|