Skip to content

Commit

Permalink
Dimensions and Metrics Explorer UX update (#2027)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
ikuleshov authored Oct 3, 2024
1 parent 4d44d60 commit 9a7455f
Show file tree
Hide file tree
Showing 8 changed files with 344 additions and 333 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,23 @@
"react-helmet": "^6.1.0",
"react-icons": "^4.8.0",
"react-json-view": "^1.21.3",
"react-markdown": "^9.0.1",
"react-loader-spinner": "^6.1.6",
"react-redux": "^8.0.5",
"react-syntax-highlighter": "^15.5.0",
"redux": "^4.2.1",
"remark-gfm": "^4.0.0",
"tsconfig-paths-webpack-plugin": "^4.0.1",
"use-debounce": "^9.0.4",
"use-query-params": "^0.4.3"
},
"devDependencies": {
"@reach/router": "^1.3.4",
"@testing-library/jest-dom": "^6.1.2",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^13.1.8",
"@types/gapi": "^0.0.39",
"@types/gapi.auth2": "^0.0.54",
"@reach/router": "^1.3.4",
"@types/gapi.client.analytics": "^3.0.7",
"@types/gapi.client.analyticsadmin": "^1.0.0",
"@types/gapi.client.analyticsdata": "^1.0.2",
Expand Down
196 changes: 129 additions & 67 deletions src/components/ga4/DimensionsMetricsExplorer/Compatible.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import { navigate } from "gatsby"
import * as React from "react"
import QueryExplorerLink from "../QueryExplorer/BasicReport/QueryExplorerLink"
import { CompatibleHook } from "./useCompatibility"
import Autocomplete from '@mui/material/Autocomplete';
import {Dimension, Metric} from '@/components/ga4/DimensionsMetricsExplorer/useDimensionsAndMetrics';
import TextField from '@mui/material/TextField';

const PREFIX = 'Compatible';

Expand All @@ -23,9 +26,9 @@ const classes = {
};

const StyledPaper = styled(Paper)((
{
theme
}
{
theme
}
) => ({
[`&.${classes.compatible}`]: {
padding: theme.spacing(2),
Expand Down Expand Up @@ -56,89 +59,148 @@ const StyledPaper = styled(Paper)((
}
}));

const WithProperty: React.FC<
CompatibleHook & { property: PropertySummary | undefined }
> = ({
dimensions,
metrics,
removeMetric,
removeDimension,
property,
hasFieldSelected,
}) => {
type CompatibleProps =
CompatibleHook
& {
property: PropertySummary | undefined,
allMetrics: Metric[],
allDimensions: Dimension[]
}
const WithProperty: React.FC<CompatibleProps> = ({
dimensions,
metrics,
removeMetric,
removeDimension, setDimensions, setMetrics,
property,
hasFieldSelected, incompatibleDimensions, incompatibleMetrics,
allDimensions,
allMetrics,
}) => {


if (property === undefined) {
return null
}

return (
<>
<Typography>
As you choose dimensions & metrics (by clicking the checkbox next to
their name), they will be added here. Incompatible dimensions & metrics
will be grayed out.
</Typography>
<div className={classes.chipGrid}>
<Typography className={classes.chipLabel}>Dimensions:</Typography>
<div className={classes.chips}>
{dimensions !== undefined && dimensions.length > 0
? dimensions.map(d => (
<Chip
variant="outlined"
key={d.apiName}
label={d.apiName}
onClick={() => navigate(`#${d.apiName}`)}
onDelete={() => removeDimension(d)}
/>
))
: "No dimensions selected."}
</div>
<Typography className={classes.chipLabel}>Metrics:</Typography>
<div className={classes.chips}>
{metrics !== undefined && metrics.length > 0
? metrics?.map(m => (
<Chip
variant="outlined"
key={m.apiName}
label={m.apiName}
onDelete={() => removeMetric(m)}
/>
))
: "No metrics selected."}
</div>
</div>
{hasFieldSelected && (
<>
<Typography>
Use these fields in the{" "}
<QueryExplorerLink dimensions={dimensions} metrics={metrics} />
As you choose dimensions & metrics, they will be added here.
Incompatible dimensions & metrics will be grayed out.
</Typography>
)}
</>
<div className={classes.chipGrid}>
<Typography className={classes.chipLabel}>Dimensions:</Typography>
<div className={classes.chips}>
<Autocomplete<Dimension, true>
fullWidth
autoComplete
multiple
isOptionEqualToValue={(a, b) => a.apiName === b.apiName}
onChange={(event, value) => setDimensions(value)}
value={dimensions || []}
options={allDimensions}
getOptionDisabled={(option) =>
incompatibleDimensions?.find(d => d.apiName === option.apiName) !== undefined
}
getOptionLabel={dimension => `${dimension.apiName}: ${dimension.uiName}` || ""}
renderInput={params => (
<TextField
{...params}
size="small"
variant="outlined"
helperText={
<>
Select dimensions.
</>
}
/>
)}
renderTags={(tagValue, getTagProps) =>
tagValue.map((option, index) => {
return (
<Chip
key={option.apiName}
label={option.apiName}
onClick={() => navigate(`#${option.apiName}`)}
onDelete={() => removeDimension(option)}
/>
);
})
}
/>
</div>
<Typography className={classes.chipLabel}>Metrics:</Typography>
<div className={classes.chips}>
<Autocomplete<Metric, true>
fullWidth
autoComplete
multiple
isOptionEqualToValue={(a, b) => a.apiName === b.apiName}
onChange={(event, value) => setMetrics(value)}
value={metrics || []}
options={allMetrics}
getOptionDisabled={(option) =>
incompatibleMetrics?.find(d => d.apiName === option.apiName) !== undefined
}
getOptionLabel={metric => `${metric.apiName}: ${metric.uiName}` || ""}
renderInput={params => (
<TextField
{...params}
size="small"
variant="outlined"
helperText={
<>
Select metrics.
</>
}
/>
)}
renderTags={(tagValue, getTagProps) =>
tagValue.map((option, index) => {
return (
<Chip
key={option.apiName}
label={option.apiName}
onClick={() => navigate(`#${option.apiName}`)}
onDelete={() => removeMetric(option)}
/>
);
})
}
/>
</div>
</div>
{hasFieldSelected && (
<Typography>
Use these fields in the{" "}
<QueryExplorerLink dimensions={dimensions} metrics={metrics} />
</Typography>
)}
</>
)
}

const Compatible: React.FC<
CompatibleHook & { property: PropertySummary | undefined }
CompatibleHook & { allDimensions: Dimension[], allMetrics: Metric[], property: PropertySummary | undefined }
> = props => {

const { reset, property, hasFieldSelected } = props

return (
<StyledPaper className={classes.compatible}>
<Typography variant="h3">
Compatible Fields
<IconButton disabled={!hasFieldSelected} onClick={reset}>
<Replay />
</IconButton>
</Typography>
<WithProperty {...props} property={property} />
{property === undefined && (
<Typography>
Pick a property above to enable this functionality.
<StyledPaper className={classes.compatible}>
<Typography variant="h3">
Compatible Fields
<IconButton disabled={!hasFieldSelected} onClick={reset}>
<Replay />
</IconButton>
</Typography>
)}
</StyledPaper>
<WithProperty {...props} property={property} />
{property === undefined && (
<Typography>
Pick a property above to enable this functionality.
</Typography>
)}
</StyledPaper>
);
}

Expand Down
Loading

0 comments on commit 9a7455f

Please sign in to comment.