* Migration: add country rules
* Add CountryRule schema
* Implement CountryRule cache
* Add country rules context interface
* Start country rules cache
* Lookup country rules on ingestion
* Remove :shields feature flag from test helpers
* Add nested sidebar menu for Shields
* Fix typo
* IP Rules: hide description on mobile view
* Prepare SiteController to handle multiple shield types
* Seed some country shield
* Implement LV for country rules
* Remove "YOU" indicator from country rules
* Fix small build
* Format
* Update typespecs
* Make docs link point at /countries
* Fix flash on top of modal for Safari
* Build the rule struct with site_id provided up-front
* Clarify why we're messaging the ComboBox component
* Re-open combobox suggestions after pressing Escape
* Update changelog
* Fix font size in country table cells
* Pass `added_by` via rule add options
* Display site's timezone timestamps in rule tooltips
* Display formatted timestamps in site's timezone
And simplify+test Timezone module; an input timestamp converted
to UTC can never be ambiguous.
* Remove no-op atom
* Display the maximum number of rules when reached
* Improve readability of remove button tests
* Credo
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
Follow-up to https://github.com/plausible/analytics/pull/3719
The previous behavior was predicated on:
- Allowing a single custom property filter
- Allowing breaking down only by the chosen custom property filter
Now these restrictions are removed the previous auto-switching just becomes annoying
* Replace footer text
* add COPYING.txt file
* Add new logos
* Use new logos in all layouts
* New logos
* Check license key on startup
* Bypass license check when Mix.env == :dev
* Use new logos with smaller wordmarks
* Add generic logo_path/1 function
* Use new favicons everywhere
* Bypass license check in test env
* Use sha256 for license key hash
* Mix.env -> config_env()
* Use Mix.evn at compile time rather than runtime
* Mix format
---------
Co-authored-by: Uku Taht <uku.taht@gmail.com>
* Revert "Unify percentage change for CR and bounce_rate (#3781)"
This reverts commit a6b1a6ebc7.
* Revert "Bring Stats API up to speed: Add `conversion_rate` to Aggregate and Breakdown (#3739)"
This reverts commit 672d682e95.
* WIP
* Allow `experimetnal_session_count` request serialization
* Extend `Plausible.Stats.Query` with `experimental_session_count` flag
* Add `FunWithFlags` actor implementation for `Site`
* Change the way sessions are retrieved
* Remove redundant test
* Format
* Update the test
---------
Co-authored-by: Uku Taht <uku.taht@gmail.com>
* disable event metric with include_imported in every case
* add missing test for metric validation
* refactor metric validation functions
* implement conversion_rate metric validation
* move calculate_cr function into Stats.Util
* Refactor: Move aggregate CR logic into Stats.aggregate
* define atoms to exist
* Ensure that CR does not depend on visitors being queried
If 'visitors' are already queried, we'll use that value. Otherwise we'll
need to make another query to fetch it.
* confirm Stats API aggregate supports CR (tests only)
* small refactor
This is the only 'event_property' left after pattern matching on all
others in the function clauses defined above.
* Make it possible to optionally query conversion_rate
...in breakdown queries (excluding goal and custom prop breakdown)
* A little refactor asking for revenue metrics
1. The `@revenue_metrics` module attribute is an empty list on full build
anyway
2. We don't need to query for revenue metrics if there are no revenue goals
returned in the given query (even if revenue goals exist in site.goals)
3. Revenue metrics are already dropped in prop breakdown without a goal
filter via (get_revenue_tracking_currency/3)
* Make it possible to optionally query conversion_rate (continuation)
... also from a custom prop and goal breakdown
* Frontend adjustments to the Locations report
* Display conversion rate in Regions and Cities (ListReport view)
* Display total conversions, conversions (visitors), and CR in the
"Details" modals of Countries, Regions, and Cities
* Move the percentage into a separate column in the Countries details table
* confirm Stats API breakdown supports conversion_rate (tests only)
* small refactor: extract maybe_add_time_on_page function
* Make it possible to query cr alone
... (without the visitors metric). Already supported in aggregate, this
commit only implements it for the breakdown API.
* Reuse Stats.Util helper functions from b02db88 for aggregate API
We can follow the same logic as with breakdown for manually adding
`visitors` into the metrics list and taking it out of the response
later on.
That way we don't have to make another query, e.g. in a case where
only pageviews and conversion rate is queried. Also keeps things
consistent.
* changelog update
* fix test after resolving merge conflict
* Use explicit string->atom mapping instead of casting
* alias Util module instead of importing it
* use Enum.empty instead of Enum.any
* improve readability
* rename special_metrics to computed_metrics and explain with a comment
* rename visitors_without_event_filters to total_visitors
* keep a single function for removing unwanted metrics
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Support using matches/contains for most filters
* Change behavior where we auto-zoom to specific browser/os/source to only do so if filtering on a single value
* No contains filtering on `location`
* Update CHANGELOG.md
* Fix merge conflict
* WIP: PropFilterRow
* Get multi-behavior working
* Render multiple prop filters in one
* Modal reads from query string correctly
* Backend support for multiple custom property filters
* Add backend tests for multiple custom property filters
* Disable already selected options in property keys
We can't allow choosing the same property multiple times without changing the request
params, which we decided against
* Allow choosing any property under Behaviors > Custom props even if custom prop filter applied
This was a limitation (I believe) introduced by using ARRAY JOINs to query custom properties
* CHANGELOG.md
* Solve credo warning about too deep nesting
* Update assets/js/dashboard/stats/modals/prop-filter-modal.js
Co-authored-by: RobertJoonas <56999674+RobertJoonas@users.noreply.github.com>
* Refactor internal function for clarity
* Add another step -> Add another
* Solve 500 error
* Separate boxes per property filter
* Retain other filters in props table
* removeFilter behavior for props
* matches_member support for custom props
* filter_suggestions for prop keys should account for prop filter
* find over filter
* refactor appliedFilters
* FILTER_TYPES => FILTER_OPERATIONS
* Make add another link not wrap the whole page
* Unique keys
---------
Co-authored-by: RobertJoonas <56999674+RobertJoonas@users.noreply.github.com>
* Allow `matches` operator to work in BE for custom props
Note: No FE support yet, needs further testing
* feat: allow choosing `contains` for property filters in the UI
* no autocomplete on prop values if `contains` for consistency
* CHANGELOG.md
* Fix: Handle (none) property in property breakdowns when using matching
When matching we should always exclude (none)
* Make modal for goal settings trigger without BE roundtrip
* Turn goal form into a live component and extract modal into a wrapper
* Further extract modal component and handle reset action
* Make ComboBox selection callback more flexible
* Add rudimentary loading state to dialog
* Make form unaware of being put inside a modal
* Make modal a live component and completely reset contents on open server-side
* Try to avoid race condition
* Fix race condition
* Remove unnecessary conditional on socket assigns
* Add typespecs and fix formatting
* Make goals form high latency friendly
* Fix tests to account for goal settings form becoming live component
* Fix goal settings form live component declaration
* Add documentation for modal
* Fix small build test
* Fix typo
Co-authored-by: hq1 <hq@mtod.org>
* Revert no longer necessary test changes from 46f65d9
* Fix and clean up modal styling
* Keep focus on dialog when open and show only spinner on backdrop when loading
* Adjust corners and shadows and implement open/close transitions
* Lock body scroll when modal is open
* Make modal top-aligned again to avoid jumping around on variable content height
---------
Co-authored-by: hq1 <hq@mtod.org>
* Revert "Remove unused RocketIcon"
This reverts commit c5e8d0c172.
* Revert "Display either hash or actual error message"
This reverts commit 0c091ab35f.
* Revert "Use ApiErrorNotice in funnels"
This reverts commit 5929de248e.
* Revert "Don't render "No data yet" when there's a NetworkError for example"
This reverts commit 70bee07632.
* Revert "Show the sinking shuttle notice whenever an API error occurs"
This reverts commit 9a62c8af2b.
* Revert "Add Hahash dependency"
This reverts commit b94207ea0a.
* Remove support hash
* Add Hahash dependency
* Don't leak internal server error details to the user
* Show the sinking shuttle notice whenever an API error occurs
* Don't render "No data yet" when there's a NetworkError for example
* Use ApiErrorNotice in funnels
* Display either hash or actual error message
The reason "internal-server-error" doesn't work well as a fallback
hash is that e.g. `NetworkError when attempting to fetch resource`
might be completely at client's fault. In such cases it's better
to display the whole thing still.
* Remove unused RocketIcon
* Display premium features tabs on the dashboard
This commit makes the funnels and props tab on the dashboard visible
even when the site owner's plan does not have access to that feature.
This is to raise awareness of those features, and if the site owner does
not want to see that tab, they can still click "Hide this report" to
hide it.
Previously, when the plan did not support a feature, the feature module
`enabled/1` function returned `false`, regardless of the
`sites.feature_enabled` toggle. This commit creates a new function
called `opted_out/1` to differentiate access from explicitly opting out
a feature.
* Remove unused data-conversions-enabled attribute
* DRY Plausible.Billing.Feature.check_availability/1 function
* Allow opting out features the user doesn't have access to
* add upgrade CTA to FeatureSetupNotice
* fix JS linting errors
* simplify notice.js
* fix behaviour when deleting funnels saved to localstorage
In case some other funnel exists, we will use that as the default
selected one. If not, a feature setup notice will be displayed again.
---------
Co-authored-by: RobertJoonas <56999674+RobertJoonas@users.noreply.github.com>
Co-authored-by: Robert Joonas <robertjoonas16@gmail.com>
This commit replaces the `mousedown` event for `click` to close a modal,
such as the detail dialog. This allows the scrollbar to be clicked
without firing an event, and right clicks too.
Closes#2872
* Inline theme script to layout
* Extract theme_script as Heex component
* Remove unused function
* Reference assigns directly
* Clean up current user
* Clean up theme javascript
* Use new theme script in focus.html layout
* Use `assigns` instead of `@conn.assigns` in `focus.html.heex` template too
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Avoid redirect in site settings
* Fix unicode in SiteController existing tests
* Fix various tests
* Add CHANGELOG
* Make sure test site is example.com
* Use Route helpers in site_controller
* Fix UTF redirect in change domain submit action
* Fix UTF site domain in reset stats action
* Update applications
* Clone community config
* Move modules to experimental dir
* Update runtime config
* Apply first set of compile-time conditionals
* Move funnel schemas to experimental
* Make funnel schema-less build compile
* Use experimental/lib for elixir code
* Move JS funnels to experimental
* Clean up conditional rendering
* Tidy up the pipeline
* Make two builds pass tests without warnings
* Reuse existing dotenvs
* Do a bunch of renames
* Clean up naming
* Run secondary CI
* Update router
* Remove RewriteFunnelDupes migration
Tests were disabled already and it was a one-off shot
* Fixup quota mixins
* Add moduledoc
* Change MIX_ENV for seconary test run
* Skip crm on small
* !fixup
* Exclude flags pipeline
* Update lib/plausible_web/controllers/stats_controller.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* 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>
* Read feature status from Billing.Feature instead of %Site{}
This commit changes data attributes passed to React. Previously the
controller read feature statuses directly from the %Site{} schema. The
Billing.Feature context is aware of the user plan and the features
available.
* Limit funnels internal API based on site owner plan
* Limit props internal API based on site owner plan
* Use site factory in QueryTest
* Limit custom property filter based on site owner plan
* Limit revenue goals queries based on site owner plan
* Add SSO link with signed JWT token
* Falls back to Nolt URL without SSO if token cannot be generated
* Add profile image (gravatar) to Nolt SSO link
* Improve navbar dropdown
* Add 'contact support' link to nav dropdown
* Add CSS rule to prevent horizontal jumps
* Dark mode styling
* Close dropdown when link is clicked
* Clarify links in dropdown
* Clarify CSS comment
* Use Alpine.data() over window
* Rename suggestions_dropdown -> combo-box
* Mix format
* Make logout link look good on dark mode
* Use proxy for gravatar
* Do not use Gravatar proxy in self-hosted
* Changelog
* Add Github Repo link to nav dropdown
* Make dialyzer happy
* Add proxy for Gravatar
* Update assets/css/app.css
Co-authored-by: hq1 <hq@mtod.org>
* Update lib/plausible_web/controllers/avatar_controller.ex
Co-authored-by: hq1 <hq@mtod.org>
* Fix alpine <> Liveview integration
---------
Co-authored-by: hq1 <hq@mtod.org>
This pull request implements limits to funnels, revenue goals and custom props based on the site owner plan. It extends the current "premium feature" notice to account for the new plans, trials and the on-going private preview. Stats API is not in the context of this pull request, but will be implemented likewise.
* Add zxcvbn dependency
* Change password length range requirement from 6-64 to 12-128
* Reimplement register form in LV
* Implement server-side check for password strength
* Add rudimentary strength meter
* Make password input with strength a separate component and improve it
* Fix existing tests to provide strong enough password
* Apply formatting
* Replace existing registration form with new one
* Hide built-in label in `.input` component when none provided
* Crop password to first 32 chars for analysis by zxcvbn
* Add tests for new form components
* Integrate hCaptcha into LV
* Fix existing AuthController tests
* Add tests for Live.RegisterForm
* Hide strength meter when password input is empty
* Randomize client IP in headers during tests to avoid hitting rate limit
* Apply auxilliary formatting fixes to AuthController
* Integrate registration from invitation into LV registration logic
* Fix existing password set and reset forms
* Make `password_length_hint` component more customizable
* Optimize `Auth.User.set_password/2`
* Remove unnecessary attribute from registration form
* Move password set and reset forms to LV
* Add tests for SetPasswordForm LV component
* Add tests for password checks in `Auth.User`
* Document code a bit
* Implement simpler approach to hCaptcha integration
* Update CHANGELOG.md
* Improve consistency of color scheme
* Introduce debounce across all text inputs in registration and password forms
* Fix email input background in register form
* Ensure only single error is rendered for empty password confirmation case
* Remove `/password` form entirely in favor of preferred password reset
* Remove unnecessary `router` option from `live_render` calls
* Make expensive assigns in LV with `assign_new` (h/t @aerosol)
* Accept passwords longer than 32 bytes uniformly as very strong
* Avoid displaying blank error side by side with weak password error
* Make register actions handle errors gracefully
* Render only a single piece of feedback to reduce noise
* Make register and password reset forms pw manager friendly (h/t @cnkk)
* Move registration forms to live routes
* Delete no longer used deadviews
* Adjust registration form in accordance to changes in #3290
* Reintroduce dogfood page path for invitation form from #3290
* Use alternative approach to submitting plausible metrics from LV form
* Rename metrics events and extend tests to account for them
* Add hint to creatable ComboBoxes without suggestions available
* Load external resources once in funnel settings
* Load external resources once in goal settings
* Make Custom Props Settings UI match Goal Settings
* Remove unnecessary goals query
This should be done only once in the live view
* Remove funnels feature flag
* fixup
* Make the modal scrollable
* By default, focus first suggestion for creatables
* Add sample props to seeds
* Load all suggestions asynchronously, unless `Mix.env == :test`
* ComboBox: Fix inconsistent suggestions
We require "Create ..." element to be only focused
when there are no suggestions available.
This causes some issues, depending on the state,
the least focusable index might be either 0 ("Create...")
or 1. This patch addresses all the quirks with focus.
* Fix ComboBox max results message
So that AlpineJS doesn't think it's a focusable
option.
* Keep the state up to date when changing props
* Update seeds with sensible prop names
* Make escape work for closing combobox suggestions
Co-authored-by: Uku Taht <Uku.taht@gmail.com>
* Revert "Make escape work for closing combobox suggestions"
This reverts commit 306866d2a1.
@ukutaht unfortunately this makes it impossible to select
an suggestion.
* Revert "Revert "Make escape work for closing combobox suggestions""
This reverts commit 4844857812.
* Make ESC great again
* Improve readability
---------
Co-authored-by: Uku Taht <Uku.taht@gmail.com>
* Update Tailwind to latest v3.3.3
* Upgrade autoprefixer and postcss
* Move tailwindcss plugins to devDependencies
* Remove unused tailwind rules
* Remove obsolete 'transform' rules
Ref: https://tailwindcss.com/docs/upgrade-guide#automatic-transforms-and-filters
* Use the current yellow, update gray to slate
* Move webpack to devdependencies
* Go more minimal with package.json changes
* Update autoprefixer version
* Update postcss version
* Adjust dark style colors
* Use proper node version is asdf config
* Render keybinding hints in the range picker
There was a regression in #3321 - some keybinding
hints stopped appearing due to exact string matching.
* Switch casing
* automatic CONVERSIONS -> PROPS navigation
In the Behaviours section, we'll navigate from Goal Conversions > Properties,
when a goal filter is applied by clicking on an entry in the Goal Conversions
list. This navigation does not happen for pageview goals or special goals (e.g.
'Outbound Link: Click', 'File Download', etc.)
The Behaviours component will remember that the navigation happened in order
to return the user to the previous view when the goal filter is removed.
* ability to store prop_keys per goal in localStorage
* pass the onclick handler to the Details view too
This makes sure that when a listItem is clicked in the Details view,
the same behaviour (such as changing the Locations tab from 'Countries'
to 'Regions') is called.
* bugfix - always escape pipes when applying goal/prop filters
* disable propkey selection when prop filter applied
* make the propkey selector take up all the width
* Update interval dropdown based on custom range selection
* Add `monthsBetweenDates` function
* Reassign interval for custom "period" based on local storage
* Generate intervals by period based on stats_start_date
* Account for "custom" and "all" period intervals dynamically
* rename Properties to Custom Properties in Site Settings
* fix docs link for custom props
* add back the external links for special goal URLs and 404 paths
* grandfathering note
* Remove `Plausible.Sites.set_allowed_event_props/2` function
This commit removes the `Plausible.Sites.set_allowed_event_props/2`
function in favor of `Plausible.Props.allow/2`.
* Allow internal prop keys in queries
This commit allows internal prop keys by default in queries. I decided
not to include internal keys in the database, because they might change
and we'd need to migrate it again.
* remove redundant 'props.' from behaviours/index.js
---------
Co-authored-by: Robert Joonas <robertjoonas16@gmail.com>
This commit removes the allowed props list from the data attribute
passed to React. The list was used for checking whether props configured
or not. This commit adds a new `hasProps` attribute, and removes the
list.
* fix conversions fetchData limit to the right number
* make Goal Conversions metric column width match Properties
* add more top-margin to Details links in ListReport
* add special handling for url prop in Conversions
* change 'Details' button to 'More' when no additional details
* fix CI
* breakdown by 'path' prop instead for 404 pages
* change the 'MORE' button back to 'DETAILS'
But keep the option of not showing the button when there are less
than 9 list entries.
* capture special props in an object instead (review suggestion)
* Add cloaked link to special goals list
---------
Co-authored-by: Vinicius Brasil <vini@hey.com>
* rename conversions.js to deprecated-conversions.js
* add a new Conversions component and switch by props FF
* add a Details view to the new Conversions component
* allow querying conversions with pagination
...and keep the current behaviour for DeprecatedConversions, always returning
page=1 and limit=100
* hide some columns on mobile
* prevent ListReport first column header overflow
* extract add_exit_rate function
* Change internal API metric names for /entry-pages & /exit-pages
* `unique_entrances` -> `visitors`,
* `total_entrances` -> `visits`,
* `unique_exits` -> `visitors`,
* `total_exits` -> `visits`,
This is just a consistency improvement - the `visitors` metric always means
one thing and there's no need to call it different for entry pages internally.
This commit does not change any noticable behavior. The UI labels are kept
the same and the column headers in the CSV export will also remain the same.
* Change internal API metric names for /conversions
* `unique_conversions` -> `visitors`,
* `total_conversions` -> `events`,
* return revenue metrics from /custom-prop-values (backend)
* be more explicit about which metric is plotted with Bar
* validate that ListReport input metrics actually exist in the API response
* display revenue metrics in the dashboard Properties section
* limit the number of columns shown on mobile
* add revenue metrics to Properties > Details
* review suggestions
* define hiddenOnMobile per metric instead of keeping the first 3
* rewrite if-else block
---------
Co-authored-by: Vini Brasil <vini@hey.com>
* extract add_exit_rate function
* Change internal API metric names for /entry-pages & /exit-pages
* `unique_entrances` -> `visitors`,
* `total_entrances` -> `visits`,
* `unique_exits` -> `visitors`,
* `total_exits` -> `visits`,
This is just a consistency improvement - the `visitors` metric always means
one thing and there's no need to call it different for entry pages internally.
This commit does not change any noticable behavior. The UI labels are kept
the same and the column headers in the CSV export will also remain the same.
* Change internal API metric names for /conversions
* `unique_conversions` -> `visitors`,
* `total_conversions` -> `events`,
* make (none) value in custom prop breakdown add +1 to pagination limit
This is needed because the (none) value is always added to the
breakdown_results **after** fetching those from ClickHouse.
* only include (none) values on the first page of results
* fix percentage metric calculation for paginated results
Instead of summing up the number of visitors from the breakdown results
to get the total, we have to make a separate query to `Stats.aggregate`.
Otherwise, the percentages for each results page will wrongly add up to 100%.
Since imported data for aggregated visitors and other properties (such as
browsers, OSs, etc) live in different tables, we have to tweak the tests to
also include the same number of visitors in the `imported_visitors` table.
* add details view for props
* changelog
* exclude imported data from total
* Add creatable option to ComboBox
This commit changes the ComboBox component to allow a `creatable`
option. This option enables users to create new options along with
choosing existing options.
* Test ComboBox class parameter
* Use display_value instead of input
* Change scroll block to nearest to prevent glitches
* add the props section in behaviors
* update listReport when keyLabel (=propKey) changes
* make column min-width configurable and increase for props
* add rendering condition to limit container height
* fix filter link
* fix tests
* disable clear for single-option combobox
* improve single-option combobox styling
* fix fetchPropKeyOptions fn update on query change
* BUGFIX: searching for prop_values in property filter modal
* change the order of funnels and props section pickers
* change props section Bar color from gray to light-red
* remove disabled options from combobox dropdown (multi & single)
* display percentage metric values without a % sign
* change metric labels in goal filter view to Visitors and Events
* fix realtime update timer
* refactor SourceList to use ListReport
* refactor SourceList into a fn comp
* change referrer-drilldown API response format and remove dead code
* use ListReport in referrer-list
* fix CI
* fix flaky test
* remove IO.inspect
* Move money cast function to Stats.Util
* Add revenue metrics to main graph API
* Plot revenue metrics on the main graph
* Return plain numbers instead of a map
* Fix Credo issues
* Fix canMetricBeGraphed function
* Revert canMetricBeGraphed function changes
* refactor ListReport
Pass a 'getFilterFor' function instead of a 'filter' object to ListReport
* Keep the statsBoxClass in one place only
* add classname prop to MoreLink
* define metric structs as ListReport inputs
* Fix a bug
If the query changes, we also want to reset the eventListener function.
Otherwise we keep calling an outdated function that fetches old data.
* fix CI
* PoC: evaluate funnel on step selection
* Adjust test to actually _select_ steps
* Throttle and test ephemeral funnel evaluation
* Format compact percentages server-side
At this point it's pointless to duplicate this;
all the primitives exist in the API in case the client
wants a different representation.
* Dynamically set :domain for the live socket
Ref: https://github.com/phoenixframework/phoenix_live_view/pull/2715
* Make runtime config raise before the user ends up in a reconnect loop
* hall of shame: remove console.info remnant
* Check origin on live websocket
* Get rid of single pipe
* Add Funnel react component
assets/js/dashboard/stats/behaviours/funnel.js - restored from:
98a76cbd Remove console.info calls
d94db99d Convert Funnel class component into a functional one
028036ad Review comments
3067a940 Stop doing maths in react
73407cc3 Fix error handling when local storage gets corrupted
e8c6fc52 Format numbers on funnel labels
c815709f Reorganize component responsibility
7a88fe44 Outline basic error handling
94caed7c Chart styling updates
4514608a Add percentages to funnel
d622c32d Add funnel picker
Co-authored-by: Uku Taht <uku.taht@gmail.com>
* Pass funnels list to react via data-funnels
* Implement Funnels react API
lib/plausible_web/controllers/api/stats_controller.ex - restored from:
f36ad234 Adjust to Plausible.Stats interface
9b532273 Test funnel stats controller
028036ad Review comments
bea3725f Remove IO.inspect
7a88fe44 Outline basic error handling
c8ae3eaf Move Funnels to StatsController and use base query
667cf222 Put private functions at the bottom
* Tweak funnel presentation
* Handle errors at the top
* Do not register DataLabels plugin globally
or else all the existing charts are affected
* Calculate drop-off percentage evaluating funnels
* Tweak dark mode + implement nicer tooltips
* Make currently selected funnel bold in the picker
* Count user_ids not session_ids when evaluating funnels
So if a visitor goes:
1. Start session
2. Complete funnel step 1
3. Inactive for 30 minutes
4. Complete funnel step 2
We would not be able to track this funnel completion because of the session timeout.
We like to o measure this as funnel completion even though the session expired in the middle.
cc @ukutaht
* Add extra properties to the funnels API
cc @ukutaht
* Improve tooltips so that step to data is rendered
* Change tooltip number formatting
* Remove debugging remnants
* Quick & dirty mobile view
* Fix mobile view: tweak dark mode & funnel switching
* Ignore DOMException: the operation was aborted
Otherwise this sometimes flashes the space shuttle
screen when navigating quickly via a keyboard.
* Format percentages on the main chart
* Close missing tag 🙈
* Revert "Close missing tag 🙈"
This reverts commit 9c2f970e22fd7e2980503242b414f42ce8bce1d2.
* Use jsx to render funnel tooltip
To get markup validated via lsp mostly...
* Fixup: s/class/className
* Fix className interpolation
* Add a ruler to the tooltip
* Tweak funnel chart style
* Fix font distortion issue on chart/canvas labels
* s/class/className
* Put "Set up funnels" link behind a feature flag
* Refactor internal selection storage
Getting ready for live funnel evaluation
* Don't try to connect LV socket if there's no CRSF token set up
This is perfectly okay for some of the templates/layouts.
* Fix up funnel creation typespecs
Unfortunately we can't define a type with literal string keys,
hence this must suffice.
* Use uniq over count/distinct
* Revert JSX in tooltips
Ref: https://github.com/plausible/analytics/pull/3066#discussion_r1241891155
* Remove the extra query for counting all visitors
cc @ukutaht
* Add premium notice
---------
Co-authored-by: Uku Taht <uku.taht@gmail.com>
This commit adds revenue data to top stats. Average and total are displayed when filtering by a revenue goal (or many if they have the same currency set).
* Update formatter config
* Install LiveView JS integration & hooks
* Temporarily update endpoint/session config
* Optionally allow preloading funnels for goals
* Site controller
* Implement funnel settings
lib/plausible_web/live/funnel_settings/combo_box.ex - restored from:
054de6e2 Fix the tab/blur bug again
20da4c89 Rename InputPicker to ComboBox
lib/plausible_web/live/funnel_settings/form.ex - restored from:
9bedda3b Remove potential FIXME
20da4c89 Rename InputPicker to ComboBox
028036ad Review comments
aea4ebc4 Access Funnel min/max steps via the __using__/1 macro
0dde27fd Remove inspect call
eed588a7 Start testing the funnel editor
0e95228b Extract funnel settings test module
7b16ace5 Leverage aplinejs to deal with the tyranny
8dc6a3e7 wip
cf228630 wip
30a43fd1 wip
89f10ecb wip
950a18d9 Dirty funnel save
298a6a53 wip
7690d50f wip
639c6238 fixup
aa59adeb wip
ff75c00b wip
lib/plausible_web/live/funnel_settings/list.ex - restored from:
4eae122c Fix data-confirm attr interpolation
51f0397d Implement deleting funnels
1f6fe25d Add number of steps to funnels list
298a6a53 wip
ff75c00b wip
test/plausible_web/live/funnel_settings/funnel_settings/combo_box_test.exs - restored from:
20da4c89 Rename InputPicker to ComboBox
test/plausible_web/live/funnel_settings/funnel_settings_test.exs - restored from:
34822ff4 Bootstrap InputPicker tests
lib/plausible_web/live/funnel_settings.ex - restored from:
028036ad Review comments
acd9c4f2 Prepare ephemeral funnel definitions so that users can test funnels
51f0397d Implement deleting funnels
0e95228b Extract funnel settings test module
8dc6a3e7 wip
89f10ecb wip
950a18d9 Dirty funnel save
298a6a53 wip
aa59adeb wip
ff75c00b wip
test/plausible_web/controllers/error_report_controller_test.exs - restored from:
34822ff4 Bootstrap InputPicker tests
test/support/html.ex - restored from:
0a53979d Improve InputPicker tests - include AlpineJS assertions
34822ff4 Bootstrap InputPicker tests
lib/plausible_web/views/layout_view.ex - restored from:
b490403b !ifxup
lib/plausible_web/templates/site/settings_funnels.html.eex - restored from:
51f0397d Implement deleting funnels
ea1315f3 Test funnels list in settings
7b16ace5 Leverage aplinejs to deal with the tyranny
ff75c00b wip
4da25c35 Fixup
lib/plausible_web/templates/layout/app.html.eex - restored from:
ff75c00b wip
* Add funnel settings route
* Warn about funnels deletion when deleting goals
lib/plausible_web/templates/site/settings_goals.html.eex - restored from:
fdd9bcd0 Fixup
f1e6364d Merge remote-tracking branch 'origin/master' into funnels-rebase
9d0b7c6d Fix markup error
4a4ddbdc Optionally preload funnels for goals and stub funnel-goal deletion
ebdc4333 Extend the prompt in case of funnel-goal deletion
639c6238 fixup
aa59adeb wip
* Split new JS LiveView additions
* Put funnels behind a feature flag
* Integrate dashboard feature toggle
* Update signing salt for live view
* Update moduledocs
* Update live reloader config
* Use Phoenix.HTML.Safe for goal names
* Workaround to get flashes working in embedded liveview
* Keep feature toggles idempotent, rename property to setting
We'll still retain the ability to flip bools on a lower level.
* Update moduledocs
* Make live flash disappear after 5s
* Tailwind: purge .heex files too
* Update docs link
* Add live components to tailwind purge config
* Update another flaky test
Ref f0bdf872
cc @vinibrsl
* Fix combobox input length w/ WebKit
* Intoduce generic notice component
* Revert "Fix combobox input length w/ WebKit"
This reverts commit 3c653a6d85d5000167631e10ef45a93c13b41ed1.
* Fix combobox input length on webkit
* Make whole combobox item clickable, not only text
* Fix glitch moving Save button on activation
* Tweak dark mode
* Show funnel form without waiting for funnel name input
* Tweak dark mode
* Include static Phoenix components in tailwind purge
* Tune funnels form into a liveview of its own
This is so that ComboBoxes can publish their selections
and unavailable choices can be propagated to other siblings.
* Push less data over websocket
* Undo Lsp/formatter race condition
* Fixup typespecs
* Bust CI cache
* copy relevant files from b2ace16540
* make it work and set site.funnels to empty list
* make Behaviours a functional component
* add UI for a setup hint and always display conversions by default
* cherry-pick migration commit
* update site schema with new fields
* backend: implement disable-feature action
* switch between tabs in the behaviors section
Introduces template components to build props and funnels on. Both
only show a setup notice atm, and both are behind feature flags.
* extend API for disabling props and funnels
* render feature setup note directly from the Behaviours component
* fix UI behavior when features are hidden
* update setup notices
* add conversions feature switch to Site Settings > Goals
* mix format
* remove IO.inspect
* change setup notice - use buttons + popup confirmation
* optimize for light mode
* restrict access to setup notices
* some styling improvements
* allow super-admins to enable/disable features
* only show conversions (last 30min) in realtime mode
* use shorter display names for tabs
* optimize for mobile screens
* note about sending custom events
* changelog update + fix CI
* change HTTP verb for the disable-feature action
* change UI label for show/hide goals
This commit brings back percentage arrows to default view. These were
removed by the recent comparisons work, and we've had reports of people
missing it. As we haven't noticed any difference in performance, I've
decided to revert that change.
This commit updates the imported 'G' icon, so that it appears only when
querying or comparing a range with imported data. By hiding the icon in
all other cases, users will see it only when they can actually click on
it.
Previously, the comparison line could sometimes be displayed with a
different scale than the main plot due to the maxTicksLimit option not
being fixed and changing based on the data. This commit fixes the issue
by setting the maxTicksLimit value to 8 in the graph settings instead of
for each individual axis.
Additionally, a callback that attempted to dynamically change the Y axis
ticks while resizing has been removed. As the graph has a fixed height,
dynamically resizing the Y axis no longer makes sense.
* Add PropFilterModal (only UI)
* small variable refactor
* allow selecting prop value filter type
* allow selecting only one prop_key
* allow selecting many prop_values only when prop_key selected
* handle submitting filter
* get applied filters from query + remove option
* change prop filter label format
* support member and not_member filter types for pageview props
* show (none) value in filter suggestions
* refactor zip_results/4 and remove unused code
* fix displaying (none) values in goals section prop breakdown
* remove unnecessary functionality
* fix bug: returning prop names for goal :member filter
* fix bug: submitting regular filter modal with Enter key
* bugfix: disallow opening prop filter modal when feature flag disabled
* mix format
* break selected combobox values into multiple lines
* fix useEffect behavior for focusing on prop_key field
* support submitting prop filter with Enter key
* refactor getFormState in PropFilterModal
* separate fetchPropKey and fetchPropValue functions
* Allow querying props for pageview goals
* Make the internal props API only return a list of props (not map)
* Separate function for fetching all props in Stats API goal breakdown (this returns a map as before)
* ditch state for keeping search bar visible
* group by event_name in db query
This pull request removes the comparisons feature flag, making it visible to all users. It also removes percentages from top stats in default view, leaving those for the comparison view only.
* Fix date picker shifting day bug
This commit fixes a bug where picking a specific date in custom range
takes you to the stats of the day before.
This was caused because Flatpickr returns a Date instance, and we were
trying to parse this Date instance into day.js using the `utc` function,
assuming it was a ISO-8601 string.
This commit fixes it by casting Date into dayjs using the `dayjs`
function instead of `utc`.
* Fix invalid date Flatpickr bug
This commit fixes a bug where the Flatpickr was not setting the minDate
correctly based on statsBegin. This was failing because parseUTCDate is
now returning a day.js instance, and Flatpickr cannot handle that type.
* Hide dayjs usage in util/date
* Pass comparison_query as argument to top stats functions
* Add comparison values and dates to top stats API
* Display comparison dates and values in top stats
* Rename function to renderPercentageComparison
* Create component to do conditional rendering
* DRY date range formatting function
---------
Co-authored-by: Uku Taht <uku.taht@gmail.com>
* Use dayjs with UTC plugin for date-formatter
* Remove 'toHuman' function
* Use dayjs dates in Datepicker component
* Use util/date.js functions in date formatter
* Remove `fromJSDate`
* Use formatISO instead of raw dayjs formatter
* Escape pipes in goal names
* Apply suggestions from code review
Use ~S sigil for better readability
Co-authored-by: Vini Brasil <vini@hey.com>
---------
Co-authored-by: Vini Brasil <vini@hey.com>
* Fix open state in combobox
* Improve filter suggestions when using the `contains` filter
* Support contains filter type for utm filter group
* Remove console.log
This commit improves the datepicker state management. Due to a bug, we
needed to use setTimeout to open Flatpickr. This change replaces the
setTimeout workaround by using a proper React state.
* Wrap Plausible.Stats.Filters with unit tests
* Parse `member` filter type
* Support for `member` filter in `aggregate_time_on_page`
* Support `not_member` filter type
* Support `matches_member` and `not_matches_member` filters
* Extract util module for React filters
* Implement Combobox from scratch with no libs
* Support multple filter clauses in combobox
* Don't use browser / os in version label
* Show highlighted option in combobox
* WIP
* Fix location filters outside filter modal
* Align open/close behaviour with react-select
* Styling updates for combobox
* Add support for wildcards in Combobox
* Implement keybindings for combobox
* Allow free choice inputs in combobox
* Rename 'Save filter' -> Apply filter
* Remove TODO comment
* Clean up some rebase mistakes
* Rename `allowWildcard` -> `freeChoice`
* Dark mode fixes
* Remove hint from filter modal
* Escape pipe character in filter modal
* Do not allow selecting duplicate options in combobox
* Escape brackets in `page_regex/1`
* Fix disabled style in dark mode
* Add regex fallback for safari
* Show no matches found when visibleOptions is empty
* Disable enter key when no visible options
* Do not submit empty form fields
* Remove unnecessary setOpen(true)
This pull request enhances the navigation for comparisons by implementing the following changes:
* Hides the comparison input behind the period picker, making the top bar less busy.
* Adds a key binding for the comparison input (assigned to x) alongside arrow navigation.
* Persists the selected comparison mode in Local Storage by domain, resulting in its persistence between refreshes.
This pull request adds support for multiple comparison modes, changes the comparison checkbox to a combobox, and implements the year over year comparison mode. The feature is still behind a feature flag.
Co-authored-by: Uku Taht <uku.taht@gmail.com>
* globally rename 'pages_per_visit' to 'views_per_visit'
* change the order of top stats
* rename 'Visits' to 'Total visits' in the UI
* add views_per_visit to UI
* put the new metric under a feature flag
* add new metric to CSV export under feature flag
* mix format
* use only one feature flag
* Use user-agent instead of screen_width to get device type
Co-authored-by: eriknakata <erik.nakata5@gmail.com>
* Fix credo
* Log on unhandled UAInspector device type
* Make 'browser' the default tab in devices report
* Remove device tooltip
* Remove screen_width from ingestion completely
* Remove browserstack harness, run playwright directly
* Select meta key based on OS platform
* Run CI tests in parallel
* Improve device match readability
* Add changelog
---------
Co-authored-by: eriknakata <erik.nakata5@gmail.com>
* Add visits metric and make it graphable
* include visits metric in csv export (visitors.csv)
* put visits under a feature flag (CSV export)
* feature flag for displaying visits on the dashboard
* fix formatting
* add visits metric to top stats (fix)
* fix imported_test to expect visits metric included
* fix formatting
* Revert "Fix graph element z-index (#2698)"
This reverts commit 35ab26308d.
* Revert "Fix interval selector z-index (#2696)"
This reverts commit c307057386.
* Set graph z-index to zero
* Add as={Fragment} to Transition component
Previously, the graph element was overlapping with other UI elements
such as the period input. This commit fixes this issue by setting the
z-index of the graph element to 0, which moves it behind other elements
in the stacking order.
* Refactor graph dataset building function
This commit refactors the graph dataset building functions into three
separate functions, one for each plot: main plot, comparison plot, and
dashed plot.
* Merge default graph dataset options
This commit moves default options from graph building functions to the
main function.
* Remove truncateToPresentIndex function
* Include dashed part when comparing periods
This commit fixes a bug where some period + interval combinations were
not working properly with comparisons. This is because `present_index`
is not available in every period, e.g. Last Month.
* Use HeadlessUI for search select box
* Remove downshift from package.json
* More consistent API for Combobox component
* Combine toFilterType and valueWithoutPrefix into a single function
* Rename MyCombobox -> PlausibleCombobox
* Update webpack-cli
* Disable cache for build
* Revert "Disable cache for build"
This reverts commit aa130541f8.
* Disable cache for build
* Update webpack dependencies
* Remove glob from webpack config
* Webpack is required by package.json
* Require autoprefixer in postcss config
* Revert build changes
* Fix styling for dark mode
* Position the graph component relatively
* lose graph container height flicker (resized canvas)
* rename variable
* prevent flicker in the loading process
* remove unused import
* disable cursor-pointer class for minute interval
* change var names and loading state conditions
* refactor showLoader condition
* fix UI bug with interval change
set `graphData` to `null` so that the component would fade out when
loader becomes visible. Before, the spinner was just displayed on top of
the graph.
* Add year to X axis of multi-year graph
* Remove hardcoded condition for rendering year string, render if multiple years present in graph view
* Apply new argument contract to dateFormatter usage in graph-util.js
* Better defensive runtime type guard when deriving hasMultipleYears
* Remove console log
* Remove unrelated JSDoc change
---------
Co-authored-by: Vini Brasil <vini@hey.com>
This commit adds support for comparing the actual showed period on the main graph with the previous one. This is a first pass and it's hidden under a feature flag because it's not feature complete yet as we want to support other comparison modes.
* Make Device section components aware of (not set)
So that no extra sub-filters are possible when the unset
top item is selected.
* Support '(not set)' in breakdown/filters
* Update expectations for export tests
* Add extra tests for returning/filtering by '(not set)'
* Add changelog entry
* Remove ListReport conditional render
* Prevent redundant sub-filters
* Fix filter text rendering
---------
Co-authored-by: Uku Taht <uku.taht@gmail.com>
* Remove the ability to collpase the top graph
This commit removes the ability to collapse the top graph. The graph
collapsed whenever `metric` was falsy. I removed all related code to
that. Metric now defaults to visitors.
We want to add new items to top stats, and this commit will make it
easier to change it. Also, there's currently a bug where top stats is
randomly collapsing, which should be fixed by this commit.
* Refactor graph and top stats loading state
The graph loading state shows and hides the graph conditionally
depending on whether the data is loaded, loading or refreshing.
The current code is a bit difficult to read because its big
conditionals. This commit refactors the loading state making it easier
to read.
This commit also fixes a bug where the graph wasn't fading out when
changing metrics.
* Move Endpoint errors setup to common config
* Implement naive Sentry link resolver
* Implement error report e-mail
* Delete static sentry script
* Implement user feedback form on server errors
* Re-arrange pipe
* Use Sentry.Config.dsn() where applicable
* Fix typo
* Use Map.replace/3
* extract maybeUpdateMetric function
* reset graph metric after fetching top stats
* fix bug
Also make sure we do not allow 'metric' to become undefined anymore
* keep graph hidden when empty metric saved
* reset metric in setState callback
* pass function not call
* extract blinkingDot function
* position pulsating-circle with tailwind instead
* remove unused function
* extract renderStatName function
* display seconds since last realtime update
Adds a 'Last updated X seconds ago' label to the Current Visitors tooltip.
* small refactor: avoid duplication of this.props and this.state
* show the 'last updated ...' tooltip in historical
* changelog update
* use className utility function
* add a new realtime-update-timer module
* hook to the new 'tick' event in ListReport for auto-updates
This commit fixes the bug where all reports using the `ListReport` component did not
auto-update in realtime mode. Those reports are:
- Pages (Top / Entry / Exit)
- Locations (Countries / Regions / Cities)
- Devices (Screen Sizes / Browsers + versions / OS-s + versions)
* fetch data for ListReports only when scrolled into view
* refactor fetching data in ListReport
* refer to one source of truth for utm tags
* make the 'All' tab in Sources auto-update
* make all UTM tabs in Sources auto-update
* fetch UTM data only when scrolled into view
* auto-update Referrers with the new timer
* auto-update google search terms
* auto-update Conversions
* make countries map auto-update
* auto-update visitor-graph and top stats with new timer
* use new tick event for current visitors (in Historical)
* remove the old timer class
* update changelog
* Visual improvements to automatic realtime updates (#2532)
* minor consistency fix for text color in dark mode
* use FlipMove in goal conversions report
* use FlipMove in ListReports
* set main graph and top stats loading state correctly
* refactor isIntervalValid function
* enforce intervals are valid when set and stored
* remove duplicate data fetching on interval change
Fetching new data is handled by the `fetchGraphData` callback in `updateInterval`
* refactor updateMetric function
* make it clearer why 'metric' can be a faulty value
* extract 'query' and 'site' variables from 'this.props'
* reset interval state only when period is changed
The 'maybeRollbackInterval' function was also used to fetch data. This commit replaces
all those function calls with 'fetchGraphData' which better describes the actual behavior.
We should only worry about rolling back the interval if 'query.period' has changed.
This commit also stops the graph from flickering when it is updated in realtime.
* update names of two variables
* remove unnecessary negation
* make collapsed graph state more explicit
* consider stored invalid intervals when graph mounts
* fix not showing loading spinner regression
* remove interval state from VisitorGraph (#2540)
* Realtime prop breakdown (#2535)
* disable load more in realtime mode
* extract doFetch function
* separate fetchPropBreakdown and fetchNextPage functions
* subscribe for auto-updates in realtime
* improve readability with function name changes
* Remove show_noref behaviour
Removes query param show_noref which was used from React to control
whether to show Direct / None traffic or not. The show_noref behaviour
was untested previously.
Closes#2523
* Add changelog entry
* Fix tests
* Removed files I did not mean to check in :)