diff --git a/packages/manager/src/managers/telemetry/types.ts b/packages/manager/src/managers/telemetry/types.ts index 3bf16be83..e857d35ca 100644 --- a/packages/manager/src/managers/telemetry/types.ts +++ b/packages/manager/src/managers/telemetry/types.ts @@ -15,6 +15,7 @@ export const SegmentEventType = { pageView: "page-view", openVideoTutorials: "open-video-tutorials", field_added: "field:added", + field_updated: "field:updated", field_settingsOpened: "field:settings-opened", customType_created: "custom-type:created", customType_sliceZoneUpdated: "custom-type:slice-zone-updated", @@ -58,6 +59,7 @@ export const HumanSegmentEventType = { [SegmentEventType.pageView]: "SliceMachine Page View", [SegmentEventType.openVideoTutorials]: "SliceMachine Open Video Tutorials", [SegmentEventType.field_added]: "SliceMachine Field Added", + [SegmentEventType.field_updated]: "SliceMachine Field Updated", [SegmentEventType.field_settingsOpened]: "SliceMachine Field Settings Opened", [SegmentEventType.customType_created]: "SliceMachine Custom Type Created", [SegmentEventType.customType_sliceZoneUpdated]: @@ -209,6 +211,21 @@ type FieldAddedSegmentEvent = SegmentEvent< } >; +type FieldUpdatedSegmentEvent = SegmentEvent< + typeof SegmentEventType.field_updated, + { + previousId: string; + id: string; + name: string; + type: FieldType; + isInAGroup: boolean; + contentType: "page type" | "custom type" | "slice"; + allowText?: boolean; + repeat?: boolean; + variants?: string[]; + } +>; + type FieldSettingsOpenedSegmentEvent = SegmentEvent< typeof SegmentEventType.field_settingsOpened, { @@ -401,6 +418,7 @@ export type SegmentEvents = | PageViewSegmentEvent | OpenVideoTutorialsSegmentEvent | FieldAddedSegmentEvent + | FieldUpdatedSegmentEvent | FieldSettingsOpenedSegmentEvent | CustomTypeCreatedSegmentEvent | CustomTypeSliceZoneUpdatedSegmentEvent diff --git a/packages/slice-machine/src/legacy/lib/builders/CustomTypeBuilder/TabZone/index.tsx b/packages/slice-machine/src/legacy/lib/builders/CustomTypeBuilder/TabZone/index.tsx index 4aa05d08a..81421e7af 100644 --- a/packages/slice-machine/src/legacy/lib/builders/CustomTypeBuilder/TabZone/index.tsx +++ b/packages/slice-machine/src/legacy/lib/builders/CustomTypeBuilder/TabZone/index.tsx @@ -36,6 +36,7 @@ import { } from "@/legacy/lib/utils"; import { transformKeyAccessor } from "@/legacy/lib/utils/str"; import { trackFieldAdded } from "@/utils/tracking/trackFieldAdded"; +import { trackFieldUpdated } from "@/utils/tracking/trackFieldUpdated"; import EditModal from "../../common/EditModal"; import Zone from "../../common/Zone"; @@ -71,7 +72,7 @@ type OnSaveFieldProps = { apiId: string; newKey: string; value: TabField; - isNewGroupField?: boolean; + inGroupFieldAction?: "add" | "update"; }; const TabZone: FC = ({ tabId }) => { @@ -169,7 +170,7 @@ const TabZone: FC = ({ tabId }) => { apiId: previousKey, newKey, value, - isNewGroupField, + inGroupFieldAction, }: OnSaveFieldProps) => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call if (ensureWidgetTypeExistence(Widgets, value.type)) { @@ -186,10 +187,22 @@ const TabZone: FC = ({ tabId }) => { }); setCustomType(newCustomType, () => { - if (isNewGroupField === true) { + if (inGroupFieldAction === "add") { toast.success("Field added"); } }); + + // We don't want to track the group field update when it's for the management of a + // field within a group (add or update). + // It would result in double tracking, the one for the field touched within the group + // and the group itself. + if (!inGroupFieldAction) { + trackFieldUpdated({ + previousId: previousKey, + id: newKey, + field: newField, + }); + } }; const onCreateOrSave = (props: OnSaveFieldProps) => { diff --git a/packages/slice-machine/src/legacy/lib/builders/SliceBuilder/FieldZones/index.tsx b/packages/slice-machine/src/legacy/lib/builders/SliceBuilder/FieldZones/index.tsx index 354249d3c..509ad6de8 100644 --- a/packages/slice-machine/src/legacy/lib/builders/SliceBuilder/FieldZones/index.tsx +++ b/packages/slice-machine/src/legacy/lib/builders/SliceBuilder/FieldZones/index.tsx @@ -36,6 +36,7 @@ import { Widgets } from "@/legacy/lib/models/common/widgets"; import { ensureDnDDestination } from "@/legacy/lib/utils"; import { transformKeyAccessor } from "@/legacy/lib/utils/str"; import { trackFieldAdded } from "@/utils/tracking/trackFieldAdded"; +import { trackFieldUpdated } from "@/utils/tracking/trackFieldUpdated"; const dataTipText = ` The non-repeatable zone is for fields
that should appear once, like a
@@ -68,7 +69,7 @@ type OnSaveFieldProps = { apiId: string; newKey: string; value: SlicePrimaryFieldSM; - isNewGroupField?: boolean; + inGroupFieldAction?: "add" | "update"; }; const FieldZones: FC = () => { @@ -105,7 +106,7 @@ const FieldZones: FC = () => { const _onSave = ( widgetArea: WidgetsArea, - { apiId: previousKey, newKey, value, isNewGroupField }: OnSaveFieldProps, + { apiId: previousKey, newKey, value, inGroupFieldAction }: OnSaveFieldProps, ) => { const newSlice = updateField({ slice, @@ -117,10 +118,18 @@ const FieldZones: FC = () => { }); setSlice(newSlice, () => { - if (isNewGroupField === true) { - toast.success("Group added"); + if (inGroupFieldAction === "add") { + toast.success("Field added"); } }); + + // We don't want to track the group field update when it's for the management of a + // field within a group (add or update). + // It would result in double tracking, the one for the field touched within the group + // and the group itself. + if (!inGroupFieldAction) { + trackFieldUpdated({ previousId: previousKey, id: newKey, field: value }); + } }; const _onSaveNewField = ( diff --git a/packages/slice-machine/src/legacy/lib/models/common/widgets/Group/ListItem/index.jsx b/packages/slice-machine/src/legacy/lib/models/common/widgets/Group/ListItem/index.jsx index 49c8783ba..8ac5fe492 100644 --- a/packages/slice-machine/src/legacy/lib/models/common/widgets/Group/ListItem/index.jsx +++ b/packages/slice-machine/src/legacy/lib/models/common/widgets/Group/ListItem/index.jsx @@ -22,6 +22,7 @@ import { ensureDnDDestination } from "@/legacy/lib/utils"; import { transformKeyAccessor } from "@/legacy/lib/utils/str"; import { getContentTypeForTracking } from "@/utils/tracking/getContentTypeForTracking"; import { trackFieldAdded } from "@/utils/tracking/trackFieldAdded"; +import { trackFieldUpdated } from "@/utils/tracking/trackFieldUpdated"; /* eslint-disable */ export const CustomListItem = ({ @@ -67,24 +68,34 @@ export const CustomListItem = ({ apiId: groupItem.key, newKey: groupItem.key, value: Groups.toSM(newGroupValue), - isNewGroupField: true, + inGroupFieldAction: "add", }); trackFieldAdded({ id, field: newField, isInAGroup: true }); }; const onSaveField = ({ apiId: previousKey, newKey, value }) => { + const updatedField = + value.type === GroupFieldType ? Groups.fromSM(value) : value; const newGroupValue = updateFieldInGroup({ group: Groups.fromSM(groupItem.value), previousFieldId: previousKey, newFieldId: newKey, - field: value.type === GroupFieldType ? Groups.fromSM(value) : value, + field: updatedField, }); saveItem({ apiId: groupItem.key, newKey: groupItem.key, value: Groups.toSM(newGroupValue), + inGroupFieldAction: "update", + }); + + trackFieldUpdated({ + previousId: previousKey, + id: newKey, + field: updatedField, + isInAGroup: true, }); }; diff --git a/packages/slice-machine/src/legacy/lib/models/common/widgets/Group/index.tsx b/packages/slice-machine/src/legacy/lib/models/common/widgets/Group/index.tsx index c8138c356..575da29d0 100644 --- a/packages/slice-machine/src/legacy/lib/models/common/widgets/Group/index.tsx +++ b/packages/slice-machine/src/legacy/lib/models/common/widgets/Group/index.tsx @@ -40,12 +40,12 @@ export interface GroupListItemProps { apiId, newKey, value, - isNewGroupField, + inGroupFieldAction, }: { apiId: string; newKey: string; value: F; - isNewGroupField?: boolean; + inGroupFieldAction?: "add" | "update"; }) => void; HintElement: JSX.Element; } diff --git a/packages/slice-machine/src/utils/tracking/trackFieldUpdated.ts b/packages/slice-machine/src/utils/tracking/trackFieldUpdated.ts new file mode 100644 index 000000000..caad3bdbb --- /dev/null +++ b/packages/slice-machine/src/utils/tracking/trackFieldUpdated.ts @@ -0,0 +1,36 @@ +import { + Group, + NestableWidget, + UID, +} from "@prismicio/types-internal/lib/customtypes"; + +import { telemetry } from "@/apiClient"; +import { SlicePrimaryFieldSM } from "@/legacy/lib/models/common/Slice"; + +import { getContentTypeForTracking } from "./getContentTypeForTracking"; + +type TrackFieldUpdatedArgs = { + id: string; + previousId: string; + field: SlicePrimaryFieldSM | NestableWidget | UID | Group; + isInAGroup?: boolean; +}; + +export function trackFieldUpdated(args: TrackFieldUpdatedArgs) { + const { id, previousId = id, field, isInAGroup = false } = args; + + void telemetry.track({ + event: "field:updated", + previousId: previousId, + id, + name: field.config?.label ?? "", + type: field.type, + isInAGroup, + contentType: getContentTypeForTracking(window.location.pathname), + ...(field.type === "Link" && { + allowText: field.config?.allowText, + repeat: field.config?.repeat, + variants: field.config?.variants, + }), + }); +}