Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/components/ga4/EventBuilder/Items.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ const Items: React.FC<Props> = ({
addNumberParam={() => addItemNumberParam(idx)}
removeParam={(itemIdx: number) => removeItemParam(idx, itemIdx)}
removeItem={() => removeItem(idx)}
setParamTimestamp={() => {}}
isUserProperty={false}
/>
</WithHelpText>
))}
Expand Down
119 changes: 63 additions & 56 deletions src/components/ga4/EventBuilder/Parameter.tsx
Original file line number Diff line number Diff line change
@@ -1,88 +1,95 @@
import * as React from "react"

import { styled } from '@mui/material/styles';
import TextField from "@mui/material/TextField"
import { Parameter as ParameterT } from "./types"
import { ShowAdvancedCtx } from "."
import { IconButton, Tooltip } from "@mui/material"
import { IconButton, Tooltip, Grid } from "@mui/material"
import { Delete } from "@mui/icons-material"

const PREFIX = 'Parameter';

const classes = {
parameter: `${PREFIX}-parameter`
};

const Root = styled('section')((
{
theme
}
) => ({
[`&.${classes.parameter}`]: {
display: "flex",
"&> *": {
flexGrow: 1,
},
"&> :not(:first-child)": {
marginLeft: theme.spacing(1),
},
}
}));

interface Props {
parameter: ParameterT
setParamName: (name: string) => void
setParamValue: (value: string) => void
setParamTimestamp: (value: number) => void
removeParam: () => void
isUserProperty: boolean
}

