Support using matches/contains for most filters (#3721)

* 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
This commit is contained in:
Karl-Aksel Puulmann 2024-02-14 13:49:17 +02:00 committed by GitHub
parent ac7da6a9d4
commit 0065cd3052
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 14 additions and 7 deletions

View File

@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
### Added
- IP Block List in Site Settings
- Allow filtering with `contains`/`matches` operator for Sources, Browsers and Operating Systems.
- Allow filtering by multiple custom properties
- Wildcard and member filtering on the Stats API `event:goal` property
- Allow filtering with `contains`/`matches` operator for custom properties

View File

@ -1,6 +1,7 @@
import React from 'react';
import * as storage from '../../util/storage'
import { isFilteringOnFixedValue } from '../../util/filters'
import ListReport from '../reports/list'
import * as api from '../../api'
import * as url from '../../util/url'
@ -161,12 +162,12 @@ export default class Devices extends React.Component {
renderContent() {
switch (this.state.mode) {
case 'browser':
if (this.props.query.filters.browser) {
if (isFilteringOnFixedValue(this.props.query, 'browser')) {
return <BrowserVersions site={this.props.site} query={this.props.query} />
}
return <Browsers site={this.props.site} query={this.props.query} />
case 'os':
if (this.props.query.filters.os) {
if (isFilteringOnFixedValue(this.props.query, 'os')) {
return <OperatingSystemVersions site={this.props.site} query={this.props.query} />
}
return <OperatingSystems site={this.props.site} query={this.props.query} />

View File

@ -2,11 +2,13 @@ import React from 'react';
import SearchTerms from './search-terms'
import SourceList from './source-list'
import ReferrerList from './referrer-list'
import { isFilteringOnFixedValue } from '../../util/filters'
export default function Sources(props) {
if (props.query.filters.source === 'Google') {
return <SearchTerms {...props} />
} else if (props.query.filters.source) {
} else if (isFilteringOnFixedValue(props.query, 'source')) {
return <ReferrerList {...props} />
} else {
return <SourceList {...props} />

View File

@ -10,9 +10,7 @@ export const FILTER_GROUPS = {
'props': ['prop_key', 'prop_value']
}
export const ALLOW_FREE_CHOICE = new Set(
FILTER_GROUPS['page'].concat(FILTER_GROUPS['utm']).concat(['prop_value'])
)
export const NO_CONTAINS_OPERATOR = new Set(['goal', 'screen'].concat(FILTER_GROUPS['location']))
export const FILTER_OPERATIONS = {
isNot: 'is not',
@ -31,7 +29,7 @@ export function supportsIsNot(filterName) {
}
export function isFreeChoiceFilter(filterName) {
return ALLOW_FREE_CHOICE.has(filterName)
return !NO_CONTAINS_OPERATOR.has(filterName)
}
// As of March 2023, Safari does not support negative lookbehind regexes. In case it throws an error, falls back to plain | matching. This means
@ -102,6 +100,11 @@ export function parseQueryFilter(query, filter) {
return {type, clauses}
}
export function isFilteringOnFixedValue(query, filter) {
const { type, clauses } = parseQueryFilter(query, filter)
return type == FILTER_OPERATIONS.is && clauses.length == 1
}
export function formatFilterGroup(filterGroup) {
if (filterGroup === 'utm') {
return 'UTM tags'