@simplybusiness/services 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/services/index.js +0 -4
  3. package/dist/cjs/services/index.js.map +1 -1
  4. package/dist/cjs/services/snowplow/Snowplow.js +138 -0
  5. package/dist/cjs/services/snowplow/Snowplow.js.map +1 -0
  6. package/dist/cjs/services/snowplow/SnowplowContext.js +2 -2
  7. package/dist/cjs/services/snowplow/SnowplowContext.js.map +1 -1
  8. package/dist/cjs/services/snowplow/event-definitions/base.js +37 -0
  9. package/dist/cjs/services/snowplow/event-definitions/base.js.map +1 -0
  10. package/dist/cjs/services/snowplow/event-definitions/index.js +31 -0
  11. package/dist/cjs/services/snowplow/event-definitions/index.js.map +1 -0
  12. package/dist/cjs/services/snowplow/{event-definitions.js → event-definitions/qcp.js} +5 -26
  13. package/dist/cjs/services/snowplow/event-definitions/qcp.js.map +1 -0
  14. package/dist/cjs/services/snowplow/index.js +16 -129
  15. package/dist/cjs/services/snowplow/index.js.map +1 -1
  16. package/dist/esm/services/index.js +0 -4
  17. package/dist/esm/services/index.js.map +1 -1
  18. package/dist/esm/services/snowplow/Snowplow.js +133 -0
  19. package/dist/esm/services/snowplow/Snowplow.js.map +1 -0
  20. package/dist/esm/services/snowplow/SnowplowContext.js +1 -1
  21. package/dist/esm/services/snowplow/SnowplowContext.js.map +1 -1
  22. package/dist/esm/services/snowplow/event-definitions/base.js +43 -0
  23. package/dist/esm/services/snowplow/event-definitions/base.js.map +1 -0
  24. package/dist/esm/services/snowplow/event-definitions/index.js +14 -0
  25. package/dist/esm/services/snowplow/event-definitions/index.js.map +1 -0
  26. package/dist/esm/services/snowplow/{event-definitions.js → event-definitions/qcp.js} +4 -24
  27. package/dist/esm/services/snowplow/event-definitions/qcp.js.map +1 -0
  28. package/dist/esm/services/snowplow/index.js +6 -131
  29. package/dist/esm/services/snowplow/index.js.map +1 -1
  30. package/dist/types/services/index.d.ts +0 -3
  31. package/dist/types/services/snowplow/Snowplow.d.ts +29 -0
  32. package/dist/types/services/snowplow/SnowplowContext.d.ts +1 -1
  33. package/dist/types/services/snowplow/event-definitions/base.d.ts +18 -0
  34. package/dist/types/services/snowplow/event-definitions/index.d.ts +2 -0
  35. package/dist/types/services/snowplow/{event-definitions.d.ts → event-definitions/qcp.d.ts} +2 -2
  36. package/dist/types/services/snowplow/index.d.ts +6 -29
  37. package/package.json +15 -15
  38. package/src/services/index.tsx +0 -4
  39. package/src/services/snowplow/Snowplow.ts +163 -0
  40. package/src/services/snowplow/SnowplowContext.tsx +1 -1
  41. package/src/services/snowplow/event-definitions/base.ts +47 -0
  42. package/src/services/snowplow/event-definitions/index.ts +13 -0
  43. package/src/services/snowplow/{event-definitions.ts → event-definitions/qcp.ts} +5 -26
  44. package/src/services/snowplow/index.test.ts +1 -1
  45. package/src/services/snowplow/index.ts +6 -163
  46. package/dist/cjs/services/snowplow/event-definitions.js.map +0 -1
  47. package/dist/cjs/tsconfig.tsbuildinfo +0 -1
  48. package/dist/esm/services/snowplow/event-definitions.js.map +0 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@simplybusiness/services",
3
3
  "license": "UNLICENSED",
4
- "version": "0.1.2",
4
+ "version": "0.1.4",
5
5
  "description": "Internal library for services",
6
6
  "repository": {
7
7
  "type": "git",
@@ -42,18 +42,18 @@
42
42
  "react-dom": "^18.2.0"
43
43
  },
