* WIP
* Fix issue with more than one page cached
* Make sure we don't access properties of undefined objects
* slight cleanup
* reset limit to 100
* add back the bottom loading spinner when fetching next page
* disable refetchOnWindowFocus in the global queryClient
* render bottom loading spinner only when fetching next page
* create a wrapper for react-query
* fix exhaustive deps warnings in modals
* always pass the full api path to BreakdownModal
* improve function doc
---------
Co-authored-by: Robert Joonas <robertjoonas16@gmail.com>
Co-authored-by: RobertJoonas <56999674+RobertJoonas@users.noreply.github.com>
* Add listing sites, goals and custom props to Sites API
* Rename exmaple props in tests
* Rename `allowed_custom_props` -> `custom_properties`
* Expose goal name in GET endpoints for goals in Sites API
* Bump default pagination limit to 100 and max to 1000
* Introduce Goal.name/display_name and use the first one for name in API
* Extend goal list response but hide currency
* Settle on `display_name` instead of `name`
* Allow viewer members to get site details and list site goals
* Don't include currency in goal's display name
* Update tailwind config
Turns out `extra` wasn't scanned properly with
previous wildcards. I don't care any more, it's not slow.
* Add interface for updating funnels
* Extend ComboBox with the ability to preselect an initial value
* Implement editing funnels UI
* Update CHANGELOG
* s/add_funnel/setup_funnel
* modal width 2/5 => 2/3
* Let's not make the list disappear on modal pop-up
* Fix the damn modal width again
* Watch extra dir
* Format
* Remove commented code
The test is implemented elsewhere
* Track funnel modified to drop default selection
* Fix screen size adoption and format large numbers
* Preserve currency so that string casting includes it
* Format
* Fix ComboBox attribute for preselected option
* Replace useDebouncedEffect with useDebounce
This commit refactors the debouncing mechanism in a more extendable way.
Using debounce as a hook that returns a callback (rather than an effect)
makes it reusable for Combobox. This way the useDebounce hook does not
need to worry about whether the function should be called on the first
render or not.
This commit also gets rid of redundant doubled search state.
* rename input to search in Combobox
* Fix debounce in Combobox
* remove debounce-promise
* Fix React CI warnings in PlausibleCombobox
* Silence NPM CI in custom-hooks.js
* cancel scheduled API calls in useDebounce hook when unmounted
* Implement basic HelpScout integration
* Set 127.0.0.1 as a default customer IP in `Plans.with_prices/2`
* Use `is_nil/1` instead of `... == nil` (h/t @aerosol)
* Use `Path.join/1,2` to build API URLs a bit more safely (h/t @aerosol)
* Check for locked sites entirely within query logic
* Move conditional start of HelpScout vault to compile-time
* Include customer_id in error sent to Sentry
* Use `Plug.Crypto.secure_compare/2` for constant-time signature comparison
* Refactor token request function
* Use `Path.join/1` in one more spot
* Use route helper to build CRM URL
- `:verification` flag is no longer needed,
however we'll keep the old "awaiting first pageview" flow
for Community Edition where verification is not available
by default
- `:traffic_drop_notifications` have been tested and should
be enabled for everyone
* Expose current visitors 12h aggregate
* Remove unused site association
* Distinct drop/spike notification factories
* Rename modules accordingly + implement drop handling
* Rename periodic oban service
* Implement drop email
* Rest of the owl
* Update changelog
* Update moduledoc
* Update moduledoc
* Min threshold to 1
* Threshold 1
* Remove merge artifact
* Put panel behind a feature flag
* Format
Some users are reporting wrong results for stats querying from events table
but with session filters.
This seems to be caused by sampling: Namely both tables end up sampled and the
incorrect sample rate seems to get used.
This is sadly impossible to test for in our test suite, but reveals itself in
production with the following query:
```sql
SELECT
toUInt64 (round(uniq (se0.user_id) * any(_sample_factor))) AS visitors
FROM
events_v2 AS se0 SAMPLE 20000000
INNER JOIN (
SELECT
sss0.session_id AS session_id,
any(_sample_factor) AS _sample_factor
FROM
sessions_v2 AS sss0 SAMPLE 20000000
WHERE
(sss0.site_id = _CAST (8195000, 'Int64'))
AND (sss0.timestamp >= _CAST (1720497600, 'DateTime'))
AND (sss0.start < _CAST (1720584000, 'DateTime'))
AND (sss0.entry_page IN ('/'))
AND (sss0.sign = 1)
GROUP BY
sss0.session_id
) AS ss1 ON se0.session_id = ss1.session_id
WHERE
(se0.site_id = _CAST (8195000, 'Int64'))
AND (se0.timestamp >= _CAST (1720497600, 'DateTime'))
AND (se0.timestamp < _CAST (1720584000, 'DateTime'))
```
By removing the inner query SAMPLE clause the result changes >50%
Related old PR: https://github.com/plausible/analytics/pull/2962
This will likely require more work in the future so looking forward to that -
after my vacation.
* Refactor Expression.dimension to accept q
* Handle quarter- and half-hour timezones
Previously APIv2 output didn't start at a full hour for these time zones
and main graph was blank
The core reasoning is that ClickHouse `timeSlots` is not time-zone
aware and works off of unix epoch - meaning that in time zones which
have an offset of 5:45 the "hours" reported would start at minute :45.
The fix is kind of silly - we now divide each hour into 4 and handle
things that way.
Related basecamp issue: https://3.basecamp.com/5308029/buckets/36789884/card_tables/cards/7590936581
* Fix test typo
Some comparisons return __blank__ values. After recent time series fix,
this blew up when trying to parse __blank__ as a date.
This fixes the issue and adds a test for a period with __blank__ values
Co-authored-by: RobertJoonas <56999674+RobertJoonas@users.noreply.github.com>
Previously, revenue metrics were reported as 0.0$ when imports were included with
APIv2. This is because the metrics were not properly included/forwarded by the
imports query.
Not sure how long this bug has persisted, but eh.
* fix(suggestions): Properly provide suggestions
Previously, if a filter was applied then filter modal suggestions would
_always_ apply the previous suggestion. Now when say applying a `page`
filter suggestions we remove the previous `page` filter.
* Improve readability
* Fix filter ["contains", "visit:country", ["E"]]
This blew up since FixedString columns dont natively support matching functions for some reason
* Dont blow up for 3-letter country codes, instead fail validation
* Allow sending numbers for visit:city along with strings
This simplifies querying as we pass the list of cities as numbers to clients
* use &is_integer/1
* Remove redundancy
* Create a new BreakdownModal component and use it for Entry Pages
* Add search functionality into the new component
* Adjust FilterLink component and use it in BreakdownModal
* pass addSearchFilter fn through props
* pass fn props as useCallback
* add a function doc to BreakdownModal
* refactor: create a Metric class
* Fixup: use Metric class for defining BreakdownModal metrics
* keep revenueAvailable state in the Dashboard component
* move query context into a higher-order component
* fix react key error in BreakdownModal
* use BreakdownModal in PropsModal
* adjust EntryPagesModal to use query context
* fix variable name typo
* fixup: BreakdownModal function doc
* use BreakdownModal in SourcesModal
* use Breakdown modal in ReferrerDrilldownModal
* use BreakdownModal in PagesModal
* use BreakdownModal in ExitPagesModal
* replace ModalTable with LocationsModal and use BreakdownModal in it
* use BreakdownModal in Conversions
* make sure next pages are loaded with 'detailed: true'
* replace loading spinner logic in BreakdownModal
* fix two flaky tests
* unfocus search input element on Escape keyup event
* ignore Escape keyup handling when search disabled
* Review suggestion: remove redundant state
* do not fetch data on every search input change
* use longer variable names
* do not define renderIcon callbacks conditionally
* deconstruct props in function header of BreakdownModal
* refactor searchEnabled being true by default
* Remove a dead method
* Move select_event/session_metrics to within QueryBuilder
* Make a method private
* Move page_regex util around
* Move utc_boundaries helper around
* Fixups for utc_boundaries
* Add legacy notices
* Move Stats.query method around
* include_sentry_replay_info consistently
* Move filters out of select_group_fields
* Collapse conditions under select_group_fields
* Shorten some imported methods
* Use dimension over dim in group_by
* Separate SQL query building from imported.ex
* props.ex -> legacy_dimensions.ex
* Move some query building out of Query.ex
* Remove unneeded method
* put_filter -> add_filter
* Remove some query setters
* Moduledoc
* Split out validations and import tests from query_test
* Move tests around
* Split event:goal tests from query_test
* Remove redundant filters
* Remove dead code
* Split special metrics tests from query_test
* Legacy module
* Move fragments module under Plausible.Stats.SQL
* Introduce select_merge_as macro
This simplifies some select_merge calls
* Simplify select_join_fields
* Remove a needless dynamic
* wrap_select_columns macro
* Move metrics from base.ex to expression.ex
* Move WhereBuilder under Plausible.Stats.SQL
* Moduledoc
* Improved macros
* Wrap more code
* select_merge_as more
* Move defp to the end
* include.time_labels parsing
* include.time_labels in result
Note that the previous implementation of the labels from TimeSeries.ex was broken
* Apply consistent function in imports and timeseries.ex
* Remove boilerplate
* WIP: Limited support for timeseries-with-querybuilder
* time:week dimension
* cleanup: property -> dimension
* Make querying with time series work
* Refactor: Move special metrics (percentage, conversion rate) to own module
* Explicitly format datetimes
* Consistent include_imported in special metrics
* Solve week-related crash
* conversion_rate hacking
* Keep include_imported consistent after splitting the query
* Simplify do_decide_tables
* Handle time dimensions in imports cleaner
* Allow time dimensions in custom property queries
* time:week handling continued
* cast_revenue_metrics_to_money
* fix `full_intervals` support
* Handle minute/realtime graphs
* experimental_session_count? with timeseries
This becomes required as we try to include visits from sessions by default
* Support hourly data in imports
* Update bounce_rate in more csv tests
* Update some time-series query tests
* Fix for meta.warning being included incorrectly
* Simplify imported.ex
* experimental_session_count flag removal
* moduledoc
* Split interval and time modules