Commit Graph

441 Commits

Author SHA1 Message Date
Adam Rutkowski c78ddf6ba4
Update migration that failed to run (#5946)
* Update migration that failed to run

* !fixup
2025-12-11 12:49:36 +00:00
Adam Rutkowski 40f0d4bfbf
Migration: make `goals.custom_props` non-null (#5945) 2025-12-11 12:22:36 +00:00
Adam Rutkowski b299aa352a
Migration: goal custom props + revamped unique constraints (#5940)
* Migration: add custom propos to goals + revisit unique constraints

* Fixup migration
2025-12-11 08:26:44 +00:00
Adrian Gruntkowski 16f1eb3075
Add necessary scaffolding for enabling LV on dashboard (#5930)
* Use forked version of

* Add necessary scaffolding for enabling LV on dashboard

* Implement basics for LV pages breakdown

* Make tile and tabs latency friendly

* Bring back eslint-disable pragma in live_socket.js

* Document the code somewhat

* Fix live navigation callback in React

* Make dashboard components inside portals testable

* Add very rudimentary basic tests

* Fix typo

* Fix eslint pragma in `live_socket.js`
2025-12-08 11:46:56 +00:00
Artur Pata 1ff2b52cbb
Add :segment_id field to shared_links schema (#5924)
* Add :limited_to_segment_id field to shared_links schema

* Refactor column name, add FK, index, and on delete cascade

* Format
2025-12-04 10:50:07 +00:00
Adam Rutkowski 5fe2be8dc8
Remove :consolidated_view feature flag (#5908) 2025-11-24 11:42:15 +00:00
Adam Rutkowski 35f1cea344
Migration: add consolidated views feature to enterprise plans (#5878) 2025-11-17 09:07:30 +00:00
Adam Rutkowski 08c7d2e948
Consolidated View life cycle + billing integration (#5866)
* Migration: add consolidated views feature to enterprise plans

* Migration: Add user preferences per team table

* Update static plan definitions

* Add feature module definition

* Display consolidated view availability in crm

* Extend ConsolidatedView interface:
 - add functions to manipulate user/team options (for CTA)
 - require at least two sites in order to create a consolidated view
 - require billing/plan compliance when computing eligibility

* Team/User preferences schema

* Implement consolidated view life cycle on /sites

Co-authored-by: Sanne de Vries <sannedv@protonmail.com>
Co-authored-by: Uku Taht <uku.taht@gmail.com>

* Enroll `consolidated_view` feature flag

* Consolidated view access hardening (+feature flag)

- require team-wise feature flag instead of super admin role
- redirect to /sites if the team isn't eligible any more
- enforce regular site in shared links controller

* Remove no longer needed `ConsolidatedView.enabled?/1`

* Alias PrimaDropdown

* No consolidates views for shared links

* Remove user argument from `ok_to_display?`

* Adjust a temporary test

* More elaborate alert

* Fix responsive design issues on sites page

- Fix z-index issue with button dropdown
- Fix truncation issue with team name
- Improve responsiveness of site cards
- Fix focus state of site cards
- Improve responsiveness of consolidated view CTA
- Improve design of prima_dropdown component
- Replace `+` with plus icons in dropdown items

* Use the plus icon for standalone "Add website" too

cc @sanne-san

* Format

* Fix z-index issue with dropdowns on sites page

* Remove TODOs

* Make consolidated view cards disappear when searching

* Clean up test

* Use per-team membership user preferences

* Use conditional instead of `with` statement

* Inline `ensure_eligible`

* Use `Map.fetch!` getting preference from default struct

* fixup

* Revert "Migration: add consolidated views feature to enterprise plans"

Will be included via main branch sync

This reverts commit 05bec55276.

* Fix and test feature-flag effect on both view and CTA cards

---------

Co-authored-by: Sanne de Vries <sannedv@protonmail.com>
Co-authored-by: Uku Taht <uku.taht@gmail.com>
2025-11-12 13:41:24 +00:00
Adam Rutkowski b0e8c8bdd0
Migration: team membership user preferences table (#5881) 2025-11-12 10:47:00 +00:00
Adrian Gruntkowski 62e9ec5f05
Add `recovery_id` column to `sessions_v2` and `events_v2` (#5875) 2025-11-07 15:04:01 +00:00
Adrian Gruntkowski 592dc8ed97
Add migration adding `teams.policy` to CE (#5868) 2025-11-04 16:09:50 +00:00
Sanne de Vries 91363a2825
Improve dark mode (#5819)
* Improve dark mode

- Switch from `slate` to `zinc` for the gray color palette
- Darken overall dark mode UI
- Switch from `green` to `emerald` for the green color palette
- Update a few previously missed instances of title case to sentence case
- Consolidate button styles and change naming from `bright` to `secondary`
- Update button disabled styles
- Fix tooltip not adjusting to content width
- Update graph tooltip layout and typography
- Add transition effects to hover states
- Reduce footer logo size

* Fix oversights

- Update funnel graph colors
- Update graph grid colors
- Improve focus styles
- Improve disabled input styles

* Fix more oversights in relation to dashboard filtering

- Improve consistency of input, button, combobox and modal components in relation to settings area
- Fix segment tooltip color

* Fix search input style in funnel and segments dropdowns

* Add white background to favicon images in dark mode

- The GitHub and ChatGPT favicons are hard to see in dark mode, so we add a white background to them.

* Fix tooltip color to fit all backgrounds in dark mode

* Fix tests

* Fixed more tests

* Extract SourceFavicon component to eliminate favicon duplication

* Fix regression on installation page after rebase

* Fix formatting issues

* Fix favicon test failure in CI by reading placeholder icon at compile time

* Undo previous commit
2025-10-28 08:28:15 +00:00
RobertJoonas a83b4f3583
Clean up legacy verification code and script v2 flag (#5824)
* add module name to service_error when check times out

Otherwise, it can sometimes remain unclear in the diagnostics, whether
it was InstallationV2 or InstallationV2CacheBust that timed out.

* Remove duplicate timeout logic

The current production logs show two types of verification timeouts:

* service_error: "Unhandled Browserless response status: 408" (vast
  majority of cases)
* service_error: :timeout (only a few cases)

The latter happens when we hit the Req receive_timeout
(endpoint_timeout + 2s). I've seen Browserless not respect the timeout
param from time to time, so it's better to keep the timeout logic
"in-house" only.

* make service_error into a map with code and extra

* interpret temporary service errors

...but still consider them "unhandled" for telemetry, also notifying Sentry
and logging the warning.

* separate sentry messages (verification)

* make Verification.ChecksTest more DRY

* organize tests into describe blocks

* test verification telemetry and logging

* fix codespell

* get rid of legacy verification

* rename Checks.InstallationV2 -> Checks.VerifyInstallation

* delete Live.Installation and rename Live.InstallationV2 -> Live.Installation

* rename installationv2 (live) files as well

* delete old change-domain routes

Also rename current liveview modules and routes, removing the v2 suffix

* rename domain_change_v2 files, removing v2 suffix

* remove legacy JS verifier code

Also fix dockerignore and elixir.yml referencing a wrong priv path

* rename verification_v2_test -> verification_test

* remove v2 prefix from logs and sentry messages

* clean up duplicate external_sites_controller_test.exs tests

* remove flag

* fix typespec

* pass timeout as query param to Browserless too

* Fixup external sites controller test module (#5826)

* fix test description

---------

Co-authored-by: Artur Pata <artur.pata@gmail.com>
2025-10-27 09:39:41 +00:00
Adam Rutkowski bce08903e5
Integrate consolidated view UI (#5798)
* Create static consolidated view UI on `/sites` page

- Improve existing site card layout
- Add static UI for the consolidated view
- Add dismissable upgrade card UI
- Extract favicon fetching logic to function
- Configure configurable fallback icon per route
- Add `/favicon/sources_globe/` route with different icon than `/favicon/sources/` to use on `/sites` page

* Improve the mobile view of the `/sites` page

* Minor query interface UX extension (#5713)

* Minor query interface extension

* !fixup

* !fixup

* Initial implementation of consolidated views on /sites

* Improve loading state

* no need to handle nil in main interface

* Juggle `can_manage_consolidated_view?`

* Require team setup in order to enable consolidated view

* nil catcher

* Fixup test fixture

* Don't show Consolidated View tab in CS if team is not setup

* Reorganize + test

* Remove comment

* Only show consolidated views to superadmins for now

* Remove temporary sleep

* CE unused bindings

* Clean up seeds

* EE

* Fixup test

* Test non-superadmin scenario

* Add a test guarding parity between small plots (consolidated vs individual)

* Move private function so CE won't complain

* See if the graphs are now similar at least :)

* sort

* Map keys are unsorted

* Ensure engagement events aren't counted as visitors on smol graphs

* just try and revert

* Revert "just try and revert"

This reverts commit 7584f59816.

* Simplify globe icon handling

* Remove unnecessary @rest

* Split tests into more focused cases

* Address jumpiness on furious refresh cycle

* Revert "Address jumpiness on furious refresh cycle"

This reverts commit 5c03b36918.

* Another attempt at jumpiness

* Enforce less noticeable lag applying the diff from loading to loaded

* Reduce flashing on stats load

---------

Co-authored-by: Sanne de Vries <sannedv@protonmail.com>
2025-10-22 10:58:26 +00:00
Uku Taht 46000fd4bc
Implement custom date/time range comparisons (#5805)
* Implement custom date/time range comparisons

* Update ts schema

* Use Etc/UTC, not UTC - timezone shifted structs are differrent otherwise

* Remove debug statement

* Adjusts timezone in tests

---------

Co-authored-by: Adam Rutkowski <hq@mtod.org>
2025-10-16 06:14:49 +00:00
Adam Rutkowski 63a89cab8e
Migration: index for caching consolidated views (#5752) 2025-09-24 14:36:51 +00:00
Adam Rutkowski b40ea25645
Make `sites.consolidated` column available in CE (#5744) 2025-09-22 11:54:43 +00:00
RobertJoonas 2be1220b70
Migration: Consolidated views (#5735)
* add migration

* behind ee_only + index

* no index yet
2025-09-18 10:18:23 +00:00
Karl-Aksel Puulmann 9af40a278d
Trim month, year, day periods to local now on main graph (#5698)
* Revert "Revert "Trim `month`, `year`, `day` periods to local now on main graph (#5668)" (#5684)"

This reverts commit 2d11681f25.

* Does not trim for comparisons

* Include the current hour in the trimmed time range
2025-09-04 09:13:17 +00:00
RobertJoonas 110f97d442
CE: Fix v2 onboarding, review installation, and domain change flows (#5692)
* fix seeds.exs for CE

* unified FF function

* remove gtm tab on ce

* CE change domain flow: remove detection logic

* CE installationv2 (review & provisioning flows) + tests

* change domain tests

* fix tests

* FF for user too

* small improvements (review comments)

* keep the CE and EE versions of the same function together
2025-09-03 17:22:18 +00:00
Adrian Gruntkowski 2d11681f25
Revert "Trim `month`, `year`, `day` periods to local now on main graph (#5668)" (#5684)
This reverts commit 563c3d22ba.
2025-08-28 14:58:57 +00:00
Adam Rutkowski 563c3d22ba
Trim `month`, `year`, `day` periods to local now on main graph (#5668)
* Trim `month`, `year`, `day` periods to now on main graph

* Revert "Trim `month`, `year`, `day` periods to now on main graph"

This reverts commit 4f3930111d3a2737a51686e067d9b64f0d85ad58.

* Re-implement trimming in query optimizer instead

* Update JS types

* This is getting confusing

* Trim in stats_controller

* Set `query.now` based on query_praser and date results

* query.period -> query.input_date_range

* Changelog

* Test for response query.date_range

---------

Co-authored-by: Karl-Aksel Puulmann <oxymaccy@gmail.com>
2025-08-28 09:51:56 +00:00
RobertJoonas 17675af4d0
Clean up old upgrade page (dead code) (#5652)
* remove deprecated modules/fns

* get rid of starter_tier flag

* remove legacy? arg from plans
2025-08-19 09:12:48 +00:00
Karl-Aksel Puulmann 23d14edd07
ScriptV2: Add updated_at index to tracker_script_configuration (#5632)
The cache uses updated_at column to look for recently updated rows. This makes that scan cheaper.

Before (full table scan):
```
postgres@127:plausible_dev> explain analyze select * from tracker_script_configuration where updated_at > now() - interval '1 minute'
+-----------------------------------------------------------------------------------------------------------------------------------------------+
| QUERY PLAN                                                                                                                                    |
|-----------------------------------------------------------------------------------------------------------------------------------------------|
| Gather  (cost=1000.00..19849.11 rows=35 width=60) (actual time=177.554..180.492 rows=0 loops=1)                                               |
|   Workers Planned: 2                                                                                                                          |
|   Workers Launched: 2                                                                                                                         |
|   ->  Parallel Seq Scan on tracker_script_configuration  (cost=0.00..18845.61 rows=15 width=60) (actual time=172.125..172.126 rows=0 loops=3) |
|         Filter: (updated_at > (now() - '00:01:00'::interval))                                                                                 |
|         Rows Removed by Filter: 336668                                                                                                        |
| Planning Time: 0.122 ms                                                                                                                       |
| Execution Time: 180.527 ms                                                                                                                    |
+-----------------------------------------------------------------------------------------------------------------------------------------------+
```

After (index scan):
```
postgres@127:plausible_dev> explain analyze select * from tracker_script_configuration where updated_at > now() - interval '1 minute'
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| QUERY PLAN                                                                                                                                                                  |
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Index Scan using tracker_script_configuration_updated_at_index on tracker_script_configuration  (cost=0.43..4.45 rows=1 width=60) (actual time=0.004..0.005 rows=0 loops=1) |
|   Index Cond: (updated_at > (now() - '00:01:00'::interval))                                                                                                                 |
| Planning Time: 0.568 ms                                                                                                                                                     |
| Execution Time: 0.013 ms                                                                                                                                                    |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
EXPLAIN 4
```
2025-08-13 05:41:43 +00:00
Artur Pata c53cb7b2e9
Add migration to run 'pa-' prefixing (#5622) 2025-08-11 10:43:50 +00:00
Adam Rutkowski ca2611fc83
Migration: audit entries (#5581)
* Migration: audit entries

* Put migration behind EE conditional
2025-07-22 10:22:56 +00:00
RobertJoonas 97dcc3fe7c
Refactor Verification module structure (#5570)
* detector.js

* refactor: organize modules better

* Renaming (Elixir + JS)

* lib/plausible/verification -> lib/plausible/installation_support
* test/plausible/verification -> test/plausible/installation_support
* priv/tracker/verifier -> priv/tracker/installation_support
* tracker/verifier -> tracker/installation_support
* tracker/test/verifier -> tracker/test/installation-support

* rename remaining test modules

* add documentation

* dialyzer: remove module refs that do not exist yet

* Fix CI

* fix tracker CI

* fix tracker CI for good
2025-07-15 10:50:34 +00:00
RobertJoonas b76996b3a4
Verification v2 (#5549)
* new verifier script with tests + telemetry

* dataDomainMismatch tests

* more tests for callbackStatus and plausibleInstalled

* create priv/verifier subfolder + fix Elixir CI

* bump CI cache version

* organize verifier tests

* Remove accidentally committed verifier

* Rework compilation: Make it a variant, always return new verifier code in tests

* Make priv/tracker/verifier/ exist

* Handle static checks with grace

* Fix paths

* Fix paths

* Add some tests

* Add one more test

* split up the JS

* proxyLikely + code structure refactor + unit tests

* fix telemetry fields

* move most telemetry to logs

* run verifier tests only on chromium

* detect wordpressPlugin and wordpressLikely

* detect GTM

* rename JS checks

* detect cookiebot

* include new fields in logs

* different logs for browserless request vs js failures

* detect manual extension

* detect unknown attrs + fix logging

* stick to Elixir checks for snippet detection

* fix codespell

* fix IO.inspect

* remove unnecessary fields from test mock

* cookiebot doc

* move test into verifier subfolder

* do not duplicate ts types

* comma -> semicolon in log

* test dynamically loaded snippet

* improve logging on Browserless error

---------

Co-authored-by: Karl-Aksel Puulmann <oxymaccy@gmail.com>
2025-07-14 14:32:21 +00:00
Adam Rutkowski 24d4ae6a58
Migration: Add `users.last_team_identifier` (#5527) 2025-06-24 15:02:25 +00:00
Adam Rutkowski 245002a34d
Migration: SSO Domain - remove unused columns (#5509) 2025-06-17 05:35:47 +00:00
Adam Rutkowski 1aea8940d2
Migration: SSO domains: s/validated/verified (#5507)
* Migration: SSO domains: s/validated/verified

Should be safe to run since there's no domains
on neither prod or staging

* Galaxy brain
2025-06-16 13:21:10 +00:00
RobertJoonas 0e9b354a45
add migration (#5472) 2025-06-05 12:49:03 +00:00
Adrian Gruntkowski d242e4ecdd
Add unique index on `users.sso_identity_id` (#5470) 2025-06-04 10:08:23 +00:00
Adrian Gruntkowski 7ccaebfee7
Add `users.sso_domain_id` FK and alter `users.sso_integration_id` FK (#5464)
* Add `users.sso_domain_id` FK and alter `users.sso_integration_id` FK

* Run the migration only on EE

* Add index on `users.sso_domain_id`
2025-06-03 13:57:30 +00:00
hq1 f8c36797ae
Remove `teams` feature from custom plans (#5460) 2025-06-03 10:59:44 +00:00
RobertJoonas 38f1de6ecd
Starter Tier: Teams UI follow-ups (#5456)
* keep teams feature explicitly for UI

* keep devsubscriptions in sync with prod

On prod, when a subscription is created without a current team in assings,
a new team is force created for that user.

* disable team creation when no point to create it

* fix ce_test compile warning

* fix tests on CE

* Update lib/plausible/teams/billing.ex

Co-authored-by: hq1 <hq@mtod.org>

* add solo team in seeds

* fix top border blur + stop autofocusing input when blurred

---------

Co-authored-by: hq1 <hq@mtod.org>
2025-06-03 10:14:50 +00:00
RobertJoonas e38bda6d00
Starter feature gates (UI) (#5426)
* replace yellow warning notice with more inviting cta (funnels)

* align VAT notice with /year on the upgrade page

* improve tooltip component

do not hide the tooltip when the mouse enters the tooltip itself directly
from the trigger element. This allows clicking links in tooltips.

* improve site segments feature gate UI

Disable the save button when site segment option is selected in create or
edit form. Also render a different upgrade notice if the user is not the owner.

* replace upgrade notices with blur UI

To fully get rid of Notice.premium_feature, we will also display a
"not allowed" cursor with tooltips asking to upgrade where necessary.

* extract toggle switch component

* Hide currency toggle from goal edit form

The currency field cannot be changed for an existing goal anyway. Therefore
it makes sense not to show it at all. This commit makes the currency picker
always visible when editing a revenue goal, and always hidden for custom
event edit form.

* simplify api key creation form

Turn "Sites API access" into a toggle switch identical to "Enable revenue
tracking" in goal creation form.

* remove team setup CTAs for Starter tier

* fix team member limit for starter

* adjust v5 plan limits and limit exceeded notices

* do not display global notices on upgrade-success page

* fix settings/subscription monthly quota boxes alignment

* fix CI

* use tailwind backdrop-blur

* remove dangling log + avoid passing setSaveDisabled

* remove duplicate function clauses revenue goals

* revert create api key UI change but disable button still

* optimize for darkmode

* blur team settings > team members for Starter

* rename team accounts to team management
2025-05-30 13:34:19 +00:00
hq1 ca7804cf86
Add `teams.locked_by_admin` column (#5438) 2025-05-28 10:12:38 +00:00
Karl-Aksel Puulmann 93dfb21669
tracker_script_configuration: backfill (step 3) (#5408)
* tracker_script_configuration table migration

* tracker_script_configuration schema + upsert tests

* TrackerScriptConfiguration: read from installation_meta, double-write, refactor installation flow to work off of new model

* Fix a test

* Backfill tracker script configuration
2025-05-26 12:31:22 +00:00
Karl-Aksel Puulmann e3914c9df6
tracker_script_configuration table migration (#5406) 2025-05-26 10:04:42 +00:00
Adrian Gruntkowski ea53582165
Add migration adding SSO-related schemas, columns and indexes (#5413) 2025-05-21 09:27:00 +00:00
RobertJoonas 2dd144bf85
Starter tier: Upgrade page remodelling (#5394)
* add a new (feature flagged) upgrade page offering v5 plans

* include starter tier plans in available_plans_for + use dev prices in test

* upgrade page remodelling with starter tier

* mobile optimizations

* optimize for darkmode

* add embedded dashboards as a growth benefit

* do not hide header on LegacyChoosePlan

* consistent v5 plan feature order

* slight grandfathering notice adjustment

* display monthly price too on yearly plans

* default to v5 plans unlesss legacy? is true

* refactor: suggest volume not plan for emails

* align back link with page title

* render grandfathering notice for growth v4 too
2025-05-20 13:22:12 +00:00
RobertJoonas 18907aef63
Starter Tier: Add plans and Mix tasks (#5392)
* fix sandbox plans v4 to be in sync with prod ones

* sync sandbox plans + unify formatting

* create v5 plans in paddle prod + sandbox + Mix.tasks

* add teams and shared links features

* remove unused line of code

* paddle credentials as module attrs

* remove teams and shared links as growth benefits for time being
2025-05-15 10:02:43 +00:00
Artur Pata 429b055920
Update headlessui to v1.7.19, refactor site switcher (#5255)
* Migrate some

* Making progress

* All fixed

* Convert interval picker to tsx

* Fix format

* Fix tests

* Make sure focus outline looks right on DropdownTabButton

* Refactor Site Switcher to Popover

* Fix site switcher test

* Better jsdom mocks in assets tests

* Try svg placeholder favicon

* Update favicon test

* Try giving transition config directly

* Remove empty props

* Remove unnecessary closeDropdown to prevent Firefox transition issue

* Register open dropmenus globally

This is needed to prevent invalid state when navigating with site hotkeys with Firefox while a dropdown is open and coming back using browser

* Colocate popover-specific component

* Clarify behaviour on hitting hotkey for current site

* Try fix Firefox issue

* Try 1.7.19

* Commit to @headlessui/react v1.7.x

* Fix last two transition origins

* Align active tab on baseline

* Remove unneeded global dropmenu state

* Add changelog

* Funnels menu is searchable and scrollable

* Fix transform origin

* Stop funnels menu from holding onto search state

* Mandate ref be passed to SearchInput from the outside
2025-05-07 05:22:53 +00:00
RobertJoonas 1de37a125c
Staging subscriptions (#5349)
* sandbox_plans.json -> sandbox_plans_v4.json

* add mix task and generate sandbox plans

* manually add sandbox_legacy_plans.json

* make all staging plans consistent with prod

* slight code style improvement

* add kb link
2025-05-05 09:23:19 +00:00
Adrian Gruntkowski a147aea0c1
Implement backfill migration for enterprise plans (#5368) 2025-04-29 15:23:05 +00:00
Karl-Aksel Puulmann a3db3af806
Avoid compiling pageleave variant and p.js (#5351)
* Avoid compiling pageleave variant

Instead, it's treated as a no-op. Tracker still serves it.

Compile wall time went down from 86s -> 46s.

* Vendor, no longer compile p.js

This was a legacy script variant which we keep for backwards
compatibility but little else.

* chore: Bump tracker_script_version to 6
2025-04-29 06:42:48 +00:00
RobertJoonas cb465511bb
Streamline creating/updating/deleting subscriptions in development (#5328)
* streamline dev subscriptions

* spawn -> Task

* fix button alignment

* do not define routes in test env

* remove explicit mentions of dev env when deciding whether to sandbox paddle

* decide checkout behaviour at compile time

* Timex -> Date

* hum

* make it work for enterprise plans too

* allow convenient subscription status change

* fix ci warnings

* remove redundant commented out code

* fix crash + review suggestion

---------

Co-authored-by: Adam Rutkowski <hq@mtod.org>
2025-04-16 13:43:17 +00:00
Adrian Gruntkowski 3097c1fd6e
Remove tables and columns that are unused after migrating to teams (#5287)
* Remove tables and columns that are unused after migrating to teams

* Do not alter FK constraint on `sites.team_id`

* Set null constraint on team_id FKs
2025-04-15 09:31:28 +00:00
hq1 cdf27e63c6
Move teams backfill migration to the end (#5320) 2025-04-11 09:46:07 +00:00