Skip to content

Commit

Permalink
Fix: has_not_done breakdown modals (#5009)
Browse files Browse the repository at this point in the history
* Fix has_not_done goal filters by not querying conversion_rate and other metrics

* hasGoalFilter -> hasConversionGoalFilter

* Fix another special case

* Fix for revenue goals

* Prettier
  • Loading branch information
macobo authored Jan 23, 2025
1 parent c0a762a commit ab77402
Show file tree
Hide file tree
Showing 22 changed files with 73 additions and 65 deletions.
10 changes: 7 additions & 3 deletions assets/js/dashboard/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,15 @@ export function postProcessFilters(filters: Array<Filter>): Array<Filter> {
// goals with the same currency. Used to decide whether to render
// revenue metrics in a dashboard report or not.
export function revenueAvailable(query: DashboardQuery, site: PlausibleSite) {
const revenueGoalsInFilter = site.revenueGoals.filter((rg) => {
const revenueGoalsInFilter = site.revenueGoals.filter((revenueGoal) => {
const goalFilters: Filter[] = getFiltersByKeyPrefix(query, 'goal')

return goalFilters.some(([_op, _key, clauses]) => {
return clauses.includes(rg.display_name)
return goalFilters.some(([operation, _key, clauses]) => {
return (
[FILTER_OPERATIONS.is, FILTER_OPERATIONS.contains].includes(
operation
) && clauses.includes(revenueGoal.display_name)
)
})
})

Expand Down
6 changes: 3 additions & 3 deletions assets/js/dashboard/stats/behaviours/goal-conversions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ListReport from "../reports/list"
import * as metrics from '../reports/metrics'
import * as url from "../../util/url"
import * as api from "../../api"
import { EVENT_PROPS_PREFIX, getGoalFilter } from "../../util/filters"
import { EVENT_PROPS_PREFIX, getGoalFilter, FILTER_OPERATIONS } from "../../util/filters"
import { useSiteContext } from "../../site-context"
import { useQueryContext } from "../../query-context"
import { customPropsRoute } from "../../router"
Expand All @@ -22,8 +22,8 @@ function getSpecialGoal(query) {
if (!goalFilter) {
return null
}
const [_operation, _filterKey, clauses] = goalFilter
if (clauses.length == 1) {
const [operation, _filterKey, clauses] = goalFilter
if (operation === FILTER_OPERATIONS.is && clauses.length == 1) {
return SPECIAL_GOALS[clauses[0]] || null
}
return null
Expand Down
6 changes: 3 additions & 3 deletions assets/js/dashboard/stats/behaviours/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import ImportedQueryUnsupportedWarning from '../imported-query-unsupported-warni
import GoalConversions, { specialTitleWhenGoalFilter, SPECIAL_GOALS } from './goal-conversions'
import Properties from './props'
import { FeatureSetupNotice } from '../../components/notice'
import { hasGoalFilter } from '../../util/filters'
import { hasConversionGoalFilter } from '../../util/filters'
import { useSiteContext } from '../../site-context'
import { useQueryContext } from '../../query-context'
import { useUserContext } from '../../user-context'
Expand Down Expand Up @@ -70,13 +70,13 @@ export default function Behaviours({ importedDataInView }) {
}, [])

useEffect(() => {
const justRemovedGoalFilter = !hasGoalFilter(query)
const justRemovedGoalFilter = !hasConversionGoalFilter(query)
if (mode === PROPS && justRemovedGoalFilter && showingPropsForGoalFilter) {
setShowingPropsForGoalFilter(false)
setMode(CONVERSIONS)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hasGoalFilter(query)])
}, [hasConversionGoalFilter(query)])

useEffect(() => {
setMode(defaultMode())
Expand Down
6 changes: 3 additions & 3 deletions assets/js/dashboard/stats/behaviours/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as metrics from '../reports/metrics';
import * as api from '../../api';
import * as url from '../../util/url';
import * as storage from "../../util/storage";
import { EVENT_PROPS_PREFIX, getGoalFilter, FILTER_OPERATIONS, hasGoalFilter } from "../../util/filters";
import { EVENT_PROPS_PREFIX, getGoalFilter, FILTER_OPERATIONS, hasConversionGoalFilter } from "../../util/filters";
import classNames from "classnames";
import { useQueryContext } from "../../query-context";
import { useSiteContext } from "../../site-context";
Expand Down Expand Up @@ -95,8 +95,8 @@ export default function Properties({ afterFetchData }) {
return [
metrics.createVisitors({ renderLabel: (_query) => "Visitors", meta: { plot: true } }),
metrics.createEvents({ renderLabel: (_query) => "Events", meta: { hiddenOnMobile: true } }),
hasGoalFilter(query) && metrics.createConversionRate(),
!hasGoalFilter(query) && metrics.createPercentage(),
hasConversionGoalFilter(query) && metrics.createConversionRate(),
!hasConversionGoalFilter(query) && metrics.createPercentage(),
BUILD_EXTRA && metrics.createTotalRevenue({ meta: { hiddenOnMobile: true } }),
BUILD_EXTRA && metrics.createAverageRevenue({ meta: { hiddenOnMobile: true } })
].filter(metric => !!metric)
Expand Down
22 changes: 11 additions & 11 deletions assets/js/dashboard/stats/devices/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import * as storage from '../../util/storage';
import { getFiltersByKeyPrefix, hasGoalFilter, isFilteringOnFixedValue } from '../../util/filters';
import { getFiltersByKeyPrefix, hasConversionGoalFilter, isFilteringOnFixedValue } from '../../util/filters';
import ListReport from '../reports/list';
import * as metrics from '../reports/metrics';
import * as api from '../../api';
Expand Down Expand Up @@ -71,8 +71,8 @@ function Browsers({ afterFetchData }) {
function chooseMetrics() {
return [
metrics.createVisitors({ meta: { plot: true } }),
hasGoalFilter(query) && metrics.createConversionRate(),
!hasGoalFilter(query) && metrics.createPercentage()
hasConversionGoalFilter(query) && metrics.createConversionRate(),
!hasConversionGoalFilter(query) && metrics.createPercentage()
].filter(metric => !!metric)
}

Expand Down Expand Up @@ -113,8 +113,8 @@ function BrowserVersions({ afterFetchData }) {
function chooseMetrics() {
return [
metrics.createVisitors({ meta: { plot: true } }),
hasGoalFilter(query) && metrics.createConversionRate(),
!hasGoalFilter(query) && metrics.createPercentage()
hasConversionGoalFilter(query) && metrics.createConversionRate(),
!hasConversionGoalFilter(query) && metrics.createPercentage()
].filter(metric => !!metric)
}

Expand Down Expand Up @@ -180,8 +180,8 @@ function OperatingSystems({ afterFetchData }) {
function chooseMetrics() {
return [
metrics.createVisitors({ meta: { plot: true } }),
hasGoalFilter(query) && metrics.createConversionRate(),
!hasGoalFilter(query) && metrics.createPercentage({ meta: { hiddenonMobile: true } })
hasConversionGoalFilter(query) && metrics.createConversionRate(),
!hasConversionGoalFilter(query) && metrics.createPercentage({ meta: { hiddenonMobile: true } })
].filter(metric => !!metric)
}

Expand Down Expand Up @@ -227,8 +227,8 @@ function OperatingSystemVersions({ afterFetchData }) {
function chooseMetrics() {
return [
metrics.createVisitors({ meta: { plot: true } }),
hasGoalFilter(query) && metrics.createConversionRate(),
!hasGoalFilter(query) && metrics.createPercentage()
hasConversionGoalFilter(query) && metrics.createConversionRate(),
!hasConversionGoalFilter(query) && metrics.createPercentage()
].filter(metric => !!metric)
}

Expand Down Expand Up @@ -268,8 +268,8 @@ function ScreenSizes({ afterFetchData }) {
function chooseMetrics() {
return [
metrics.createVisitors({ meta: { plot: true } }),
hasGoalFilter(query) && metrics.createConversionRate(),
!hasGoalFilter(query) && metrics.createPercentage()
hasConversionGoalFilter(query) && metrics.createConversionRate(),
!hasConversionGoalFilter(query) && metrics.createPercentage()
].filter(metric => !!metric)
}

Expand Down
4 changes: 2 additions & 2 deletions assets/js/dashboard/stats/graph/graph-util.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getFiltersByKeyPrefix, hasGoalFilter } from '../../util/filters'
import { getFiltersByKeyPrefix, hasConversionGoalFilter } from '../../util/filters'
import { revenueAvailable } from '../../query'

export function getGraphableMetrics(query, site) {
const isRealtime = query.period === 'realtime'
const isGoalFilter = hasGoalFilter(query)
const isGoalFilter = hasConversionGoalFilter(query)
const isPageFilter = getFiltersByKeyPrefix(query, "page").length > 0

if (isRealtime && isGoalFilter) {
Expand Down
4 changes: 2 additions & 2 deletions assets/js/dashboard/stats/graph/line-graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { buildDataSet, METRIC_LABELS } from './graph-util'
import dateFormatter from './date-formatter';
import FadeIn from '../../fade-in';
import classNames from 'classnames';
import { hasGoalFilter } from '../../util/filters';
import { hasConversionGoalFilter } from '../../util/filters';
import { MetricFormatterShort } from '../reports/metric-formatter'

const calculateMaximumY = function(dataset) {
Expand All @@ -32,7 +32,7 @@ class LineGraph extends React.Component {
getGraphMetric() {
let metric = this.props.graphData.metric

if (metric == 'visitors' && hasGoalFilter(this.props.query)) {
if (metric == 'visitors' && hasConversionGoalFilter(this.props.query)) {
return 'conversions'
} else {
return metric
Expand Down
8 changes: 4 additions & 4 deletions assets/js/dashboard/stats/locations/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as api from '../../api';
import { apiPath } from '../../util/url';
import ListReport from '../reports/list';
import * as metrics from '../reports/metrics';
import { hasGoalFilter, getFiltersByKeyPrefix } from '../../util/filters';
import { hasConversionGoalFilter, getFiltersByKeyPrefix } from '../../util/filters';
import ImportedQueryUnsupportedWarning from '../imported-query-unsupported-warning';
import { citiesRoute, countriesRoute, regionsRoute } from '../../router';
import { useQueryContext } from '../../query-context';
Expand All @@ -33,7 +33,7 @@ function Countries({ query, site, onClick, afterFetchData }) {
function chooseMetrics() {
return [
metrics.createVisitors({ meta: {plot: true}}),
hasGoalFilter(query) && metrics.createConversionRate(),
hasConversionGoalFilter(query) && metrics.createConversionRate(),
].filter(metric => !!metric)
}

Expand Down Expand Up @@ -72,7 +72,7 @@ function Regions({ query, site, onClick, afterFetchData }) {
function chooseMetrics() {
return [
metrics.createVisitors({ meta: {plot: true}}),
hasGoalFilter(query) && metrics.createConversionRate(),
hasConversionGoalFilter(query) && metrics.createConversionRate(),
].filter(metric => !!metric)
}

Expand Down Expand Up @@ -111,7 +111,7 @@ function Cities({ query, site, afterFetchData }) {
function chooseMetrics() {
return [
metrics.createVisitors({ meta: {plot: true}}),
hasGoalFilter(query) && metrics.createConversionRate(),
hasConversionGoalFilter(query) && metrics.createConversionRate(),
].filter(metric => !!metric)
}

Expand Down
6 changes: 3 additions & 3 deletions assets/js/dashboard/stats/modals/devices/choose-metrics.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { hasGoalFilter, isRealTimeDashboard } from "../../../util/filters";
import { hasConversionGoalFilter, isRealTimeDashboard } from "../../../util/filters";
import * as metrics from '../../reports/metrics'

export default function chooseMetrics(query) {
if (hasGoalFilter(query)) {
if (hasConversionGoalFilter(query)) {
return [
metrics.createTotalVisitors(),
metrics.createVisitors({ renderLabel: (_query) => 'Conversions', width: 'w-28' }),
Expand All @@ -23,4 +23,4 @@ export default function chooseMetrics(query) {
metrics.createBounceRate(),
metrics.createVisitDuration()
]
}
}
4 changes: 2 additions & 2 deletions assets/js/dashboard/stats/modals/entry-pages.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback } from "react";
import Modal from './modal'
import { hasGoalFilter, isRealTimeDashboard } from "../../util/filters";
import { hasConversionGoalFilter, isRealTimeDashboard } from "../../util/filters";
import { addFilter } from '../../query'
import BreakdownModal from "./breakdown-modal";
import * as metrics from '../reports/metrics'
Expand Down Expand Up @@ -33,7 +33,7 @@ function EntryPagesModal() {
}, [reportInfo.dimension])

function chooseMetrics() {
if (hasGoalFilter(query)) {
if (hasConversionGoalFilter(query)) {
return [
metrics.createTotalVisitors(),
metrics.createVisitors({ renderLabel: (_query) => 'Conversions', width: 'w-28' }),
Expand Down
4 changes: 2 additions & 2 deletions assets/js/dashboard/stats/modals/exit-pages.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback } from "react";
import Modal from './modal'
import { hasGoalFilter } from "../../util/filters";
import { hasConversionGoalFilter } from "../../util/filters";
import { addFilter } from '../../query'
import BreakdownModal from "./breakdown-modal";
import * as metrics from '../reports/metrics'
Expand Down Expand Up @@ -33,7 +33,7 @@ function ExitPagesModal() {
}, [reportInfo.dimension])

function chooseMetrics() {
if (hasGoalFilter(query)) {
if (hasConversionGoalFilter(query)) {
return [
metrics.createTotalVisitors(),
metrics.createVisitors({ renderLabel: (_query) => 'Conversions', width: 'w-28' }),
Expand Down
4 changes: 2 additions & 2 deletions assets/js/dashboard/stats/modals/locations-modal.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useCallback } from "react";

import Modal from "./modal";
import { hasGoalFilter } from "../../util/filters";
import { hasConversionGoalFilter } from "../../util/filters";
import BreakdownModal from "./breakdown-modal";
import * as metrics from "../reports/metrics";
import * as url from "../../util/url";
Expand Down Expand Up @@ -36,7 +36,7 @@ function LocationsModal({ currentView }) {
}, [reportInfo.dimension])

function chooseMetrics() {
if (hasGoalFilter(query)) {
if (hasConversionGoalFilter(query)) {
return [
metrics.createTotalVisitors(),
metrics.createVisitors({ renderLabel: (_query) => 'Conversions', width: 'w-28' }),
Expand Down
4 changes: 2 additions & 2 deletions assets/js/dashboard/stats/modals/pages.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {useCallback} from "react";
import Modal from './modal'
import { hasGoalFilter, isRealTimeDashboard } from "../../util/filters";
import { hasConversionGoalFilter, isRealTimeDashboard } from "../../util/filters";
import { addFilter } from '../../query'
import BreakdownModal from "./breakdown-modal";
import * as metrics from '../reports/metrics'
Expand Down Expand Up @@ -33,7 +33,7 @@ function PagesModal() {
}, [reportInfo.dimension])

function chooseMetrics() {
if (hasGoalFilter(query)) {
if (hasConversionGoalFilter(query)) {
return [
metrics.createTotalVisitors(),
metrics.createVisitors({renderLabel: (_query) => 'Conversions', width: 'w-28'}),
Expand Down
6 changes: 3 additions & 3 deletions assets/js/dashboard/stats/modals/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useParams } from "react-router-dom";
import Modal from './modal'
import { addFilter, revenueAvailable } from '../../query'
import { specialTitleWhenGoalFilter } from "../behaviours/goal-conversions";
import { EVENT_PROPS_PREFIX, hasGoalFilter } from "../../util/filters"
import { EVENT_PROPS_PREFIX, hasConversionGoalFilter } from "../../util/filters"
import BreakdownModal from "./breakdown-modal";
import * as metrics from "../reports/metrics";
import * as url from "../../util/url";
Expand Down Expand Up @@ -43,8 +43,8 @@ function PropsModal() {
return [
metrics.createVisitors({ renderLabel: (_query) => "Visitors" }),
metrics.createEvents({ renderLabel: (_query) => "Events" }),
hasGoalFilter(query) && metrics.createConversionRate(),
!hasGoalFilter(query) && metrics.createPercentage(),
hasConversionGoalFilter(query) && metrics.createConversionRate(),
!hasConversionGoalFilter(query) && metrics.createPercentage(),
showRevenueMetrics && metrics.createAverageRevenue(),
showRevenueMetrics && metrics.createTotalRevenue(),
].filter(metric => !!metric)
Expand Down
4 changes: 2 additions & 2 deletions assets/js/dashboard/stats/modals/referrer-drilldown.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useCallback } from 'react'
import { useParams } from 'react-router-dom';

import Modal from './modal'
import { hasGoalFilter, isRealTimeDashboard } from "../../util/filters";
import { hasConversionGoalFilter, isRealTimeDashboard } from "../../util/filters";
import BreakdownModal from "./breakdown-modal";
import * as metrics from "../reports/metrics";
import * as url from "../../util/url";
Expand Down Expand Up @@ -37,7 +37,7 @@ function ReferrerDrilldownModal() {
}, [reportInfo.dimension])

function chooseMetrics() {
if (hasGoalFilter(query)) {
if (hasConversionGoalFilter(query)) {
return [
metrics.createTotalVisitors(),
metrics.createVisitors({ renderLabel: (_query) => 'Conversions', width: 'w-28' }),
Expand Down
4 changes: 2 additions & 2 deletions assets/js/dashboard/stats/modals/sources.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback } from "react";
import Modal from './modal'
import { hasGoalFilter, isRealTimeDashboard } from "../../util/filters";
import { hasConversionGoalFilter, isRealTimeDashboard } from "../../util/filters";
import BreakdownModal from "./breakdown-modal";
import * as metrics from "../reports/metrics";
import * as url from "../../util/url";
Expand Down Expand Up @@ -61,7 +61,7 @@ function SourcesModal({ currentView }) {
}, [reportInfo.dimension])

function chooseMetrics() {
if (hasGoalFilter(query)) {
if (hasConversionGoalFilter(query)) {
return [
metrics.createTotalVisitors(),
metrics.createVisitors({ renderLabel: (_query) => 'Conversions', width: 'w-28' }),
Expand Down
8 changes: 4 additions & 4 deletions assets/js/dashboard/stats/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as api from '../../api';
import ListReport from './../reports/list';
import * as metrics from './../reports/metrics';
import ImportedQueryUnsupportedWarning from '../imported-query-unsupported-warning';
import { hasGoalFilter } from '../../util/filters';
import { hasConversionGoalFilter } from '../../util/filters';
import { useQueryContext } from '../../query-context';
import { useSiteContext } from '../../site-context';
import { entryPagesRoute, exitPagesRoute, topPagesRoute } from '../../router';
Expand All @@ -32,7 +32,7 @@ function EntryPages({ afterFetchData }) {
function chooseMetrics() {
return [
metrics.createVisitors({ defaultLabel: 'Unique Entrances', width: 'w-36', meta: { plot: true } }),
hasGoalFilter(query) && metrics.createConversionRate(),
hasConversionGoalFilter(query) && metrics.createConversionRate(),
].filter(metric => !!metric)
}

Expand Down Expand Up @@ -71,7 +71,7 @@ function ExitPages({ afterFetchData }) {
function chooseMetrics() {
return [
metrics.createVisitors({ defaultLabel: 'Unique Exits', width: 'w-36', meta: { plot: true } }),
hasGoalFilter(query) && metrics.createConversionRate(),
hasConversionGoalFilter(query) && metrics.createConversionRate(),
].filter(metric => !!metric)
}

Expand Down Expand Up @@ -110,7 +110,7 @@ function TopPages({ afterFetchData }) {
function chooseMetrics() {
return [
metrics.createVisitors({ meta: { plot: true } }),
hasGoalFilter(query) && metrics.createConversionRate(),
hasConversionGoalFilter(query) && metrics.createConversionRate(),
].filter(metric => !!metric)
}

Expand Down
Loading

0 comments on commit ab77402

Please sign in to comment.