const Parameter: React.FC<Props> = ({
parameter,
setParamName,
setParamValue,
setParamTimestamp,
removeParam,
isUserProperty,
}) => {

const showAdvanced = React.useContext(ShowAdvancedCtx)

const [name, setName] = React.useState(parameter.name)
const [value, setValue] = React.useState(parameter.value || "")
const [timestamp, setTimestamp] = React.useState(
parameter.timestamp_micros?.toString() || ""
)

const inputs = (
<Root className={classes.parameter}>
<TextField
id={`#/events/0/params/${name}`}
variant="outlined"
size="small"
value={name}
onChange={e => setName(e.target.value)}
onBlur={() => setParamName(name)}
label="name"
/>
<TextField
variant="outlined"
size="small"
value={value || ""}
InputLabelProps={{
...(parameter.exampleValue === undefined ? {} : { shrink: true }),
}}
onChange={e => setValue(e.target.value)}
onBlur={() => setParamValue(value)}
label={`${parameter.type} value`}
placeholder={parameter.exampleValue?.toString()}
/>
</Root>
<Grid container spacing={1}>
<Grid item xs>
<TextField
id={`#/events/0/params/${name}`}
variant="outlined"
size="small"
value={name}
onChange={e => setName(e.target.value)}
onBlur={() => setParamName(name)}
label="name"
fullWidth
/>
</Grid>
<Grid item xs>
<TextField
variant="outlined"
size="small"
value={value || ""}
InputLabelProps={{
...(parameter.exampleValue === undefined ? {} : { shrink: true }),
}}
onChange={e => setValue(e.target.value)}
onBlur={() => setParamValue(value)}
label={`${parameter.type} value`}
placeholder={parameter.exampleValue?.toString()}
fullWidth
/>
</Grid>
{isUserProperty && (
<Grid item xs>
<TextField
variant="outlined"
size="small"
value={timestamp}
onChange={e => setTimestamp(e.target.value)}
onBlur={() => setParamTimestamp(parseInt(timestamp, 10))}
label="timestamp micros"
helperText="The timestamp to be applied to the user property. Optional."
fullWidth
/>
</Grid>
)}
</Grid>
)
if (showAdvanced) {
return (
<section /* className={formClasses.trashRow} */>
<Tooltip title="remove parameter">
<IconButton onClick={removeParam}>
<Delete />
</IconButton>
</Tooltip>
{inputs}
</section>
<Grid container spacing={1} alignItems="flex-start">
<Grid item>
<Tooltip title="remove parameter">
<IconButton onClick={removeParam}>
<Delete />
</IconButton>
</Tooltip>
</Grid>
<Grid item xs>
{inputs}
</Grid>
</Grid>
)
}
return inputs
Expand Down
6 changes: 6 additions & 0 deletions src/components/ga4/EventBuilder/Parameters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,26 @@ interface Props {
parameters: ParameterT[]
setParamName: (idx: number, name: string) => void
setParamValue: (idx: number, value: string) => void
setParamTimestamp: (idx: number, value: number) => void
addStringParam: () => void
addNumberParam: () => void
removeParam: (idx: number) => void
removeItem?: () => void
addItemsParam?: () => void
isUserProperty: boolean
}

const Parameters: React.FC<Props> = ({
parameters,
setParamName,
setParamValue,
setParamTimestamp,
addStringParam,
addNumberParam,
removeParam,
addItemsParam,
removeItem,
isUserProperty,
}) => {
const showAdvanced = React.useContext(ShowAdvancedCtx)

Expand All @@ -62,7 +66,9 @@ const Parameters: React.FC<Props> = ({
parameter={parameter}
setParamName={name => setParamName(idx, name)}
setParamValue={value => setParamValue(idx, value)}
setParamTimestamp={timestamp => setParamTimestamp(idx, timestamp)}
removeParam={() => removeParam(idx)}
isUserProperty={isUserProperty}
/>
))}
<section className={classes.buttonRow} >
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export const eventSchema = {
"maxLength": 40
},
"params": {"type": "object"},
"items": itemsSchema
"items": itemsSchema,
"timestamp_micros": {}
},
"allOf": buildEvents()
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,11 @@ export const userPropertiesSchema = {
"type": "object",
"required": ["value"],
"additionalProperties": false,

"properties": {
"value": {
"maxLength": 36
},
"timestamp_micros": {
"type": "number",
"maxLength": 36
}
"timestamp_micros": {}
}
}
},
Expand Down
18 changes: 11 additions & 7 deletions src/components/ga4/EventBuilder/ValidateEvent/usePayload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,19 @@ const objectifyUserProperties = (acc: {}, p: Parameter) => {
if (p.type === ParameterType.Number) {
value = tryParseNum(value)
}

if (p.name === "" || value === "" || value === undefined) {
return acc
}

const newProp: { value: any; timestamp_micros?: number } = { value }
if (p.timestamp_micros) {
newProp.timestamp_micros = p.timestamp_micros
}

return {
...acc,
...(p.name !== "" && value !== "" && value !== undefined
? {
[p.name]: {
value,
},
}
: {}),
[p.name]: newProp,
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/components/ga4/EventBuilder/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ describe("Event Builder", () => {
/"app_instance_id":"my_instance_id"/
)
expect(payload).toHaveTextContent(/"user_id":"my_user_id"/)
expect(payload).toHaveTextContent(/"timestamp_micros":"1234"/)
expect(payload).toHaveTextContent(/"timestamp_micros":1234/)
expect(payload).toHaveTextContent(/"non_personalized_ads":true/)
expect(payload).toHaveTextContent(/"name":"select_content"/)
})
Expand Down Expand Up @@ -206,7 +206,7 @@ describe("Event Builder", () => {
const payload = await findByTestId("payload")
expect(payload).toHaveTextContent(/"client_id":"my_client_id"/)
expect(payload).toHaveTextContent(/"user_id":"my_user_id"/)
expect(payload).toHaveTextContent(/"timestamp_micros":"1234"/)
expect(payload).toHaveTextContent(/"timestamp_micros":1234/)
expect(payload).toHaveTextContent(/"non_personalized_ads":true/)
expect(payload).toHaveTextContent(/"name":"campaign_details"/)
})
Expand Down
12 changes: 10 additions & 2 deletions src/components/ga4/EventBuilder/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ const Root = styled('div')((

[`& .${classes.form}`]: {
maxWidth: "80ch",
"& h5:not(:first-of-type)": {
marginTop: theme.spacing(4),
},
},

[`& .${classes.items}`]: {
Expand Down Expand Up @@ -144,7 +147,7 @@ export type EventPayload = {
parameters: Parameter[]
items: Parameter[][] | undefined
userProperties: Parameter[]
timestamp_micros: string | undefined
timestamp_micros: number | undefined
non_personalized_ads: boolean | undefined
clientIds: ClientIds
instanceId: InstanceId
Expand All @@ -169,6 +172,7 @@ const EventBuilder: React.FC = () => {
removeUserProperty,
setUserPropertyName,
setUserPropertyValue,
setUserPropertyTimestamp,
} = useUserProperties()

const {
Expand Down Expand Up @@ -591,6 +595,8 @@ const EventBuilder: React.FC = () => {
setParamName={setParamName}
setParamValue={setParamValue}
addItemsParam={items === undefined ? addItemsParam : undefined}
setParamTimestamp={() => {}}
isUserProperty={false}
/>
{items !== undefined && (
<>
Expand Down Expand Up @@ -619,6 +625,8 @@ const EventBuilder: React.FC = () => {
addNumberParam={addNumberUserProperty}
setParamName={setUserPropertyName}
setParamValue={setUserPropertyValue}
setParamTimestamp={setUserPropertyTimestamp}
isUserProperty={true}
/>
</>
)}
Expand All @@ -640,7 +648,7 @@ const EventBuilder: React.FC = () => {
parameters,
eventName,
userProperties,
timestamp_micros,
timestamp_micros: (num => isNaN(num) ? undefined : num)(parseFloat(timestamp_micros || '')),
non_personalized_ads,
useTextBox,
payloadObj,
Expand Down
2 changes: 2 additions & 0 deletions src/components/ga4/EventBuilder/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,14 @@ export interface NumberParameter {
name: string
value: string | undefined
exampleValue?: number
timestamp_micros?: number
}
export interface StringParameter {
type: ParameterType.String
name: string
value: string | undefined
exampleValue?: string
timestamp_micros?: number
}

export type Parameter = NumberParameter | StringParameter
Expand Down
8 changes: 8 additions & 0 deletions src/components/ga4/EventBuilder/useUserProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,21 @@ const useUserProperties = () => {
[updateUserProperty]
)

const setUserPropertyTimestamp = useCallback(
(idx: number, timestamp_micros: number) => {
updateUserProperty(idx, old => ({ ...old, timestamp_micros }))
},
[updateUserProperty]
)

return {
userProperties: userProperties || [],
addStringUserProperty,
addNumberUserProperty,
removeUserProperty,
setUserPropertyValue,
setUserPropertyName,
setUserPropertyTimestamp,
}
}

Expand Down
Loading