@@ -53,6 +53,18 @@ type IndexBreakdownProps = SharedBreakdownReportProps & {
5353 metricColumnWidth ?: string
5454 DimensionElement : ( props : DimensionCellWithBarProps ) => ReactNode
5555 onDataReady ?: ( data : QueryApiResponse ) => void
56+ /**
57+ * When true (default), `percentage` is shown inline inside the Visitors
58+ * cell rather than as its own column. Set to false for reports that want
59+ * percentage as a separate breakdown column (e.g. custom properties).
60+ */
61+ bundlePercentageWithVisitors ?: boolean
62+ /**
63+ * Metrics that should be dropped from the rendered columns when every row's
64+ * value for that metric is null. Used by the goals report to hide revenue
65+ * columns when the current rows have no revenue data.
66+ */
67+ hideMetricsIfAllNull ?: Metric [ ]
5668}
5769
5870export function IndexBreakdown ( {
@@ -62,7 +74,9 @@ export function IndexBreakdown({
6274 dimensionLabel,
6375 alwaysOnFilters,
6476 onDataReady,
65- metricColumnWidth = DEFAULT_METRIC_COLUMN_WIDTH
77+ metricColumnWidth = DEFAULT_METRIC_COLUMN_WIDTH ,
78+ bundlePercentageWithVisitors = true ,
79+ hideMetricsIfAllNull
6680} : IndexBreakdownProps ) {
6781 const site = useSiteContext ( )
6882 const { dashboardState } = useDashboardStateContext ( )
@@ -123,19 +137,36 @@ export function IndexBreakdown({
123137 [ dashboardState , dimensions ]
124138 )
125139
140+ const columnsHiddenForAllNull = useMemo ( ( ) : Set < Metric > => {
141+ const hidden = new Set < Metric > ( )
142+ if ( ! hideMetricsIfAllNull || ! apiState . data || ! query ) return hidden
143+ for ( const metric of hideMetricsIfAllNull ) {
144+ const idx = query . metrics . indexOf ( metric )
145+ if ( idx === - 1 ) continue
146+ const allNull = apiState . data . results . every (
147+ ( row ) => row . metrics [ idx ] == null
148+ )
149+ if ( allNull ) hidden . add ( metric )
150+ }
151+ return hidden
152+ } , [ apiState . data , query , hideMetricsIfAllNull ] )
153+
126154 const columns = useMemo ( ( ) : ColumnConfiguration < QueryResultRow > [ ] | null => {
127155 if ( ! query || barMetricIndex === null || barMaxValue === null ) return null
128156
129- // Only render columns for metrics the API actually returned. Also,
130- // percentage is not its own column —- it's shown inline in the
131- // visitors cell instead.
132- const filteredMetrics = query . metrics . filter ( ( m ) => m !== 'percentage' )
157+ // Only render columns for metrics the API actually returned. When
158+ // bundlePercentageWithVisitors is on (default), `percentage` is shown
159+ // inline in the Visitors cell rather than as its own column.
160+ const filteredMetrics = query . metrics . filter ( ( m ) => {
161+ if ( columnsHiddenForAllNull . has ( m ) ) return false
162+ return ! ( bundlePercentageWithVisitors && m === 'percentage' )
163+ } )
133164
134165 const filterDimension = query . dimensions [ 0 ] as NonTimeDimension
135166
136167 const hasPercentage = query . metrics . includes ( 'percentage' )
137168 const isVisitorsWithPercentageCell = ( m : Metric ) =>
138- hasPercentage && m === 'visitors'
169+ bundlePercentageWithVisitors && hasPercentage && m === 'visitors'
139170
140171 return [
141172 {
@@ -191,7 +222,9 @@ export function IndexBreakdown({
191222 metricLabelFor ,
192223 barMaxValue ,
193224 query ,
194- metricColumnWidth
225+ metricColumnWidth ,
226+ bundlePercentageWithVisitors ,
227+ columnsHiddenForAllNull
195228 ] )
196229
197230 return (
0 commit comments