Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add user_clicked_save to analytics_summary view #3972

Merged
merged 9 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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 = {
RODO94 marked this conversation as resolved.
Show resolved Hide resolved
event: "saveClick";
RODO94 marked this conversation as resolved.
Show resolved Hide resolved
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;
Loading