analytics/test/plausible_web/live/sites_test.exs

229 lines
6.4 KiB
Elixir
Raw Normal View History

Implement new sites view (#3463) * Implement complete basics of LV sites * Reimplement everything in LV except pagination * Implement basic search capability * PoC: plot visitors on sites index * Add rudimentary clipped gradient in minicharts * Fix clipping gradient, define once * Format * Add moduledoc to visitors component * Move paginator helpers to the top core namespace * Fix typespec of `Plausible.Sites.list` * Split sites component into subcomponents * Add function to uniformly calculate 24h intervals and visitor totals across multiple sites. * Integrate batch 24h interval query with plots on sites view * Don't confuse heex compiler with alpine @ shorthands * Make linear gradient svg definition truly invisible * Implement basic pagination * Extract `site_stats` from site and invitation cards * Improve pagination * Tweak css * Improve filtering on pagination and make WSS fail graceful * Test `last_24h_visitors_hourly_intervals/2` * Replace /sites with LV implementation * Add debounce to search filter * Fix typespecs * Fix styling * Fix mini graph scaling factor calculation * Fix search consuming itself * Minimal tweaks to the plots * Fixup * Remove magic numbers from the plot * Create `site_pins` table * Add `SitePin` schema * Implement listing invitations, sites and pins in a single query * Add FIXME note * Remove site pins for now * Add tests for `Plausible.Sites.list/3` * Add a couple more tests to sites dead view * Remove unnecessary FIXME * Add LV tests for Sites * Calculate and display 24h visitors change * Render the change in bold * Add clarfying comment on virtual field in `Site` schema * Remove unnecessary function from Invitations API * Remove unused list opt from type definition in `Sites` * Improve joins in list query slightly * Add comment on manually computing sites list total * Start searching from a singly character in domain field * Add typespec to `last_24h_visitors_hourly_intervals` * Extend moduledoc in visitors component * Simplify loading sites in LV * Simplify assigns in LV * Add missing group for shadow under site card * Make invitation modal render * Make HTML in sites LV semantically correct * Remove autofocus and focus search on `/` * Remove shadow from search input * Make search cancel on escape * Fix tests relying on outdated HTML structure * Make visitor chart color scheme consistent with dashboard chart * Update styling of trend labels * Fix empty state and improve search blur/focus handling * Use live navigation for pagination * Implement spinner on load from search * Remove unused `Plausible.Stats.Clickhouse.last_24h_visitors/1` * Calculate uniques correctly across hour boundaries * Swap inlined svg for Heroicons component in invitation modal * Add order by to base query in 24h hourly intervals * Revert "Add order by to base query in 24h hourly intervals" This reverts commit a6be5e302662b3a90f68da0e3fdfa6ff271c168e. * Query clickhouse 24h visitors only on second mount * Remove redundant sign from percentage change when negative * Switch to offset-based pagination - offset seems easier to deal with for when actions on paginated list will be performed such as site pinning; tracking cursor data makes some entries disappear in edge cases. The data set is still fairly small and static, even for large customers. - we're removing Phoenix.Pagination as it doesn't really fir any use case, and it was only used to limit the number of sites in the site picker - site picker is now limited to 9 sites (future: pinned sites will be prioritized there) - no need to re-query for total count any more - BTW, the old /sites template was removed * Refine the plot queries; Tests pass snapshot * Add PromEx plugin for LiveView * Fix tiny plot cut-off at the top --------- Co-authored-by: Adam Rutkowski <hq@mtod.org>
2023-11-02 15:18:11 +03:00
defmodule PlausibleWeb.Live.SitesTest do
use PlausibleWeb.ConnCase, async: true
import Phoenix.LiveViewTest
import Plausible.Test.Support.HTML
Implement pinned sites (#3469) * Revert "Remove site pins for now" This reverts commit 5eccf4eaf62508432d53c7557f79650ced0e6516. * 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 11:08:26 +03:00
alias Plausible.Repo
Implement new sites view (#3463) * Implement complete basics of LV sites * Reimplement everything in LV except pagination * Implement basic search capability * PoC: plot visitors on sites index * Add rudimentary clipped gradient in minicharts * Fix clipping gradient, define once * Format * Add moduledoc to visitors component * Move paginator helpers to the top core namespace * Fix typespec of `Plausible.Sites.list` * Split sites component into subcomponents * Add function to uniformly calculate 24h intervals and visitor totals across multiple sites. * Integrate batch 24h interval query with plots on sites view * Don't confuse heex compiler with alpine @ shorthands * Make linear gradient svg definition truly invisible * Implement basic pagination * Extract `site_stats` from site and invitation cards * Improve pagination * Tweak css * Improve filtering on pagination and make WSS fail graceful * Test `last_24h_visitors_hourly_intervals/2` * Replace /sites with LV implementation * Add debounce to search filter * Fix typespecs * Fix styling * Fix mini graph scaling factor calculation * Fix search consuming itself * Minimal tweaks to the plots * Fixup * Remove magic numbers from the plot * Create `site_pins` table * Add `SitePin` schema * Implement listing invitations, sites and pins in a single query * Add FIXME note * Remove site pins for now * Add tests for `Plausible.Sites.list/3` * Add a couple more tests to sites dead view * Remove unnecessary FIXME * Add LV tests for Sites * Calculate and display 24h visitors change * Render the change in bold * Add clarfying comment on virtual field in `Site` schema * Remove unnecessary function from Invitations API * Remove unused list opt from type definition in `Sites` * Improve joins in list query slightly * Add comment on manually computing sites list total * Start searching from a singly character in domain field * Add typespec to `last_24h_visitors_hourly_intervals` * Extend moduledoc in visitors component * Simplify loading sites in LV * Simplify assigns in LV * Add missing group for shadow under site card * Make invitation modal render * Make HTML in sites LV semantically correct * Remove autofocus and focus search on `/` * Remove shadow from search input * Make search cancel on escape * Fix tests relying on outdated HTML structure * Make visitor chart color scheme consistent with dashboard chart * Update styling of trend labels * Fix empty state and improve search blur/focus handling * Use live navigation for pagination * Implement spinner on load from search * Remove unused `Plausible.Stats.Clickhouse.last_24h_visitors/1` * Calculate uniques correctly across hour boundaries * Swap inlined svg for Heroicons component in invitation modal * Add order by to base query in 24h hourly intervals * Revert "Add order by to base query in 24h hourly intervals" This reverts commit a6be5e302662b3a90f68da0e3fdfa6ff271c168e. * Query clickhouse 24h visitors only on second mount * Remove redundant sign from percentage change when negative * Switch to offset-based pagination - offset seems easier to deal with for when actions on paginated list will be performed such as site pinning; tracking cursor data makes some entries disappear in edge cases. The data set is still fairly small and static, even for large customers. - we're removing Phoenix.Pagination as it doesn't really fir any use case, and it was only used to limit the number of sites in the site picker - site picker is now limited to 9 sites (future: pinned sites will be prioritized there) - no need to re-query for total count any more - BTW, the old /sites template was removed * Refine the plot queries; Tests pass snapshot * Add PromEx plugin for LiveView * Fix tiny plot cut-off at the top --------- Co-authored-by: Adam Rutkowski <hq@mtod.org>
2023-11-02 15:18:11 +03:00
setup [:create_user, :log_in]
describe "/sites" do
test "renders empty sites page", %{conn: conn} do
{:ok, _lv, html} = live(conn, "/sites")
assert text(html) =~ "You don't have any sites yet"
end
Move limit enforcement to accepting site ownership transfer (#3612) * Move limit enforcement to accepting site ownerhsip transfer * enforce pageview limit on ownership transfer accept * Refactor plan limit check logic * Extract `ensure_can_take_ownership` to `Invitations` context and refactor * Improve styling of exceeded limits notice in invitation dialog and disable button * styling improvements to notice * make transfer_ownership return transfer to self error * do not allow transferring to user without active subscription WIP * Add missing typespec and improve existing ones * Fix formatting * Explicitly label direct match on function argument for clarity * Slightly refactor `CreateInvitation.bulk_transfer_ownership_direct` * Exclude quota enforcement tests from small build test suite * Remove unused return type from `invite_error()` union type * Do not block plan upgrade when there's pending ownership transfer * Don't block and only warn about missing features on transfer * Remove `x-init` attribute used for debugging * Add tests for `Quota.monthly_pageview_usage/2` * Test and improve site admin ownership transfer actions * Extend tests for `AcceptInvitation.transfer_ownership` * Test transfer ownership controller level accept action error cases * Test choosing plan by user without sites but with a pending ownership transfer * Test invitation x-data in sites LV * Remove sitelocker trigger in invitation acceptance code and simplify logic * Add Quota test for `user.allow_next_upgrade_override` being set * ignore pageview limit only when subscribing to plan * Use sandbox Paddle instance for staging * Use sandbox paddle key for staging and dev --------- Co-authored-by: Robert Joonas <robertjoonas16@gmail.com>
2023-12-20 17:56:49 +03:00
@tag :full_build_only
test "renders ownership transfer invitation for a case with no plan", %{
conn: conn,
user: user
} do
site = insert(:site)
invitation =
insert(:invitation,
site_id: site.id,
inviter: build(:user),
email: user.email,
role: :owner
)
{:ok, _lv, html} = live(conn, "/sites")
invitation_data = get_invitation_data(html)
assert get_in(invitation_data, ["invitations", invitation.invitation_id, "no_plan"])
end
@tag :full_build_only
test "renders ownership transfer invitation for a case with exceeded limits", %{
conn: conn,
user: user
} do
site = insert(:site)
insert(:growth_subscription, user: user)
# fill site quota
insert_list(10, :site, members: [user])
invitation =
insert(:invitation,
site_id: site.id,
inviter: build(:user),
email: user.email,
role: :owner
)
{:ok, _lv, html} = live(conn, "/sites")
invitation_data = get_invitation_data(html)
assert get_in(invitation_data, ["invitations", invitation.invitation_id, "exceeded_limits"]) ==
"site limit"
end
@tag :full_build_only
test "renders ownership transfer invitation for a case with missing features", %{
conn: conn,
user: user
} do
site = insert(:site, allowed_event_props: ["dummy"])
insert(:growth_subscription, user: user)
invitation =
insert(:invitation,
site_id: site.id,
inviter: build(:user),
email: user.email,
role: :owner
)
{:ok, _lv, html} = live(conn, "/sites")
invitation_data = get_invitation_data(html)
assert get_in(invitation_data, ["invitations", invitation.invitation_id, "missing_features"]) ==
"Custom Properties"
end
Implement new sites view (#3463) * Implement complete basics of LV sites * Reimplement everything in LV except pagination * Implement basic search capability * PoC: plot visitors on sites index * Add rudimentary clipped gradient in minicharts * Fix clipping gradient, define once * Format * Add moduledoc to visitors component * Move paginator helpers to the top core namespace * Fix typespec of `Plausible.Sites.list` * Split sites component into subcomponents * Add function to uniformly calculate 24h intervals and visitor totals across multiple sites. * Integrate batch 24h interval query with plots on sites view * Don't confuse heex compiler with alpine @ shorthands * Make linear gradient svg definition truly invisible * Implement basic pagination * Extract `site_stats` from site and invitation cards * Improve pagination * Tweak css * Improve filtering on pagination and make WSS fail graceful * Test `last_24h_visitors_hourly_intervals/2` * Replace /sites with LV implementation * Add debounce to search filter * Fix typespecs * Fix styling * Fix mini graph scaling factor calculation * Fix search consuming itself * Minimal tweaks to the plots * Fixup * Remove magic numbers from the plot * Create `site_pins` table * Add `SitePin` schema * Implement listing invitations, sites and pins in a single query * Add FIXME note * Remove site pins for now * Add tests for `Plausible.Sites.list/3` * Add a couple more tests to sites dead view * Remove unnecessary FIXME * Add LV tests for Sites * Calculate and display 24h visitors change * Render the change in bold * Add clarfying comment on virtual field in `Site` schema * Remove unnecessary function from Invitations API * Remove unused list opt from type definition in `Sites` * Improve joins in list query slightly * Add comment on manually computing sites list total * Start searching from a singly character in domain field * Add typespec to `last_24h_visitors_hourly_intervals` * Extend moduledoc in visitors component * Simplify loading sites in LV * Simplify assigns in LV * Add missing group for shadow under site card * Make invitation modal render * Make HTML in sites LV semantically correct * Remove autofocus and focus search on `/` * Remove shadow from search input * Make search cancel on escape * Fix tests relying on outdated HTML structure * Make visitor chart color scheme consistent with dashboard chart * Update styling of trend labels * Fix empty state and improve search blur/focus handling * Use live navigation for pagination * Implement spinner on load from search * Remove unused `Plausible.Stats.Clickhouse.last_24h_visitors/1` * Calculate uniques correctly across hour boundaries * Swap inlined svg for Heroicons component in invitation modal * Add order by to base query in 24h hourly intervals * Revert "Add order by to base query in 24h hourly intervals" This reverts commit a6be5e302662b3a90f68da0e3fdfa6ff271c168e. * Query clickhouse 24h visitors only on second mount * Remove redundant sign from percentage change when negative * Switch to offset-based pagination - offset seems easier to deal with for when actions on paginated list will be performed such as site pinning; tracking cursor data makes some entries disappear in edge cases. The data set is still fairly small and static, even for large customers. - we're removing Phoenix.Pagination as it doesn't really fir any use case, and it was only used to limit the number of sites in the site picker - site picker is now limited to 9 sites (future: pinned sites will be prioritized there) - no need to re-query for total count any more - BTW, the old /sites template was removed * Refine the plot queries; Tests pass snapshot * Add PromEx plugin for LiveView * Fix tiny plot cut-off at the top --------- Co-authored-by: Adam Rutkowski <hq@mtod.org>
2023-11-02 15:18:11 +03:00
test "renders 24h visitors correctly", %{conn: conn, user: user} do
site = insert(:site, members: [user])
populate_stats(site, [build(:pageview), build(:pageview), build(:pageview)])
{:ok, _lv, html} = live(conn, "/sites")
site_card = text_of_element(html, "li[data-domain=\"#{site.domain}\"]")
assert site_card =~ "3 visitors in last 24h"
assert site_card =~ site.domain
end
test "filters by domain", %{conn: conn, user: user} do
_site1 = insert(:site, domain: "first.example.com", members: [user])
_site2 = insert(:site, domain: "second.example.com", members: [user])
_site3 = insert(:site, domain: "first-another.example.com", members: [user])
{:ok, lv, _html} = live(conn, "/sites")
type_into_input(lv, "filter_text", "firs")
html = render(lv)
assert html =~ "first.example.com"
assert html =~ "first-another.example.com"
refute html =~ "second.example.com"
end
test "filtering plays well with pagination", %{conn: conn, user: user} do
_site1 = insert(:site, domain: "first.another.example.com", members: [user])
_site2 = insert(:site, domain: "second.example.com", members: [user])
_site3 = insert(:site, domain: "third.another.example.com", members: [user])
{:ok, lv, html} = live(conn, "/sites?page_size=2")
assert html =~ "first.another.example.com"
assert html =~ "second.example.com"
refute html =~ "third.another.example.com"
assert html =~ "page=2"
refute html =~ "page=1"
type_into_input(lv, "filter_text", "anot")
html = render(lv)
assert html =~ "first.another.example.com"
refute html =~ "second.example.com"
assert html =~ "third.another.example.com"
refute html =~ "page=1"
refute html =~ "page=2"
end
end
Implement pinned sites (#3469) * Revert "Remove site pins for now" This reverts commit 5eccf4eaf62508432d53c7557f79650ced0e6516. * 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 11:08:26 +03:00
describe "pinning" do
test "renders pin site option when site not pinned", %{conn: conn, user: user} do
site = insert(:site, members: [user])
{:ok, _lv, html} = live(conn, "/sites")
assert text_of_element(
html,
~s/li[data-domain="#{site.domain}"] a[phx-value-domain]/
Implement pinned sites (#3469) * Revert "Remove site pins for now" This reverts commit 5eccf4eaf62508432d53c7557f79650ced0e6516. * 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 11:08:26 +03:00
) == "Pin Site"
end
test "site state changes when pin toggled", %{conn: conn, user: user} do
site = insert(:site, members: [user])
{:ok, lv, _html} = live(conn, "/sites")
button_selector = ~s/li[data-domain="#{site.domain}"] a[phx-value-domain]/
Implement pinned sites (#3469) * Revert "Remove site pins for now" This reverts commit 5eccf4eaf62508432d53c7557f79650ced0e6516. * 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 11:08:26 +03:00
html =
lv
|> element(button_selector)
|> render_click()
assert html =~ "Site pinned"
assert text_of_element(html, button_selector) == "Unpin Site"
html =
lv
|> element(button_selector)
|> render_click()
assert html =~ "Site unpinned"
assert text_of_element(html, button_selector) == "Pin Site"
end
test "shows error when pins limit hit", %{conn: conn, user: user} do
for _ <- 1..9 do
site = insert(:site, members: [user])
assert {:ok, _} = Plausible.Sites.toggle_pin(user, site)
end
site = insert(:site, members: [user])
{:ok, lv, _html} = live(conn, "/sites")
button_selector = ~s/li[data-domain="#{site.domain}"] a[phx-value-domain]/
Implement pinned sites (#3469) * Revert "Remove site pins for now" This reverts commit 5eccf4eaf62508432d53c7557f79650ced0e6516. * 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 11:08:26 +03:00
html =
lv
|> element(button_selector)
|> render_click()
assert text(html) =~ "Looks like you've hit the pinned sites limit!"
end
test "does not allow pinning site user doesn't have access to", %{conn: conn, user: user} do
site = insert(:site)
{:ok, lv, _html} = live(conn, "/sites")
render_click(lv, "pin-toggle", %{"domain" => site.domain})
refute Repo.get_by(Plausible.Site.UserPreference, user_id: user.id, site_id: site.id)
end
end
Implement new sites view (#3463) * Implement complete basics of LV sites * Reimplement everything in LV except pagination * Implement basic search capability * PoC: plot visitors on sites index * Add rudimentary clipped gradient in minicharts * Fix clipping gradient, define once * Format * Add moduledoc to visitors component * Move paginator helpers to the top core namespace * Fix typespec of `Plausible.Sites.list` * Split sites component into subcomponents * Add function to uniformly calculate 24h intervals and visitor totals across multiple sites. * Integrate batch 24h interval query with plots on sites view * Don't confuse heex compiler with alpine @ shorthands * Make linear gradient svg definition truly invisible * Implement basic pagination * Extract `site_stats` from site and invitation cards * Improve pagination * Tweak css * Improve filtering on pagination and make WSS fail graceful * Test `last_24h_visitors_hourly_intervals/2` * Replace /sites with LV implementation * Add debounce to search filter * Fix typespecs * Fix styling * Fix mini graph scaling factor calculation * Fix search consuming itself * Minimal tweaks to the plots * Fixup * Remove magic numbers from the plot * Create `site_pins` table * Add `SitePin` schema * Implement listing invitations, sites and pins in a single query * Add FIXME note * Remove site pins for now * Add tests for `Plausible.Sites.list/3` * Add a couple more tests to sites dead view * Remove unnecessary FIXME * Add LV tests for Sites * Calculate and display 24h visitors change * Render the change in bold * Add clarfying comment on virtual field in `Site` schema * Remove unnecessary function from Invitations API * Remove unused list opt from type definition in `Sites` * Improve joins in list query slightly * Add comment on manually computing sites list total * Start searching from a singly character in domain field * Add typespec to `last_24h_visitors_hourly_intervals` * Extend moduledoc in visitors component * Simplify loading sites in LV * Simplify assigns in LV * Add missing group for shadow under site card * Make invitation modal render * Make HTML in sites LV semantically correct * Remove autofocus and focus search on `/` * Remove shadow from search input * Make search cancel on escape * Fix tests relying on outdated HTML structure * Make visitor chart color scheme consistent with dashboard chart * Update styling of trend labels * Fix empty state and improve search blur/focus handling * Use live navigation for pagination * Implement spinner on load from search * Remove unused `Plausible.Stats.Clickhouse.last_24h_visitors/1` * Calculate uniques correctly across hour boundaries * Swap inlined svg for Heroicons component in invitation modal * Add order by to base query in 24h hourly intervals * Revert "Add order by to base query in 24h hourly intervals" This reverts commit a6be5e302662b3a90f68da0e3fdfa6ff271c168e. * Query clickhouse 24h visitors only on second mount * Remove redundant sign from percentage change when negative * Switch to offset-based pagination - offset seems easier to deal with for when actions on paginated list will be performed such as site pinning; tracking cursor data makes some entries disappear in edge cases. The data set is still fairly small and static, even for large customers. - we're removing Phoenix.Pagination as it doesn't really fir any use case, and it was only used to limit the number of sites in the site picker - site picker is now limited to 9 sites (future: pinned sites will be prioritized there) - no need to re-query for total count any more - BTW, the old /sites template was removed * Refine the plot queries; Tests pass snapshot * Add PromEx plugin for LiveView * Fix tiny plot cut-off at the top --------- Co-authored-by: Adam Rutkowski <hq@mtod.org>
2023-11-02 15:18:11 +03:00
defp type_into_input(lv, id, text) do
lv
|> element("form")
|> render_change(%{id => text})
end
Move limit enforcement to accepting site ownership transfer (#3612) * Move limit enforcement to accepting site ownerhsip transfer * enforce pageview limit on ownership transfer accept * Refactor plan limit check logic * Extract `ensure_can_take_ownership` to `Invitations` context and refactor * Improve styling of exceeded limits notice in invitation dialog and disable button * styling improvements to notice * make transfer_ownership return transfer to self error * do not allow transferring to user without active subscription WIP * Add missing typespec and improve existing ones * Fix formatting * Explicitly label direct match on function argument for clarity * Slightly refactor `CreateInvitation.bulk_transfer_ownership_direct` * Exclude quota enforcement tests from small build test suite * Remove unused return type from `invite_error()` union type * Do not block plan upgrade when there's pending ownership transfer * Don't block and only warn about missing features on transfer * Remove `x-init` attribute used for debugging * Add tests for `Quota.monthly_pageview_usage/2` * Test and improve site admin ownership transfer actions * Extend tests for `AcceptInvitation.transfer_ownership` * Test transfer ownership controller level accept action error cases * Test choosing plan by user without sites but with a pending ownership transfer * Test invitation x-data in sites LV * Remove sitelocker trigger in invitation acceptance code and simplify logic * Add Quota test for `user.allow_next_upgrade_override` being set * ignore pageview limit only when subscribing to plan * Use sandbox Paddle instance for staging * Use sandbox paddle key for staging and dev --------- Co-authored-by: Robert Joonas <robertjoonas16@gmail.com>
2023-12-20 17:56:49 +03:00
defp get_invitation_data(html) do
html
|> text_of_attr("div[x-data]", "x-data")
|> String.trim("dropdown")
|> String.replace("selectedInvitation:", "\"selectedInvitation\":")
|> String.replace("invitationOpen:", "\"invitationOpen\":")
|> String.replace("invitations:", "\"invitations\":")
|> Jason.decode!()
end
Implement new sites view (#3463) * Implement complete basics of LV sites * Reimplement everything in LV except pagination * Implement basic search capability * PoC: plot visitors on sites index * Add rudimentary clipped gradient in minicharts * Fix clipping gradient, define once * Format * Add moduledoc to visitors component * Move paginator helpers to the top core namespace * Fix typespec of `Plausible.Sites.list` * Split sites component into subcomponents * Add function to uniformly calculate 24h intervals and visitor totals across multiple sites. * Integrate batch 24h interval query with plots on sites view * Don't confuse heex compiler with alpine @ shorthands * Make linear gradient svg definition truly invisible * Implement basic pagination * Extract `site_stats` from site and invitation cards * Improve pagination * Tweak css * Improve filtering on pagination and make WSS fail graceful * Test `last_24h_visitors_hourly_intervals/2` * Replace /sites with LV implementation * Add debounce to search filter * Fix typespecs * Fix styling * Fix mini graph scaling factor calculation * Fix search consuming itself * Minimal tweaks to the plots * Fixup * Remove magic numbers from the plot * Create `site_pins` table * Add `SitePin` schema * Implement listing invitations, sites and pins in a single query * Add FIXME note * Remove site pins for now * Add tests for `Plausible.Sites.list/3` * Add a couple more tests to sites dead view * Remove unnecessary FIXME * Add LV tests for Sites * Calculate and display 24h visitors change * Render the change in bold * Add clarfying comment on virtual field in `Site` schema * Remove unnecessary function from Invitations API * Remove unused list opt from type definition in `Sites` * Improve joins in list query slightly * Add comment on manually computing sites list total * Start searching from a singly character in domain field * Add typespec to `last_24h_visitors_hourly_intervals` * Extend moduledoc in visitors component * Simplify loading sites in LV * Simplify assigns in LV * Add missing group for shadow under site card * Make invitation modal render * Make HTML in sites LV semantically correct * Remove autofocus and focus search on `/` * Remove shadow from search input * Make search cancel on escape * Fix tests relying on outdated HTML structure * Make visitor chart color scheme consistent with dashboard chart * Update styling of trend labels * Fix empty state and improve search blur/focus handling * Use live navigation for pagination * Implement spinner on load from search * Remove unused `Plausible.Stats.Clickhouse.last_24h_visitors/1` * Calculate uniques correctly across hour boundaries * Swap inlined svg for Heroicons component in invitation modal * Add order by to base query in 24h hourly intervals * Revert "Add order by to base query in 24h hourly intervals" This reverts commit a6be5e302662b3a90f68da0e3fdfa6ff271c168e. * Query clickhouse 24h visitors only on second mount * Remove redundant sign from percentage change when negative * Switch to offset-based pagination - offset seems easier to deal with for when actions on paginated list will be performed such as site pinning; tracking cursor data makes some entries disappear in edge cases. The data set is still fairly small and static, even for large customers. - we're removing Phoenix.Pagination as it doesn't really fir any use case, and it was only used to limit the number of sites in the site picker - site picker is now limited to 9 sites (future: pinned sites will be prioritized there) - no need to re-query for total count any more - BTW, the old /sites template was removed * Refine the plot queries; Tests pass snapshot * Add PromEx plugin for LiveView * Fix tiny plot cut-off at the top --------- Co-authored-by: Adam Rutkowski <hq@mtod.org>
2023-11-02 15:18:11 +03:00
end