44
44
  "devDependencies": {
45
- "@react-types/shared": "^3.23.1",
46
- "@swc/cli": "^0.3.14",
47
- "@swc/core": "^1.6.5",
45
+ "@react-types/shared": "^3.24.1",
46
+ "@swc/cli": "^0.4.0",
47
+ "@swc/core": "^1.7.1",
48
48
  "@swc/jest": "^0.2.36",
49
- "@testing-library/dom": "^10.2.0",
50
- "@testing-library/jest-dom": "6.4.6",
49
+ "@testing-library/dom": "^10.4.0",
50
+ "@testing-library/jest-dom": "6.4.8",
51
51
  "@testing-library/react": "^16.0.0",
52
52
  "@types/jest": "^29.5.12",
53
53
  "@types/react": "^18.3.3",
54
54
  "@types/react-dom": "^18.3.0",
55
- "@typescript-eslint/eslint-plugin": "^7.14.1",
56
- "@typescript-eslint/parser": "^7.14.1",
55
+ "@typescript-eslint/eslint-plugin": "^7.17.0",
56
+ "@typescript-eslint/parser": "^7.17.0",
57
57
  "eslint": "^8.57.0",
58
58
  "eslint-config-airbnb": "^19.0.4",
59
59
  "eslint-config-prettier": "^9.1.0",
@@ -61,23 +61,23 @@
61
61
  "eslint-plugin-import": "^2.29.1",
62
62
  "eslint-plugin-jsx-a11y": "^6.9.0",
63
63
  "eslint-plugin-no-only-tests": "^3.1.0",
64
- "eslint-plugin-prettier": "^5.1.3",
65
- "eslint-plugin-react": "^7.34.3",
64
+ "eslint-plugin-prettier": "^5.2.1",
65
+ "eslint-plugin-react": "^7.35.0",
66
66
  "eslint-plugin-react-hooks": "^4.6.2",
67
67
  "identity-obj-proxy": "^3.0.0",
68
68
  "jest": "^29.7.0",
69
69
  "jest-environment-jsdom": "^29.7.0",
70
- "prettier": "^3.3.2",
70
+ "prettier": "^3.3.3",
71
71
  "react": "^18.3.1",
72
72
  "react-dom": "^18.3.1",
73
- "ts-jest": "^29.1.5",
73
+ "ts-jest": "^29.2.3",
74
74
  "tslib": "^2.6.3",
75
- "typescript": "^5.5.2"
75
+ "typescript": "^5.5.4"
76
76
  },
77
77
  "dependencies": {
78
78
  "@airbrake/browser": "^2.1.8",
79
- "@simplybusiness/mobius": "^4.13.0",
80
- "@snowplow/browser-tracker": "^3.24.0",
79
+ "@simplybusiness/mobius": "^4.14.0",
80
+ "@snowplow/browser-tracker": "^3.24.2",
81
81
  "classnames": "^2.5.1"
82
82
  },
