analytics/lib/plausible_web/controllers/api/internal_controller.ex
Adrian Gruntkowski f464ceae88
Implement pinned sites (#3469)
* Revert "Remove site pins for now"

This reverts commit 5eccf4eaf6.

* Implement basic site pin schema level logic within user specific preferences

* Add vertical ellipsis menu markup

* Implement basic changesets for user preferences

* Implement pin toggling

* Try to fix pin sorting

* Implement pin toggling in LV

* Adjust moduledocs for new schema(s)

* Remove unnecessary `distinct` from query

* Use `button` for pin/unpin action

* Generalize preference setting

* Rename schema and fields for clarity

* Rename `list_type` -> `entry_type`

* Safeguard setting options

* Test `set_option/4` and `toggle_pin/2`

* Add test for listing pinned sites via `Sites.list`

* Disallow pinning sites outside page explicitly

* Test pinning in LV

* Test conditional rendering of site settings in /sites

* Remove unnecessary TODO comment

* Safeguard `Sites.set_option/4` against invalid user/site combo

* Handle pinned sites in dashboard site picker

* Clear flashes upon (un)pinning sites

* Update CHANGELOG

* Prevent blinking of hamburger menu items on first paint

* Highlight hamburger handle on hover in /sites

* Start showing hotkeys in site picker again

* Sort pinned sites in the order they were pinned

* Update sites list order immediately after pin/unpin toggle

* Refactor and split `Sites.list/3`, extracting `Sites.list_with_invitations/3`

* Cap number of pinned sites at 9 per user

* First pass on visual indication of site cards (dis)appearing

* Apply ellipsis gradient+shadow on card hover

* Fix responsive padding of site cards

* Sort by invitations first, pinned sites second and then the rest

* Revert "Apply ellipsis gradient+shadow on card hover"

This reverts commit 0608796612639030ccbb12df639709f78edc1434.

* Apply more subtle hover effect on the ellipsis menu

* Make error and success flash LV boxes use separate component containers

* Promote `pinned_at` in table migration to a column

* Switch logic to using `pinned_at` as a standard schema field

* Refactor `Sites.list*` getting rid of subquery (h/t @ukutaht)

* Remove migration which is already merged upstream

---------

Co-authored-by: Adam Rutkowski <hq@mtod.org>
2023-11-13 09:08:26 +01:00

73 lines
2.3 KiB
Elixir

defmodule PlausibleWeb.Api.InternalController do
use PlausibleWeb, :controller
use Plausible.Repo
alias Plausible.Stats.Clickhouse, as: Stats
alias Plausible.{Sites, Site, Auth}
alias Plausible.Auth.User
def domain_status(conn, %{"domain" => domain}) do
with %User{id: user_id} <- conn.assigns[:current_user],
%Site{} = site <- Sites.get_by_domain(domain),
true <- Sites.has_admin_access?(user_id, site) || Auth.is_super_admin?(user_id),
true <- Stats.has_pageviews?(site) do
json(conn, "READY")
else
_ ->
json(conn, "WAITING")
end
end
def sites(conn, _params) do
current_user = conn.assigns[:current_user]
if current_user do
sites = sites_for(current_user)
json(conn, %{data: sites})
else
PlausibleWeb.Api.Helpers.unauthorized(
conn,
"You need to be logged in to request a list of sites"
)
end
end
@features %{
"funnels" => Plausible.Billing.Feature.Funnels,
"props" => Plausible.Billing.Feature.Props,
"conversions" => Plausible.Billing.Feature.Goals
}
def disable_feature(conn, %{"domain" => domain, "feature" => feature}) do
with %User{id: user_id} <- conn.assigns[:current_user],
site <- Sites.get_by_domain(domain),
true <- Sites.has_admin_access?(user_id, site) || Auth.is_super_admin?(user_id),
{:ok, mod} <- Map.fetch(@features, feature),
{:ok, _site} <- mod.toggle(site, override: false) do
json(conn, "ok")
else
{:error, :upgrade_required} ->
PlausibleWeb.Api.Helpers.payment_required(
conn,
"This feature is part of the Plausible Business plan. To get access to this feature, please upgrade your account"
)
:error ->
PlausibleWeb.Api.Helpers.bad_request(
conn,
"The feature you tried to disable is not valid. Valid features are: #{@features |> Map.keys() |> Enum.join(", ")}"
)
_ ->
PlausibleWeb.Api.Helpers.unauthorized(
conn,
"You need to be logged in as the owner or admin account of this site"
)
end
end
defp sites_for(user) do
pagination = Sites.list(user, %{page_size: 9})
Enum.map(pagination.entries, &%{domain: &1.domain})
end
end