Skip to content

Commit 9a7455f

Browse files
authored
Dimensions and Metrics Explorer UX update (#2027)
* Add screen_view, ad_impression, campaign_details events to EventBuilder * remove UA toggle * update the react-spinner version * remove unimplemented LineItem component * Force Typography to use span tag instead of div to avoid compilation warnings. Remove duplicate code and fix tests by renaming labels... * remove UA code and tests * fix tests * Dimensions and Metrics Explorer UX update Use the autocomplete component to search metrics/dimensions. The main list of all dimensions/metrics remains unchanged when selecting fields for compatibility check. The list of options available in Autocomplete components is updated based on fields' compatibility. Display field categories in accordion with Expand all / Collapse all options. Add option to display compatible only/incompatible only/all fields. Render field description using Markdown.
1 parent 4d44d60 commit 9a7455f

8 files changed

Lines changed: 344 additions & 333 deletions

File tree

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,23 @@
4444
"react-helmet": "^6.1.0",
4545
"react-icons": "^4.8.0",
4646
"react-json-view": "^1.21.3",
47+
"react-markdown": "^9.0.1",
4748
"react-loader-spinner": "^6.1.6",
4849
"react-redux": "^8.0.5",
4950
"react-syntax-highlighter": "^15.5.0",
5051
"redux": "^4.2.1",
52+
"remark-gfm": "^4.0.0",
5153
"tsconfig-paths-webpack-plugin": "^4.0.1",
5254
"use-debounce": "^9.0.4",
5355
"use-query-params": "^0.4.3"
5456
},
5557
"devDependencies": {
58+
"@reach/router": "^1.3.4",
5659
"@testing-library/jest-dom": "^6.1.2",
5760
"@testing-library/react": "^14.0.0",
5861
"@testing-library/user-event": "^13.1.8",
5962
"@types/gapi": "^0.0.39",
6063
"@types/gapi.auth2": "^0.0.54",
61-
"@reach/router": "^1.3.4",
6264
"@types/gapi.client.analytics": "^3.0.7",
6365
"@types/gapi.client.analyticsadmin": "^1.0.0",
6466
"@types/gapi.client.analyticsdata": "^1.0.2",

src/components/ga4/DimensionsMetricsExplorer/Compatible.tsx

Lines changed: 129 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import { navigate } from "gatsby"
1111
import * as React from "react"
1212
import QueryExplorerLink from "../QueryExplorer/BasicReport/QueryExplorerLink"
1313
import { CompatibleHook } from "./useCompatibility"
14+
import Autocomplete from '@mui/material/Autocomplete';
15+
import {Dimension, Metric} from '@/components/ga4/DimensionsMetricsExplorer/useDimensionsAndMetrics';
16+
import TextField from '@mui/material/TextField';
1417

1518
const PREFIX = 'Compatible';
1619

@@ -23,9 +26,9 @@ const classes = {
2326
};
2427

2528
const StyledPaper = styled(Paper)((
26-
{
27-
theme
28-
}
29+
{
30+
theme
31+
}
2932
) => ({
3033
[`&.${classes.compatible}`]: {
3134
padding: theme.spacing(2),
@@ -56,89 +59,148 @@ const StyledPaper = styled(Paper)((
5659
}
5760
}));
5861

59-
const WithProperty: React.FC<
60-
CompatibleHook & { property: PropertySummary | undefined }
61-
> = ({
62-
dimensions,
63-
metrics,
64-
removeMetric,
65-
removeDimension,
66-
property,
67-
hasFieldSelected,
68-
}) => {
62+
type CompatibleProps =
63+
CompatibleHook
64+
& {
65+
property: PropertySummary | undefined,
66+
allMetrics: Metric[],
67+
allDimensions: Dimension[]
68+
}
69+
const WithProperty: React.FC<CompatibleProps> = ({
70+
dimensions,
71+
metrics,
72+
removeMetric,
73+
removeDimension, setDimensions, setMetrics,
74+
property,
75+
hasFieldSelected, incompatibleDimensions, incompatibleMetrics,
76+
allDimensions,
77+
allMetrics,
78+
}) => {
6979

7080

7181
if (property === undefined) {
7282
return null
7383
}
7484

7585
return (
76-
<>
77-
<Typography>
78-
As you choose dimensions & metrics (by clicking the checkbox next to
79-
their name), they will be added here. Incompatible dimensions & metrics
80-
will be grayed out.
81-
</Typography>
82-
<div className={classes.chipGrid}>
83-
<Typography className={classes.chipLabel}>Dimensions:</Typography>
84-
<div className={classes.chips}>
85-
{dimensions !== undefined && dimensions.length > 0
86-
? dimensions.map(d => (
87-
<Chip
88-
variant="outlined"
89-
key={d.apiName}
90-
label={d.apiName}
91-
onClick={() => navigate(`#${d.apiName}`)}
92-
onDelete={() => removeDimension(d)}
93-
/>
94-
))
95-
: "No dimensions selected."}
96-
</div>
97-
<Typography className={classes.chipLabel}>Metrics:</Typography>
98-
<div className={classes.chips}>
99-
{metrics !== undefined && metrics.length > 0
100-
? metrics?.map(m => (
101-
<Chip
102-
variant="outlined"
103-
key={m.apiName}
104-
label={m.apiName}
105-
onDelete={() => removeMetric(m)}
106-
/>
107-
))
108-
: "No metrics selected."}
109-
</div>
110-
</div>
111-
{hasFieldSelected && (
86+
<>
11287
<Typography>
113-
Use these fields in the{" "}
114-
<QueryExplorerLink dimensions={dimensions} metrics={metrics} />
88+
As you choose dimensions & metrics, they will be added here.
89+
Incompatible dimensions & metrics will be grayed out.
11590
</Typography>
116-
)}
117-
</>
91+
<div className={classes.chipGrid}>
92+
<Typography className={classes.chipLabel}>Dimensions:</Typography>
93+
<div className={classes.chips}>
94+
<Autocomplete<Dimension, true>
95+
fullWidth
96+
autoComplete
97+
multiple
98+
isOptionEqualToValue={(a, b) => a.apiName === b.apiName}
99+
onChange={(event, value) => setDimensions(value)}
100+
value={dimensions || []}
101+
options={allDimensions}
102+
getOptionDisabled={(option) =>
103+
incompatibleDimensions?.find(d => d.apiName === option.apiName) !== undefined
104+
}
105+
getOptionLabel={dimension => `${dimension.apiName}: ${dimension.uiName}` || ""}
106+
renderInput={params => (
107+
<TextField
108+
{...params}
109+
size="small"
110+
variant="outlined"
111+
helperText={
112+
<>
113+
Select dimensions.
114+
</>
115+
}
116+
/>
117+
)}
118+
renderTags={(tagValue, getTagProps) =>
119+
tagValue.map((option, index) => {
120+
return (
121+
<Chip
122+
key={option.apiName}
123+
label={option.apiName}
124+
onClick={() => navigate(`#${option.apiName}`)}
125+
onDelete={() => removeDimension(option)}
126+
/>
127+
);
128+
})
129+
}
130+
/>
131+
</div>
132+
<Typography className={classes.chipLabel}>Metrics:</Typography>
133+
<div className={classes.chips}>
134+
<Autocomplete<Metric, true>
135+
fullWidth
136+
autoComplete
137+
multiple
138+
isOptionEqualToValue={(a, b) => a.apiName === b.apiName}
139+
onChange={(event, value) => setMetrics(value)}
140+
value={metrics || []}
141+
options={allMetrics}
142+
getOptionDisabled={(option) =>
143+
incompatibleMetrics?.find(d => d.apiName === option.apiName) !== undefined
144+
}
145+
getOptionLabel={metric => `${metric.apiName}: ${metric.uiName}` || ""}
146+
renderInput={params => (
147+
<TextField
148+
{...params}
149+
size="small"
150+
variant="outlined"
151+
helperText={
152+
<>
153+
Select metrics.
154+
</>
155+
}
156+
/>
157+
)}
158+
renderTags={(tagValue, getTagProps) =>
159+
tagValue.map((option, index) => {
160+
return (
161+
<Chip
162+
key={option.apiName}
163+
label={option.apiName}
164+
onClick={() => navigate(`#${option.apiName}`)}
165+
onDelete={() => removeMetric(option)}
166+
/>
167+
);
168+
})
169+
}
170+
/>
171+
</div>
172+
</div>
173+
{hasFieldSelected && (
174+
<Typography>
175+
Use these fields in the{" "}
176+
<QueryExplorerLink dimensions={dimensions} metrics={metrics} />
177+
</Typography>
178+
)}
179+
</>
118180
)
119181
}
120182

121183
const Compatible: React.FC<
122-
CompatibleHook & { property: PropertySummary | undefined }
184+
CompatibleHook & { allDimensions: Dimension[], allMetrics: Metric[], property: PropertySummary | undefined }
123185
> = props => {
124186

125187
const { reset, property, hasFieldSelected } = props
126188

127189
return (
128-
<StyledPaper className={classes.compatible}>
129-
<Typography variant="h3">
130-
Compatible Fields
131-
<IconButton disabled={!hasFieldSelected} onClick={reset}>
132-
<Replay />
133-
</IconButton>
134-
</Typography>
135-
<WithProperty {...props} property={property} />
136-
{property === undefined && (
137-
<Typography>
138-
Pick a property above to enable this functionality.
190+
<StyledPaper className={classes.compatible}>
191+
<Typography variant="h3">
192+
Compatible Fields
193+
<IconButton disabled={!hasFieldSelected} onClick={reset}>
194+
<Replay />
195+
</IconButton>
139196
</Typography>
140-
)}
141-
</StyledPaper>
197+
<WithProperty {...props} property={property} />
198+
{property === undefined && (
199+
<Typography>
200+
Pick a property above to enable this functionality.
201+
</Typography>
202+
)}
203+
</StyledPaper>
142204
);
143205
}
144206

0 commit comments

Comments
 (0)