83
83
  "lint-staged": {
@@ -1,6 +1,2 @@
1
- // TODO: move all Snowplow related code to a single index.tsx file
2
1
  export * from "./snowplow";
3
- export * from "./snowplow/SnowplowContext";
4
- export * from "./snowplow/getSnowplowConfig";
5
- export * from "./snowplow/contexts";
6
2
  export * from "./airbrake";
@@ -0,0 +1,163 @@
1
+ import {
2
+ SelfDescribingJson,
3
+ StructuredEvent,
4
+ TrackerConfiguration,
5
+ newTracker,
6
+ setCookiePath,
7
+ setUserId,
8
+ trackPageView,
9
+ trackSelfDescribingEvent,
10
+ trackStructEvent,
11
+ } from "@snowplow/browser-tracker";
12
+ import { EventDefinition, TrackingProps } from "./types";
13
+
14
+ export type FrontOfficeStructuredEvent = StructuredEvent & {
15
+ serviceChannelIdentifier: string;
16
+ };
17
+
18
+ /**
19
+ * This class is an abstraction which wraps Snowplow
20
+ * and exposes common methods with other services:
21
+ * - trackEvent : sends a standard payload
22
+ * - trackUnstructEvent : sends a payload for custom schema
23
+ */
24
+ export class Snowplow {
25
+ avalancheTrackerName = "sb-ava";
26
+
27
+ bronzeAvalancheTrackerName = "sb-ava-br";
28
+
29
+ pvAvalancheTrackerName = "sb-ava-pv";
30
+
31
+ uid: unknown = "";
32
+
33
+ trackPageView: boolean = false;
34
+
35
+ contexts: SelfDescribingJson<Record<string, unknown>>[] = [];
36
+
37
+ eventHandlers: Record<string, (params?: Record<string, unknown>) => void> =
38
+ {};
39
+
40
+ constructor(props?: TrackingProps) {
41
+ if (!props) return;
42
+
43
+ const {
44
+ appId,
45
+ cookieDomain,
46
+ avalancheCollector,
47
+ eventMethod,
48
+ uid,
49
+ postPath,
50
+ // includeGAContext,
51
+ // trackActivity,
52
+ trackPageView: tpv,
53
+ } = props;
54
+ this.uid = uid;
55
+ this.trackPageView = tpv;
56
+
57
+ // Set options
58
+ const stateStorageStrategy = "cookieAndLocalStorage";
59
+ const baseOptions: TrackerConfiguration = {
60
+ appId,
61
+ cookieDomain,
62
+ eventMethod,
63
+ stateStorageStrategy,
64
+ postPath,
65
+ };
66
+ // Initialize trackers
67
+ newTracker(this.avalancheTrackerName, avalancheCollector, baseOptions);
68
+
69
+ newTracker(
70
+ this.bronzeAvalancheTrackerName,
71
+ avalancheCollector,
72
+ baseOptions,
73
+ );
74
+
75
+ // Page view tracker
76
+ newTracker(this.pvAvalancheTrackerName, avalancheCollector, {
77
+ ...baseOptions,
78
+ eventMethod: eventMethod === "post" ? "beacon" : eventMethod,
79
+ });
80
+
81
+ setCookiePath("/");
82
+ if (uid) {
83
+ setUserId(uid);
84
+ }
85
+ }
86
+
87
+ setContexts(contexts: SelfDescribingJson<Record<string, unknown>>[]) {
88
+ this.contexts = contexts;
89
+ // Update identity context
90
+ const index = this.contexts?.findIndex(ctx =>
91
+ ctx.schema?.includes("identity_context"),
92
+ );
93
+ if (index > -1) {
94
+ this.contexts[index].data.domain_userid = this.uid;
95
+ }
96
+ return this;
97
+ }
98
+
99
+ // Send a page view event
100
+ trackView() {
101
+ if (this.trackPageView) {
102
+ trackPageView({ context: this.contexts });
103
+ }
104
+ return this;
105
+ }
106
+
107
+ // Send a structured event with contexts
108
+ async trackEvent(event: StructuredEvent) {
109
+ await trackStructEvent({ ...event, context: this.contexts }, [
110
+ this.bronzeAvalancheTrackerName,
111
+ ]);
112
+ return this;
113
+ }
114
+
115
+ // Send a custom event with defined schema and optional contexts
116
+ async trackUnstructEvent(event: SelfDescribingJson<Record<string, unknown>>) {
117
+ if (!event) {
118
+ return this;
119
+ }
120
+ await trackSelfDescribingEvent({ event, context: this.contexts }, [
121
+ this.avalancheTrackerName,
122
+ ]);
123
+ return this;
124
+ }
125
+
126
+ addEventHandlers(eventDefinitions: EventDefinition[]) {
127
+ eventDefinitions.forEach(({ name, type, makePayload }) => {
128
+ // Convert type into relevant function
129
+ if (type === "structured") {
130
+ this.addEventHandler(name, (params?: Record<string, unknown>) => {
131
+ this.trackEvent(makePayload(params) as StructuredEvent);
132
+ });
133
+ } else {
134
+ this.addEventHandler(name, (params?: Record<string, unknown>) => {
135
+ this.trackUnstructEvent(
136
+ makePayload(params) as SelfDescribingJson<Record<string, unknown>>,
137
+ );
138
+ });
139
+ }
140
+ });
141
+ return this;
142
+ }
143
+
144
+ private addEventHandler(
145
+ name: string,
146
+ handler: (params?: Record<string, unknown>) => void,
147
+ ) {
148
+ this.eventHandlers[name] = handler;
149
+ return this;
150
+ }
151
+
152
+ private removeEventHandler(name: string) {
153
+ delete this.eventHandlers[name];
154
+ return this;
155
+ }
156
+
157
+ trigger(name: string, params?: Record<string, unknown>) {
158
+ if (this.eventHandlers[name]) {
159
+ this.eventHandlers[name](params);
160
+ }
161
+ return this;
162
+ }
163
+ }
@@ -7,9 +7,9 @@ import {
7
7
  useState,
8
8
  type ReactNode,
9
9
  } from "react";
10
- import { Snowplow } from ".";
11
10
  import { getContexts } from "./contexts";
12
11
  import { eventDefinitions } from "./event-definitions";
12
+ import { Snowplow } from "./Snowplow";
13
13
  import { EventDefinition, TrackingProps } from "./types";
14
14
 
15
15
  export interface SnowplowContextInterface {
@@ -0,0 +1,47 @@
1
+ import { EventDefinition } from "../types";
2
+
3
+ /**
4
+ * Event definitions for Snowplow
5
+ * @type {EventDefinition[]}
6
+ * @property {string} name - The name of the event, to use when triggering
7
+ * @property {string} type - The type of the event (structured | unstructured)
8
+ * @property {makePayload} makePayload
9
+ * - Function that creates the payload for the event;
10
+ * - Allows optional params object to be passed in
11
+ *
12
+ * @example
13
+ * import { Snowplow } from "./Snowplow";
14
+ * import { eventDefinitions } from "./event-definitions";
15
+ *
16
+ * const snowplow = new Snowplow();
17
+ * snowplow.addEventHandlers(eventDefinitions);
18
+ */
19
+
20
+ // Base page events
21
+ export const baseEventDefinitions: EventDefinition[] = [
22
+ // Mobile link in header
23
+ {
24
+ name: "mobileLinkClick",
25
+ type: "structured",
26
+ makePayload: () => ({
27
+ category: "marketing",
28
+ action: "link-click",
29
+ label: "mobile_call_button",
30
+ property: window.location.href,
31
+ }),
32
+ },
33
+ // Operating hours link in footer
34
+ {
35
+ name: "operatingHoursClick",
36
+ type: "unstructured",
37
+ makePayload: () => ({
38
+ schema:
39
+ "iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0",
40
+ data: {
41
+ schema:
42
+ "iglu:com.simplybusiness/operating_hours_clicked/jsonschema/1-0-2",
43
+ data: {},
44
+ },
45
+ }),
46
+ },
47
+ ];
@@ -0,0 +1,13 @@
1
+ import { baseEventDefinitions } from "./base";
2
+ import { qcpEventDefinitions } from "./qcp";
3
+
4
+ // All events (keep up to date with new files)
5
+ export const eventDefinitions = [
6
+ ...baseEventDefinitions,
7
+ ...qcpEventDefinitions,
8
+ ];
9
+
10
+ export const qcpPageEvents = [...baseEventDefinitions, ...qcpEventDefinitions];
11
+
12
+ // Create a new export for each kind of page below
13
+ // containing just the subset needed for that page
@@ -1,5 +1,5 @@
1
- import { EventDefinition, ParamsType } from "./types";
2
- import { snakeCase } from "../../utils";
1
+ import { snakeCase } from "../../../utils";
2
+ import { EventDefinition, ParamsType } from "../types";
3
3
 
4
4
  /**
5
5
  * Event definitions for Snowplow
@@ -17,30 +17,9 @@ import { snakeCase } from "../../utils";
17
17
  * const snowplow = new Snowplow();
18
18
  * snowplow.addEventHandlers(eventDefinitions);
19
19
  */
20
- export const eventDefinitions: EventDefinition[] = [
21
- {
22
- name: "mobileLinkClick",
23
- type: "structured",
24
- makePayload: () => ({
25
- category: "marketing",
26
- action: "link-click",
27
- label: "mobile_call_button",
28
- property: window.location.href,
29
- }),
30
- },
31
- {
32
- name: "operatingHoursClick",
33
- type: "unstructured",
34
- makePayload: () => ({
35
- schema:
36
- "iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0",
37
- data: {
38
- schema:
39
- "iglu:com.simplybusiness/operating_hours_clicked/jsonschema/1-0-2",
40
- data: {},
41
- },
42
- }),
43
- },
20
+
21
+ // QCP page events
22
+ export const qcpEventDefinitions: EventDefinition[] = [
44
23
  {
45
24
  // QDP details button
46
25
  name: "detailsClicked",
@@ -4,8 +4,8 @@ import { pageData } from "../../data/scripts-mock";
4
4
  import eventDefinitions from "../../mocks/eventDefinitions";
5
5
  import { getContexts } from "./contexts";
6
6
  import { getSnowplowConfig } from "./getSnowplowConfig";
7
- import { Snowplow } from "./index";
8
7
  import { EventDefinition, PageDataProps, TrackingProps } from "./types";
8
+ import { Snowplow } from "./Snowplow";
9
9
 
10
10
  const snowplowProps = getSnowplowConfig(pageData as PageDataProps);
11
11
  const contexts = getContexts(snowplowProps as TrackingProps);
@@ -1,163 +1,6 @@
1
- import {
2
- SelfDescribingJson,
3
- StructuredEvent,
4
- TrackerConfiguration,
5
- newTracker,
6
- setCookiePath,
7
- setUserId,
8
- trackPageView,
9
- trackSelfDescribingEvent,
10
- trackStructEvent,
11
- } from "@snowplow/browser-tracker";
12
- import { EventDefinition, TrackingProps } from "./types";
13
-
14
- export type FrontOfficeStructuredEvent = StructuredEvent & {
15
- serviceChannelIdentifier: string;
16
- };
17
-
18
- /**
19
- * This class is an abstraction which wraps Snowplow
20
- * and exposes common methods with other services:
21
- * - trackEvent : sends a standard payload
22
- * - trackUnstructEvent : sends a payload for custom schema
23
- */
24
- export class Snowplow {
25
- avalancheTrackerName = "sb-ava";
26
-
27
- bronzeAvalancheTrackerName = "sb-ava-br";
28
-
29
- pvAvalancheTrackerName = "sb-ava-pv";
30
-
31
- uid: unknown = "";
32
-
33
- trackPageView: boolean = false;
34
-
35
- contexts: SelfDescribingJson<Record<string, unknown>>[] = [];
36
-
37
- eventHandlers: Record<string, (params?: Record<string, unknown>) => void> =
38
- {};
39
-
40
- constructor(props?: TrackingProps) {
41
- if (!props) return;
42
-
43
- const {
44
- appId,
45
- cookieDomain,
46
- avalancheCollector,
47
- eventMethod,
48
- uid,
49
- postPath,
50
- // includeGAContext,
51
- // trackActivity,
52
- trackPageView: tpv,
53
- } = props;
54
- this.uid = uid;
55
- this.trackPageView = tpv;
56
-
57
- // Set options
58
- const stateStorageStrategy = "cookieAndLocalStorage";
59
- const baseOptions: TrackerConfiguration = {
60
- appId,
61
- cookieDomain,
62
- eventMethod,
63
- stateStorageStrategy,
64
- postPath,
65
- };
66
- // Initialize trackers
67
- newTracker(this.avalancheTrackerName, avalancheCollector, baseOptions);
68
-
69
- newTracker(
70
- this.bronzeAvalancheTrackerName,
71
- avalancheCollector,
72
- baseOptions,
73
- );
74
-
75
- // Page view tracker
76
- newTracker(this.pvAvalancheTrackerName, avalancheCollector, {
77
- ...baseOptions,
78
- eventMethod: eventMethod === "post" ? "beacon" : eventMethod,
79
- });
80
-
81
- setCookiePath("/");
82
- if (uid) {
83
- setUserId(uid);
84
- }
85
- }
86
-
87
- setContexts(contexts: SelfDescribingJson<Record<string, unknown>>[]) {
88
- this.contexts = contexts;
89
- // Update identity context
90
- const index = this.contexts?.findIndex(ctx =>
91
- ctx.schema?.includes("identity_context"),
92
- );
93
- if (index > -1) {
94
- this.contexts[index].data.domain_userid = this.uid;
95
- }
96
- return this;
97
- }
98
-
99
- // Send a page view event
100
- trackView() {
101
- if (this.trackPageView) {
102
- trackPageView({ context: this.contexts });
103
- }
104
- return this;
105
- }
106
-
107
- // Send a structured event with contexts
108
- async trackEvent(event: StructuredEvent) {
109
- await trackStructEvent({ ...event, context: this.contexts }, [
110
- this.bronzeAvalancheTrackerName,
111
- ]);
112
- return this;
113
- }
114
-
115
- // Send a custom event with defined schema and optional contexts
116
- async trackUnstructEvent(event: SelfDescribingJson<Record<string, unknown>>) {
117
- if (!event) {
118
- return this;
119
- }
120
- await trackSelfDescribingEvent({ event, context: this.contexts }, [
121
- this.avalancheTrackerName,
122
- ]);
123
- return this;
124
- }
125
-
126
- addEventHandlers(eventDefinitions: EventDefinition[]) {
127
- eventDefinitions.forEach(({ name, type, makePayload }) => {
128
- // Convert type into relevant function
129
- if (type === "structured") {
130
- this.addEventHandler(name, (params?: Record<string, unknown>) => {
131
- this.trackEvent(makePayload(params) as StructuredEvent);
132
- });
133
- } else {
134
- this.addEventHandler(name, (params?: Record<string, unknown>) => {
135
- this.trackUnstructEvent(
136
- makePayload(params) as SelfDescribingJson<Record<string, unknown>>,
137
- );
138
- });
139
- }
140
- });
141
- return this;
142
- }
143
-
144
- private addEventHandler(
145
- name: string,
146
- handler: (params?: Record<string, unknown>) => void,
147
- ) {
148
- this.eventHandlers[name] = handler;
149
- return this;
150
- }
151
-
152
- private removeEventHandler(name: string) {
153
- delete this.eventHandlers[name];
154
- return this;
155
- }
156
-
157
- trigger(name: string, params?: Record<string, unknown>) {
158
- if (this.eventHandlers[name]) {
159
- this.eventHandlers[name](params);
160
- }
161
- return this;
162
- }
163
- }
1
+ export * from "./contexts";
2
+ export * from "./event-definitions";
3
+ export * from "./getSnowplowConfig";
4
+ export * from "./Snowplow";
5
+ export * from "./SnowplowContext";
6
+ export * from "./types";
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../src/services/snowplow/event-definitions.ts"],"sourcesContent":["import { EventDefinition, ParamsType } from \"./types\";\nimport { snakeCase } from \"../../utils\";\n\n/**\n * Event definitions for Snowplow\n * @type {EventDefinition[]}\n * @property {string} name - The name of the event, to use when triggering\n * @property {string} type - The type of the event (structured | unstructured)\n * @property {makePayload} makePayload\n * - Function that creates the payload for the event;\n * - Allows optional params object to be passed in\n *\n * @example\n * import { Snowplow } from \"./Snowplow\";\n * import { eventDefinitions } from \"./event-definitions\";\n *\n * const snowplow = new Snowplow();\n * snowplow.addEventHandlers(eventDefinitions);\n */\nexport const eventDefinitions: EventDefinition[] = [\n {\n name: \"mobileLinkClick\",\n type: \"structured\",\n makePayload: () => ({\n category: \"marketing\",\n action: \"link-click\",\n label: \"mobile_call_button\",\n property: window.location.href,\n }),\n },\n {\n name: \"operatingHoursClick\",\n type: \"unstructured\",\n makePayload: () => ({\n schema:\n \"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\n data: {\n schema:\n \"iglu:com.simplybusiness/operating_hours_clicked/jsonschema/1-0-2\",\n data: {},\n },\n }),\n },\n {\n // QDP details button\n name: \"detailsClicked\",\n type: \"structured\",\n makePayload: () => ({\n category: \"comparison_cta\",\n action: \"link_click\",\n label: \"Details\",\n }),\n },\n {\n // Buy button\n name: \"selectClicked\",\n type: \"structured\",\n makePayload: () => ({\n category: \"comparison_cta\",\n action: \"link_click\",\n label: \"Select\",\n }),\n },\n {\n // Quote Details Slider Next steps button\n name: \"nextStepsClicked\",\n type: \"structured\",\n makePayload: () => ({\n category: \"quote_details_slider_next_step_cta\",\n action: \"link_click\",\n label: \"Next steps\",\n }),\n },\n {\n // Toggle deductibles accordion\n name: \"deductiblesClicked\",\n type: \"structured\",\n makePayload: () => ({\n category: \"us-qcp-react\",\n action: \"view_deductables_clicked\",\n label: \"view_deductables_clicked\",\n property: window.location.href,\n }),\n },\n {\n name: \"deductiblesClickedUk\",\n type: \"structured\",\n makePayload: params => {\n const { label, deviceType } = params as ParamsType;\n const urlFriendlyLabel = label.replace(/ /g, \"-\").toLowerCase();\n\n return {\n category: `uk-qcp-react-${deviceType}-${urlFriendlyLabel}-view-excess-toggle`,\n action: \"view_excess_clicked\",\n label,\n property: window.location.href,\n };\n },\n },\n {\n // Quote Details Slider opened\n name: \"sliderOpened\",\n type: \"structured\",\n makePayload: params => {\n const { label } = params as ParamsType;\n\n return {\n category: \"comparison_cta\",\n action: \"quote_details_slider_opened\",\n label,\n };\n },\n },\n {\n // Coverage modal opened\n name: \"coverageModalOpened\",\n type: \"structured\",\n makePayload: params => {\n const {\n category,\n product = \"extra_coverage\",\n title,\n } = params as ParamsType;\n const productLabel = snakeCase(product);\n\n return {\n category,\n action: `${productLabel}_${snakeCase(title)}_popup_opened`,\n label: productLabel,\n property: window.location.href,\n };\n },\n },\n {\n // Toggle cover select\n name: \"coverChanged\",\n type: \"unstructured\",\n makePayload: params => {\n const { name = \"\", fromValue = \"\", toValue = \"\" } = params as ParamsType;\n // Derive data\n let action = \"change\";\n\n // This logic is taken directly from Chopin without documentation:\n // If a cover has zero value, then change the action to add or remove\n if (fromValue === \"0\") {\n action = \"add\";\n }\n if (toValue === \"0\") {\n action = \"remove\";\n }\n\n return {\n schema:\n \"iglu:com.simplybusiness/comparison_page_cover_changed/jsonschema/1-0-0\",\n data: {\n name,\n action,\n from_value: fromValue,\n to_value: toValue,\n },\n };\n },\n },\n {\n name: \"ratingsModalOpened\",\n type: \"structured\",\n makePayload: params => {\n const { category, label } = params as ParamsType;\n\n return {\n category,\n action: \"insurer_rating_help_popup_triggered\",\n label,\n property: window.location.href,\n };\n },\n },\n {\n name: \"coverToggleOpened\",\n type: \"structured\",\n makePayload: () => ({\n category: \"qcp_limit_interaction\",\n label: \"limit_interaction\",\n action: \"limit_interaction_clicked\",\n property: window.location.href,\n }),\n },\n {\n name: \"paymentToggleClicked\",\n type: \"structured\",\n makePayload: params => {\n const { category, label } = params as ParamsType;\n\n return {\n category,\n action: \"button_click\",\n label,\n property: window.location.href,\n };\n },\n },\n {\n name: \"insurerDetailsAccordionClicked\",\n type: \"structured\",\n makePayload: () => ({\n category: \"quote_details_slider_insurer_details_description\",\n action: \"accordion_clicked\",\n label: \"accordion_clicked\",\n property: window.location.href,\n }),\n },\n {\n name: \"priceDetailsPopUpOpened\",\n type: \"structured\",\n makePayload: () => ({\n category: \"price_details\",\n action: \"price_details_popup_opened\",\n label: \"Price details\",\n property: window.location.href,\n }),\n },\n {\n name: \"editLimitButtonClicked\",\n type: \"structured\",\n makePayload: () => ({\n category: \"cover_limit_changes\",\n action: \"edit_limit_button_clicked\",\n label: \"Edit Limit\",\n property: window.location.href,\n }),\n },\n {\n name: \"applyButtonClicked\",\n type: \"structured\",\n makePayload: () => ({\n category: \"cover_limit_changes\",\n action: \"apply_button_clicked\",\n label: \"Apply Button Clicked\",\n property: window.location.href,\n }),\n },\n {\n name: \"coverageInfoClicked\",\n type: \"structured\",\n makePayload: params => {\n const { deviceType } = params as ParamsType;\n\n return {\n action: \"show_coverage_info_clicked\",\n category: `uk-qcp-react-${deviceType}-show-coverage-info-toggle`,\n label: \"show_coverage_info_clicked\",\n property: window.location.href,\n };\n },\n },\n];\n"],"names":["eventDefinitions","name","type","makePayload","category","action","label","property","window","location","href","schema","data","params","deviceType","urlFriendlyLabel","replace","toLowerCase","product","title","productLabel","snakeCase","fromValue","toValue","from_value","to_value"],"mappings":"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"}