Skip to content

Commit

Permalink
feat: add user_clicked_save to analytics_summary view (#3972)
Browse files Browse the repository at this point in the history
  • Loading branch information
RODO94 authored Nov 20, 2024
1 parent a42f8e8 commit 8b7f886
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const SaveResumeButton: React.FC = () => {

const handleClick = () => {
if (saveToEmail) {
trackEvent({ event: "saveClick", metadata: null });
trackEvent({
event: "flowDirectionChange",
metadata: null,
Expand Down
12 changes: 12 additions & 0 deletions editor.planx.uk/src/pages/FlowEditor/lib/analytics/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ export const UPDATE_HAS_CLICKED_HELP = gql`
}
`;

export const UPDATE_HAS_CLICKED_SAVE = gql`
mutation UpdateHasClickedSave($id: bigint!, $metadata: jsonb = {}) {
update_analytics_logs_by_pk(
pk_columns: { id: $id }
_set: { has_clicked_save: true }
_append: { metadata: $metadata }
) {
id
}
}
`;

export const UPDATE_ANALYTICS_LOG_METADATA = gql`
mutation UpdateAnalyticsLogMetadata($id: bigint!, $metadata: jsonb = {}) {
update_analytics_logs_by_pk(
Expand Down
12 changes: 8 additions & 4 deletions editor.planx.uk/src/pages/FlowEditor/lib/analytics/provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
UPDATE_ANALYTICS_LOG_METADATA,
UPDATE_FLOW_DIRECTION,
UPDATE_HAS_CLICKED_HELP,
UPDATE_HAS_CLICKED_SAVE,
UPDATE_NEXT_LOG_CREATED_AT,
} from "./mutations";
import {
Expand Down Expand Up @@ -256,7 +257,7 @@ export const AnalyticsProvider: React.FC<{ children: React.ReactNode }> = ({
return !shouldTrackAnalytics || !lastVisibleNodeAnalyticsLogId;
}

async function updateMetadata(mutation: DocumentNode, metadata: Metadata) {
async function updateMetadata(mutation: DocumentNode, metadata?: Metadata) {
await publicClient.mutate({
mutation: mutation,
variables: {
Expand All @@ -268,14 +269,17 @@ export const AnalyticsProvider: React.FC<{ children: React.ReactNode }> = ({

async function trackEvent(eventData: EventData) {
if (shouldSkipTracking()) return;
const { event, metadata } = eventData;
const { event } = eventData;
switch (event) {
case "helpClick":
updateMetadata(UPDATE_HAS_CLICKED_HELP, metadata);
updateMetadata(UPDATE_HAS_CLICKED_HELP, eventData.metadata);
return;
case "saveClick":
updateMetadata(UPDATE_HAS_CLICKED_SAVE);
return;
case "nextStepsClick":
case "helpTextFeedback":
updateMetadata(UPDATE_ANALYTICS_LOG_METADATA, metadata);
updateMetadata(UPDATE_ANALYTICS_LOG_METADATA, eventData.metadata);
return;
case "backwardsNavigation": {
const { initiator, nodeId } = eventData;
Expand Down
14 changes: 13 additions & 1 deletion editor.planx.uk/src/pages/FlowEditor/lib/analytics/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ export type EventData =
| BackwardsNavigation
| FlowDirectionChange
| InputErrors
| HelpTextFeedback;
| HelpTextFeedback
| SaveClick;

/**
* Capture when a user clicks on the `More Information` i.e. the help on a
Expand All @@ -108,6 +109,17 @@ type HelpClick = {
metadata: HelpClickMetadata;
};

/**
* Captured when a user clicks Save and Return.
* The mutation sets the "has_clicked_help: true" when Save and
* Return button is clicked
*/

type SaveClick = {
event: "saveClick";
metadata: null;
};

/**
* A user gets to a `NextSteps` component. Track every time a user selects a
* link and appends it to the array.
Expand Down
2 changes: 2 additions & 0 deletions hasura.planx.uk/metadata/tables.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
- created_at
- flow_direction
- has_clicked_help
- has_clicked_save
- id
- input_errors
- metadata
Expand All @@ -79,6 +80,7 @@
- allow_list_answers
- flow_direction
- has_clicked_help
- has_clicked_save
- input_errors
- metadata
- next_log_created_at
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
alter table "public"."analytics_logs" drop column "has_clicked_save";

CREATE OR REPLACE VIEW "public"."analytics_summary" AS
SELECT a.id AS analytics_id,
al.id AS analytics_log_id,
f.slug AS service_slug,
t.slug AS team_slug,
a.type AS analytics_type,
al.created_at AS analytics_log_created_at,
a.created_at AS analytics_created_at,
((a.user_agent -> 'os'::text) ->> 'name'::text) AS operating_system,
((a.user_agent -> 'browser'::text) ->> 'name'::text) AS browser,
((a.user_agent -> 'platform'::text) ->> 'type'::text) AS platform,
a.referrer,
al.flow_direction,
(al.metadata ->> 'change'::text) AS change_metadata,
(al.metadata ->> 'back'::text) AS back_metadata,
(al.metadata ->> 'selectedUrls'::text) AS selected_urls,
(al.metadata ->> 'flag'::text) AS result_flag,
((al.metadata -> 'flagSet'::text))::text AS result_flagset,
((al.metadata -> 'displayText'::text) ->> 'heading'::text) AS result_heading,
((al.metadata -> 'displayText'::text) ->> 'description'::text) AS result_description,
((al.metadata -> 'helpTextUseful'::text))::text AS help_text_useful,
CASE
WHEN al.has_clicked_help THEN al.metadata
ELSE NULL::jsonb
END AS help_metadata,
al.user_exit AS is_user_exit,
al.node_type,
al.node_title,
al.has_clicked_help,
al.input_errors,
(date_part('epoch'::text, (al.next_log_created_at - al.created_at)))::numeric(10,1) AS time_spent_on_node_seconds,
a.ended_at AS analytics_ended_at,
((date_part('epoch'::text, (a.ended_at - a.created_at)) / (60)::double precision))::numeric(10,1) AS time_spent_on_analytics_session_minutes,
al.node_id,
al.allow_list_answers,
((al.allow_list_answers -> 'proposal.projectType'::text))::text AS proposal_project_type,
((al.allow_list_answers -> 'application.declaration.connection'::text))::text AS application_declaration_connection,
((al.allow_list_answers -> 'property.type'::text))::text AS property_type,
((al.allow_list_answers -> 'drawBoundary.action'::text))::text AS draw_boundary_action,
((al.allow_list_answers -> 'user.role'::text))::text AS user_role,
((al.allow_list_answers -> 'property.constraints.planning'::text))::text AS property_constraints_planning,
((al.allow_list_answers -> 'findProperty.action'::text))::text AS find_property_action,
((al.allow_list_answers -> 'usedFOIYNPP'::text))::text AS used_foiynpp,
((al.allow_list_answers -> 'propertyInformation.action'::text))::text AS property_information_action,
((al.allow_list_answers -> 'planningConstraints.action'::text))::text AS planning_constraints_action,
((al.allow_list_answers -> '_overrides'::text))::text AS overrides,
((al.allow_list_answers -> 'rab.exitReason'::text))::text AS rab_exit_reason,
((al.allow_list_answers -> 'service.type'::text))::text AS pre_app_service_type,
((al.allow_list_answers -> 'application.information.harmful'::text))::text AS pre_app_harmful_info,
((al.allow_list_answers -> 'application.information.sensitive'::text))::text AS pre_app_sensitive_info,
al.allow_list_answers -> 'application.type' ->> 0 AS application_type,
((al.allow_list_answers -> '_feedback') ->> 'feedbackScore'::text)::int AS feedback_score,
al.allow_list_answers -> 'applicant.researchOptIn' ->> 0 AS applicant_research_opt_in
FROM (((analytics a
LEFT JOIN analytics_logs al ON ((a.id = al.analytics_id)))
LEFT JOIN flows f ON ((a.flow_id = f.id)))
LEFT JOIN teams t ON ((t.id = f.team_id)));

GRANT SELECT ON "public"."analytics_summary" TO metabase_read_only;
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
alter table "public"."analytics_logs" add column "has_clicked_save" boolean
null default 'false';

CREATE OR REPLACE VIEW "public"."analytics_summary" AS
SELECT a.id AS analytics_id,
al.id AS analytics_log_id,
f.slug AS service_slug,
t.slug AS team_slug,
a.type AS analytics_type,
al.created_at AS analytics_log_created_at,
a.created_at AS analytics_created_at,
((a.user_agent -> 'os'::text) ->> 'name'::text) AS operating_system,
((a.user_agent -> 'browser'::text) ->> 'name'::text) AS browser,
((a.user_agent -> 'platform'::text) ->> 'type'::text) AS platform,
a.referrer,
al.flow_direction,
(al.metadata ->> 'change'::text) AS change_metadata,
(al.metadata ->> 'back'::text) AS back_metadata,
(al.metadata ->> 'selectedUrls'::text) AS selected_urls,
(al.metadata ->> 'flag'::text) AS result_flag,
((al.metadata -> 'flagSet'::text))::text AS result_flagset,
((al.metadata -> 'displayText'::text) ->> 'heading'::text) AS result_heading,
((al.metadata -> 'displayText'::text) ->> 'description'::text) AS result_description,
((al.metadata -> 'helpTextUseful'::text))::text AS help_text_useful,
CASE
WHEN al.has_clicked_help THEN al.metadata
ELSE NULL::jsonb
END AS help_metadata,
al.user_exit AS is_user_exit,
al.node_type,
al.node_title,
al.has_clicked_help,
al.input_errors,
(date_part('epoch'::text, (al.next_log_created_at - al.created_at)))::numeric(10,1) AS time_spent_on_node_seconds,
a.ended_at AS analytics_ended_at,
((date_part('epoch'::text, (a.ended_at - a.created_at)) / (60)::double precision))::numeric(10,1) AS time_spent_on_analytics_session_minutes,
al.node_id,
al.allow_list_answers,
((al.allow_list_answers -> 'proposal.projectType'::text))::text AS proposal_project_type,
((al.allow_list_answers -> 'application.declaration.connection'::text))::text AS application_declaration_connection,
((al.allow_list_answers -> 'property.type'::text))::text AS property_type,
((al.allow_list_answers -> 'drawBoundary.action'::text))::text AS draw_boundary_action,
((al.allow_list_answers -> 'user.role'::text))::text AS user_role,
((al.allow_list_answers -> 'property.constraints.planning'::text))::text AS property_constraints_planning,
((al.allow_list_answers -> 'findProperty.action'::text))::text AS find_property_action,
((al.allow_list_answers -> 'usedFOIYNPP'::text))::text AS used_foiynpp,
((al.allow_list_answers -> 'propertyInformation.action'::text))::text AS property_information_action,
((al.allow_list_answers -> 'planningConstraints.action'::text))::text AS planning_constraints_action,
((al.allow_list_answers -> '_overrides'::text))::text AS overrides,
((al.allow_list_answers -> 'rab.exitReason'::text))::text AS rab_exit_reason,
((al.allow_list_answers -> 'service.type'::text))::text AS pre_app_service_type,
((al.allow_list_answers -> 'application.information.harmful'::text))::text AS pre_app_harmful_info,
((al.allow_list_answers -> 'application.information.sensitive'::text))::text AS pre_app_sensitive_info,
al.allow_list_answers -> 'application.type' ->> 0 AS application_type,
((al.allow_list_answers -> '_feedback') ->> 'feedbackScore'::text)::int AS feedback_score,
al.allow_list_answers -> 'applicant.researchOptIn' ->> 0 AS applicant_research_opt_in,
al.has_clicked_save
FROM (((analytics a
LEFT JOIN analytics_logs al ON ((a.id = al.analytics_id)))
LEFT JOIN flows f ON ((a.flow_id = f.id)))
LEFT JOIN teams t ON ((t.id = f.team_id)));

GRANT SELECT ON "public"."analytics_summary" TO metabase_read_only;

0 comments on commit 8b7f886

Please sign in to comment.