diff --git a/editor.planx.uk/package.json b/editor.planx.uk/package.json index 326a421c10..b6206f9086 100644 --- a/editor.planx.uk/package.json +++ b/editor.planx.uk/package.json @@ -40,6 +40,7 @@ "@turf/helpers": "^6.5.0", "array-move": "^4.0.0", "axios": "0.27.2", + "bowser": "^2.11.0", "camelcase-keys": "^9.0.0", "classnames": "^2.3.2", "core-js": "^3.31.0", diff --git a/editor.planx.uk/pnpm-lock.yaml b/editor.planx.uk/pnpm-lock.yaml index 093c67f9df..476a46a288 100644 --- a/editor.planx.uk/pnpm-lock.yaml +++ b/editor.planx.uk/pnpm-lock.yaml @@ -123,6 +123,9 @@ dependencies: axios: specifier: 0.27.2 version: 0.27.2 + bowser: + specifier: ^2.11.0 + version: 2.11.0 camelcase-keys: specifier: ^9.0.0 version: 9.0.0 @@ -9572,6 +9575,10 @@ packages: /boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + /bowser@2.11.0: + resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + dev: false + /bplist-parser@0.2.0: resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} engines: {node: '>= 5.10.0'} diff --git a/editor.planx.uk/src/pages/FlowEditor/lib/analyticsProvider.tsx b/editor.planx.uk/src/pages/FlowEditor/lib/analyticsProvider.tsx index f2ba6ed71f..4aa54474cd 100644 --- a/editor.planx.uk/src/pages/FlowEditor/lib/analyticsProvider.tsx +++ b/editor.planx.uk/src/pages/FlowEditor/lib/analyticsProvider.tsx @@ -5,6 +5,7 @@ import { FlagSet, } from "@opensystemslab/planx-core/types"; import { TYPES } from "@planx/components/types"; +import Bowser from "bowser"; import { publicClient } from "lib/graphql"; import React, { createContext, useContext, useEffect, useState } from "react"; @@ -129,7 +130,7 @@ export const AnalyticsProvider: React.FC<{ children: React.ReactNode }> = ({ async function track(direction: AnalyticsLogDirection, analyticsId: number) { const metadata = getNodeMetadata(); - const node_title = + const nodeTitle = node?.type === TYPES.Content ? getContentTitle(node) : node?.data?.title ?? node?.data?.text ?? node?.data?.flagSet; @@ -138,7 +139,7 @@ export const AnalyticsProvider: React.FC<{ children: React.ReactNode }> = ({ direction, analyticsId, metadata, - node_title, + nodeTitle, ); const id = result?.data.insert_analytics_logs_one?.id; const newLogCreatedAt = result?.data.insert_analytics_logs_one?.created_at; @@ -156,7 +157,7 @@ export const AnalyticsProvider: React.FC<{ children: React.ReactNode }> = ({ direction: AnalyticsLogDirection, analyticsId: number, metadata: NodeMetadata, - node_title: string, + nodeTitle: string, ) { const result = await publicClient.mutate({ mutation: gql` @@ -166,6 +167,7 @@ export const AnalyticsProvider: React.FC<{ children: React.ReactNode }> = ({ $metadata: jsonb $node_type: Int $node_title: String + $user_agent: jsonb ) { insert_analytics_logs_one( object: { @@ -187,7 +189,7 @@ export const AnalyticsProvider: React.FC<{ children: React.ReactNode }> = ({ analytics_id: analyticsId, metadata: metadata, node_type: node?.type, - node_title: node_title, + node_title: nodeTitle, }, }); return result; @@ -287,10 +289,25 @@ export const AnalyticsProvider: React.FC<{ children: React.ReactNode }> = ({ async function createAnalytics(type: AnalyticsType) { if (shouldTrackAnalytics) { + const userAgent = Bowser.parse(window.navigator.userAgent); + const referrer = document.referrer || null; + const response = await publicClient.mutate({ mutation: gql` - mutation InsertNewAnalytics($type: String, $flow_id: uuid) { - insert_analytics_one(object: { type: $type, flow_id: $flow_id }) { + mutation InsertNewAnalytics( + $type: String + $flow_id: uuid + $user_agent: jsonb + $referrer: String + ) { + insert_analytics_one( + object: { + type: $type + flow_id: $flow_id + user_agent: $user_agent + referrer: $referrer + } + ) { id } } @@ -298,6 +315,8 @@ export const AnalyticsProvider: React.FC<{ children: React.ReactNode }> = ({ variables: { type, flow_id: flowId, + user_agent: userAgent, + referrer, }, }); const id = response.data.insert_analytics_one.id; diff --git a/hasura.planx.uk/metadata/tables.yaml b/hasura.planx.uk/metadata/tables.yaml index f4d1793f57..e3fb973ab0 100644 --- a/hasura.planx.uk/metadata/tables.yaml +++ b/hasura.planx.uk/metadata/tables.yaml @@ -9,7 +9,9 @@ - created_at - flow_id - id + - referrer - type + - user_agent select_permissions: - role: public permission: diff --git a/hasura.planx.uk/migrations/1698350858952_alter_table_public_analytics_logs_add_column_user_agent/down.sql b/hasura.planx.uk/migrations/1698350858952_alter_table_public_analytics_logs_add_column_user_agent/down.sql new file mode 100644 index 0000000000..deae24b750 --- /dev/null +++ b/hasura.planx.uk/migrations/1698350858952_alter_table_public_analytics_logs_add_column_user_agent/down.sql @@ -0,0 +1,3 @@ +ALTER TABLE "public"."analytics" DROP COLUMN "referrer" + +ALTER TABLE "public"."analytics" DROP COLUMN "user_agent" \ No newline at end of file diff --git a/hasura.planx.uk/migrations/1698350858952_alter_table_public_analytics_logs_add_column_user_agent/up.sql b/hasura.planx.uk/migrations/1698350858952_alter_table_public_analytics_logs_add_column_user_agent/up.sql new file mode 100644 index 0000000000..a5a449ae17 --- /dev/null +++ b/hasura.planx.uk/migrations/1698350858952_alter_table_public_analytics_logs_add_column_user_agent/up.sql @@ -0,0 +1,5 @@ +alter table "public"."analytics" add column "user_agent" jsonb + null default '{}'; + +alter table "public"."analytics" add column "referrer" text + null; \ No newline at end of file