* Use goals from postgres to build goal filter
* Remove unnecessary goal preloading
* Add contains filter for goals
* Make sure the correct imported tables are used when goals are in filters
* Remove 'contains' filter type for now
* Remove TODO comment
* Fix QueryParser test
* move goals.ex into a goals subfolder
* extract goal filtering logic into a separate module
* remove duplication from Imported.Base
* Extract `get_filter_goals` function
* Credo suggestions
* Credo ignore nesting
* apply suggestion - remove Sql.Util
* apply suggestion - pass imported? via opts
* remove duplicate function
* Uncomment tests
* Fix 500 error with goal suggestions
---------
Co-authored-by: Robert Joonas <robertjoonas16@gmail.com>
* track browser_language, theme, and logged_in for 'Filter Menu: Open'
* track props for 'Signup' and 'Signup via invitation'
* do not track theme as 'system' for non-logged-in users
* fix tests
* Install @tanstack/react-router
* Fix with imported switch
* Refactor redirect to new search parser
* Deregister timeout in ComparisonInput
* Comment uses of window.location
* Fix with imported switch appearing in realtime dashboard
* Handle not found routes more gracefully
* Extend the GSC API with search functionality
* Fix typo in error tuple atom
* log GSC errors
* rename confusing variable name
* Fix the API response format and error handling
* Read results under the `results` key to be consistent with other
endpoints
* Return errors with a non-200 status code, and with an error payload
that will be well constructed into ApiError
* rebuild Google Keywords modal with useAPIClient
* Add pagination support in Search Terms API
* delete unused fixture file
* rename fixture files
* fix tests
* 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>
* 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
* 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
* 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
* 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
* Make goals accept wildcards in :is queries
* Add support for contains/does_not_contains in the backend
* Support all operations for event custom properties
* Support does_not_contain on the frontend
* Changelog entry
* Render filter operations nicely for does not contain
Found 3 extra pixels for operation dropdown
* Remove multiple_filters feature flag
* Autoselect propkey on opening properties breakdown
* reset propkey when query changes
* ignore custom prop filter when selecting a prop key
* throttle api requests
* Force loading state on combobox when loading propkey
* Remove artificial throttling of API requests
* Disable combobox when no prop keys are found
* drop prop_key and set loading true when query changes
* Update changelog
---------
Co-authored-by: Robert Joonas <robertjoonas16@gmail.com>
Co-authored-by: RobertJoonas <56999674+RobertJoonas@users.noreply.github.com>
* Add popular browser icons
* Adjust fallback icon color for dark mode
* Add changelog
* Add MIUI browser logo
* Fix Edge and MacOS in seeds
* Add smaller browser logos
* Revert "Revert "Multiple filters on the frontend (#4174)" (#4218)"
This reverts commit 2f7dcae991.
* Make city links work again
By enforcing everything sent to the BE is stringified. We do this at serialization-time to ensure old dashboard links still work
* Add new logic for query parsing
Note this is not yet final, but this scaffolding will soon be used
* Send filters to BE in new encoding, flag add more button
* query.property -> query.dimensions
* Reduce number of operations for filtering
This helps ensure we can be consistent/simple with apiv2
* Update search console filter mapping
* Update filters sent from frontend
* Update new filter parsing
* Remove redundant clause
* Make filtering by event:goal work
* Handle * as old backend did - prefix/suffix by **, if not using wildcards already
* Update imports logic
* Credo warning
* Spacing for add row button in filter modals
* query fix
* LegacyDashboardFilterParser
* only single hostname filter allowed
---------
Co-authored-by: Uku Taht <uku.taht@gmail.com>
* Revert "revert filters.js from 14cf650 (#4208)"
This reverts commit 4edeed33ca.
* fix bug with wrong var name
* Do not cancel api requests on the first dashboard render
* Remove dead code (ComparisonContext)
The state of ComparisonContext is never read. We are storing all the
necessary state either in localStorage or in the `query` object.
* turn Filters into a fn comp
* turn Dashboard and CurrentVisitors into fn components
* turn Realtime into a fn comp
* Turn QueryLink into a fn comp
Also fix the "staticContext" console error when opening the period picker.
We don't need to pass all props into the Link component.
* extract a WRAPSTATE object
* prioritize other skip_imported_reasons over not requested
* return with_imported_switch info from top stats
* fix the with-imported-switch component
* Refactor ImportedQueryUnsupportedWarning
* do not render warning bubble when imported data not requested
* stop displaying warning bubble before the API response is received
* fix tab switch pills jumping due to bubble height
* drop loading condition of ImportedQueryUnsupportedWarning for Funnels
* add explicit check for realtime when rendering the bubble
* remove unused JS imports
* rename snake_case to camelCase
* Fix parsing = in jsonurl
This works around a bug in the jsonurl library where the literal causes a syntaxerror.
The urlencoded = however is handled without errors
* Changelog
* move imported.ex to imported subfolder
* move constructing base imported query into a separate module
* Implement imported table deciding and filtering
+ tests for pages, entry_pages, exit_pages and common filter types
* add top stats test with country filter
* add timeseries test
* Drop bounce_rate and time_on_page from imported & page-filtered Top Stats
* rename field returned by top stats
* turn pages into a fn comp
* Move dashboard API results under a results key
...and also return the skip_imported_reason to the frontend to be used
for displaying warnings.
* extend ListReport component with an optional afterFetchData prop
* turn Devices into a fn comp
* add not_requested as a skip_imported_reason
* display warning icons in the dashboard
* Implement filtering suggestions and translate filter fields for imported
* WIP
* Improve and cover filtering suggestions with tests
* Rename imported suggestions query helpers
* fix screen size breakdown with screen size filter
* support filtering by the same suggestion property
* support location filters when fetching location suggestions
* support filtering by multiple props from the same table
* Implement filtering by goals
* Make views per visit metric work for import entry and exit pages
* Get rid of circular dependencies between Stats.Imported and Stats.Imported.Base
* Clean up Query struct manipulation in Breakdown
* Rename helper function for clarity
* Automatically refresh query struct state after modifications
* Shutup credo
* display imported warning bubble in prop breakdown section
* Render warning bubble for funnels whenever imported data is in the view
* Transform any operator on respective goal filters
* Fix percentage and conversion_rate calculation in presence of custom props
* add tests for for combining page and pageview goal filters
* add skip_refresh option to query tweaking functions
* add imported CR support for timeseries
* still show url breakdown when special goal + url in filter
* rename Query.refresh
* use flat_map instead of map and concat
* fix darkmode color
* Handle invalid imported region codes in suggestions gracefully
* Add an entry to CHANGELOG.md
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Make React frontend capable of reading API results under a results key
* remove redundant double negation
* Update assets/js/dashboard/stats/modals/props.js
add length key back
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Allow running browserless.io locally
* Compile tailwind classes based on extra/ too
* Add browserless runtime configuration
* Ignore verification events on ingestion
* Improve extracting HTML text in tests
* Update dependencies
- Floki will be used on production to parse site contents
- Req will be used to handle redundant stuff like retrying etc.
* Add shuttle SVG to generic components
Later on we'll use it to indicate verification errors
* Connect live socket & allow skipping awaiting the first pageview
* Connect live socket in general settings
* Implement verification checks & diagnostics
* Stub remote services with Req for testing
* Change snippet screen copy
* Update tracker script, so that:
1. headless browsers aren't ignored if `window.__plausible` is defined
2. callback optionally supplies the event response HTTP status
This will be later used to check whether the server acknowledged
the verification event.
* Implement LiveView verification UI
* Embed the verification UIs into settings and onboarding
* Implement browserless puppeteer verification script
It:
- tries to visit the site
- defines window.__plausible, so the tracker doesn't ignore test events
- sends a verification event and instruments the callback
- awaits the callback to fire and returns the result
* Improve diagnostics for CSP
Only report CSP error if the snippet is already found
* Put verification behind a feature flag/env setting
* Contact Us hint only for Enterprise Edition
* For headless code, use JS context instead of EEx interpolation
* Update diagnostics test with WordPress scenarios
* Shorten exception/throw interception
* Rename test
* Tidy up
* Bust URL always on headless check
* Update moduledoc
* Detect official Plausible WordPress Plugin
and act accordingly on diagnostics interoperation
* Stop using 'rating' in favour of 'interpretation'
* Only report CSP error if no proxy is likely
* Update CHANGELOG
* Allow event-* attributes on snippet elements
* Improve naive GTM detection, not to confuse it with GA4
* Update lib/plausible/verification.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Update test/plausible/site/verification/checks_test.exs
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* s/perform_wrapped/perform_safe
* Update lib/plausible/verification/checks/installation.ex
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Remove garbage
---------
Co-authored-by: Adrian Gruntkowski <adrian.gruntkowski@gmail.com>
* Start refactoring, supporting jsonurl
* WIP: Listing of applied filters works
* WIP: Remove some unneeded hackery
* WIP: Handle country labels better
* WIP: Handle multiple filters better
* WIP: Serializing filters for API queries
* Split modal code into 3
* Merge code paths for prop and other filter modals
* Get suggestions working again
* Display prop filters properly
* Handle re-opening a props modal properly
* Better label handling
* Better linking to filter modals
* Remove unneeded component
* Standardize how we update query more
* Use updatedQuery to remove more usecases of URLSearchParams
* Dont export toFilterQuery
* Custom toString for PlausibleSearchParams
* Fix props suggestions/filtering
* Refactor isFilteringOnFixedValue
* Improved encoding - goals now work again
* fix a typo
* Handle more cases where query.filters[ is used
* Fix locations tab changing behavior
* Fix for `setQuery` not to double up ?
* Handle goal filters properly now
* Delete dead code
* Update special goals handling
* Update <ListReport /> linking
* Show labeled values in list of filters
* Updae Props component handling of storage keys
* re-add special case handling in devices view
* Fix modal-related typo
* Get updatedQuery callsites working
* Update location modals linking
* Update props details model linking logic
* Switch back tab from props when removing goal filter
* Remove query.filters usage from within <Referrers /> component
* Private escapeFilterValue
* Fix sources/index.js
* Legacy redirect logic
* Update comment
* Disabled options in props modal
* Update escaping and is_not operator
* Restore `false` search property handling meaning unset
* changelog
* Fix filtering after clicking on a map
* FilterOperatorSelector
* replaceFilterByPrefix
* Improve naming for filter modals/groups
* Apply filters in search console request
* Remove dead code from search console modal
* Remove unimportant information from keyword modal
* Show invalid filters from search console
* Fix tests
* Add/Fix tests
* Fix typo
* Remove unused variable
* Fix typo
* Changelog entry
* Fix Credo
* Display impressions, CTR and position in keyword modal
* Undo change that should not have been committed
* Fix test
* Fix test
* filters -> search_console_filters
* make sure valid intervals consider custom range
* make default intervals per period more logical
* remove unused function
* adjust defaults for custom range
* Give a more semantic name to a function
* Make the LineGraph component thinner
* Move LineGraph into a separate file
* Move interval logic into interval-picker.js
This commit also fixes a bug where the interval name displayed inside
the picker component flickers the default interval when the graph is
loading.
The problem was that we were counting on graphData for returning us the
current interval: `let currentInterval = graphData?.interval`
We should always know the default interval before making the main-graph
request. Sending graphData to IntervalPicker component does not make
sense anyway.
* extract data fetching functions out of VisitorGraph component
* Return graph_metric key from Top Stats API
This commit introduces no behavioral changes - only starts returning an
additional field, allowing us to avoid the following logic in React:
1. Finding the metric names, given a stat display name. E.g.
`Unique visitors (last 30 min) -> visitors`
2. Checking if a metric is graphable or not
* Move metric state into localStorage
This commit gets rid of the internal `metric` state in the VisitorGraph
component and starts using localStorage for that instead.
This commit also chains the main-graph request into the top-stats request
callback - meaning that we'll always fetch new graph data after top stats
are updated. And we do it all in a single function.
Doing so simplifies the loading state significantly, and also helps to
make it clear, that at all times, existing top stats are required before
we can fetch the graph. That's because the metric is determined by which
Top stats are returned (for example, we can't be sure whether revenue
metrics will be returned or not).
* Make sure graph tooltip says "Converted Visitors"
* Extract a StatsExport function component
Again, instead of relying on `graphData?.interval` we can read it from
localStorage, or default to the largest interval available. The export
should not be dependant on the graph.
* Extract SamplingNotice function component
* Extract WithImportedSwitch function component
* Stop "lazy-loading" the graph and top stats
Since the container is always on top on the page, it will be visible on
the first render in any case - no matter the screen size.
* Turn VisitorGraph into a function component
* Display empty container until everything has loaded
* Do not display loading spinner on realtime ticks
* Turn Top Stats into a fn component
* fetch top stats and graph async
* Make sure revenue metrics can remain on the graph
* Add an extra check to canMetricBeGraphed
* fix typo
* remove redundant double negation
* CH Migration: exit/entry hostnames in sessions_v2
* Leave only exit_page_hostname, we already record hostnames
* Use ClickHouse DDL in favour of ecto so that cluster is included
* Compress with ZSTD(3)
* Expose Hostname filter in the dashboard dropdown
* Add `exit_page_hostname` to ClickHouse `sessions_v2` schema
* Start tracking hostname changes in sessions
* Implement hostname filter suggestions
* Enable filtering by `event:hostname`
* Add tests for filtering by hostnames
* Ensure filter suggestions work for exit pages too
* Allow overriding hostnames with `send_pageview` mix task
* Remove `:window_time_on_page` flag
It seems that we can remove it after all?
* Initialize `experimental_hostname_filter` query parameter
* Rewrite cache store behaviour with regards to session hostnames
* Work around inconsistent session merging
So that `populate_stats` can get closer to actual ingestion
* Improve top stats test
* Make it possible to filter sessions by entry/exit hostnames
* Update pages tests
* Expose `experimental_hostname_filtering` temporarily in the UI
* Untested yet: also apply experimental filtering to sources
* Introduce `hostname_filter` feature flag
* Format
* Test top sources with hostname filter + experimental flag
* Check import presence across all imports and not just the first one
Also, simplify imported data toggle rendering to not explicitly
refer to the earliest import source.
* Change imported stats toggle icon in dashboard
* Test `Imported.get_imports_date_range/1`
* Simplify failed UA/GA import email copy
* Add validation for the events metric in main_graph
* Test the already existing events metric support in main-graph
* Put total conversions on the graph
* extract main_graph_csv function (refactor only)
* add total_conversions and conversion_rate to goal-filtered visitors.csv
* update changelog
* add conversion rate to Stats API timeseries
* make sure CR can be queried as the only metric
* add a test asserting zeros are returned
* add tests for filtering by other properties at the same time
* Remove unnecessary validation of params
1. It doesn't make to validate `interval` (and its granularity) in all
endpoints. It's only relevant for the main graph.
2. The plug (renamed to `date_validation_plug`) already makes sure that
the dates are validated. No need to call the same function again in
Top Stats and Funnel endpoints.
* add metric validation to main graph
* Add tests for main graph API
* put conversion rate on the graph
* update changelog
* Add revenue metrics into metrics.ex
* make fn private
* avoid setting graph metric to visitors in goal-filtered view
* UX improvement: don't autofocus on Custom properties on dashboard
Currently when you visit the dashboard with a certain configuration,
it will automatically scroll to the bottom, which is annoying.
To reproduce:
1. localStorage.clear() in console
2. Refresh, open properties at the very bottom
3. Refresh again
Expected behavior:
1. Dashboard shows
Actual behavior:
1. Dashboard scrolls to the bottom
* Changelog entry
* 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