Skip to content

Commit

Permalink
upcoming: [M3-8328] - Add Analytics Events to Linode Create v2 (#10649)
Browse files Browse the repository at this point in the history
* send linode create event on creation

* add analytics for Create using command line

* Added changeset: Add Analytics Events to Linode Create v2

* pass form values insted of payload

* lint

* feedback @abailly-akamai

---------

Co-authored-by: Banks Nussman <[email protected]>
  • Loading branch information
bnussman-akamai and bnussman authored Jul 8, 2024
1 parent dfe0ce1 commit 22a8bcf
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

Add Analytics Events to Linode Create v2 ([#10649](https://github.com/linode/manager/pull/10649))
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { CreateLinodeRequest } from '@linode/api-v4';
import React, { useState } from 'react';
import { useFormContext } from 'react-hook-form';

import { Box } from 'src/components/Box';
import { Button } from 'src/components/Button/Button';
import { useRestrictedGlobalGrantCheck } from 'src/hooks/useRestrictedGlobalGrantCheck';
import { sendApiAwarenessClickEvent } from 'src/utilities/analytics/customEventAnalytics';
import { scrollErrorIntoView } from 'src/utilities/scrollErrorIntoView';

import { ApiAwarenessModal } from '../LinodesCreate/ApiAwarenessModal/ApiAwarenessModal';
import { getLinodeCreatePayload } from './utilities';

import type { CreateLinodeRequest } from '@linode/api-v4';

export const Actions = () => {
const [isAPIAwarenessModalOpen, setIsAPIAwarenessModalOpen] = useState(false);

Expand All @@ -24,6 +26,7 @@ export const Actions = () => {
});

const onOpenAPIAwareness = async () => {
sendApiAwarenessClickEvent('Button', 'Create Using Command Line');
if (await trigger()) {
// If validation is successful, we open the dialog.
setIsAPIAwarenessModalOpen(true);
Expand Down
19 changes: 16 additions & 3 deletions packages/manager/src/features/Linodes/LinodeCreatev2/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { isEmpty } from '@linode/api-v4';
import { useQueryClient } from '@tanstack/react-query';
import { useSnackbar } from 'notistack';
import React, { useEffect, useRef } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useHistory } from 'react-router-dom';
Expand Down Expand Up @@ -35,6 +37,7 @@ import { Marketplace } from './Tabs/Marketplace/Marketplace';
import { StackScripts } from './Tabs/StackScripts/StackScripts';
import { UserData } from './UserData/UserData';
import {
captureLinodeCreateAnalyticsEvent,
defaultValues,
defaultValuesMap,
getLinodeCreatePayload,
Expand All @@ -50,7 +53,6 @@ import type { SubmitHandler } from 'react-hook-form';

export const LinodeCreatev2 = () => {
const { params, setParams } = useLinodeCreateQueryParams();
const formRef = useRef<HTMLFormElement>(null);

const form = useForm<LinodeCreateFormValues>({
defaultValues,
Expand All @@ -60,9 +62,10 @@ export const LinodeCreatev2 = () => {
});

const history = useHistory();

const queryClient = useQueryClient();
const { mutateAsync: createLinode } = useCreateLinodeMutation();
const { mutateAsync: cloneLinode } = useCloneLinodeMutation();
const { enqueueSnackbar } = useSnackbar();

const currentTabIndex = getTabIndex(params.type);

Expand All @@ -87,6 +90,16 @@ export const LinodeCreatev2 = () => {
: await createLinode(payload);

history.push(`/linodes/${linode.id}`);

enqueueSnackbar(`Your Linode ${linode.label} is being created.`, {
variant: 'success',
});

captureLinodeCreateAnalyticsEvent({
queryClient,
type: params.type ?? 'Distributions',
values,
});
} catch (errors) {
for (const error of errors) {
if (error.field) {
Expand Down Expand Up @@ -118,7 +131,7 @@ export const LinodeCreatev2 = () => {
docsLink="https://www.linode.com/docs/guides/platform/get-started/"
title="Create"
/>
<form onSubmit={form.handleSubmit(onSubmit)} ref={formRef}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<Error />
<Stack gap={3}>
<Tabs index={currentTabIndex} onChange={onTabChange}>
Expand Down
53 changes: 53 additions & 0 deletions packages/manager/src/features/Linodes/LinodeCreatev2/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { getLinode, getStackScript } from '@linode/api-v4';
import { omit } from 'lodash';
import { useHistory } from 'react-router-dom';

import { stackscriptQueries } from 'src/queries/stackscripts';
import { sendCreateLinodeEvent } from 'src/utilities/analytics/customEventAnalytics';
import { privateIPRegex } from 'src/utilities/ipUtils';
import { getQueryParamsFromQueryString } from 'src/utilities/queryParams';

Expand All @@ -15,6 +17,7 @@ import type {
InterfacePayload,
Linode,
} from '@linode/api-v4';
import type { QueryClient } from '@tanstack/react-query';

/**
* This is the ID of the Image of the default distribution.
Expand Down Expand Up @@ -332,3 +335,53 @@ export const defaultValuesMap: Record<LinodeCreateType, CreateLinodeRequest> = {
'One-Click': defaultValuesForStackScripts,
StackScripts: defaultValuesForStackScripts,
};

interface LinodeCreateAnalyticsEventOptions {
queryClient: QueryClient;
type: LinodeCreateType;
values: LinodeCreateFormValues;
}

/**
* Captures a custom analytics event when a Linode is created.
*/
export const captureLinodeCreateAnalyticsEvent = async (
options: LinodeCreateAnalyticsEventOptions
) => {
const { queryClient, type, values } = options;

if (type === 'Backups' && values.backup_id) {
sendCreateLinodeEvent('backup', String(values.backup_id));
}

if (type === 'Clone Linode' && values.linode) {
const linodeId = values.linode.id;
// @todo use Linode query key factory when it is implemented
const linode = await queryClient.ensureQueryData({
queryFn: () => getLinode(linodeId),
queryKey: ['linodes', 'linode', linodeId, 'details'],
});

sendCreateLinodeEvent('clone', values.type, {
isLinodePoweredOff: linode.status === 'offline',
});
}

if (type === 'Distributions' || type === 'Images') {
sendCreateLinodeEvent('image', values.image ?? undefined);
}

if (type === 'StackScripts' && values.stackscript_id) {
const stackscript = await queryClient.ensureQueryData(
stackscriptQueries.stackscript(values.stackscript_id)
);
sendCreateLinodeEvent('stackscript', stackscript.label);
}

if (type === 'One-Click' && values.stackscript_id) {
const stackscript = await queryClient.ensureQueryData(
stackscriptQueries.stackscript(values.stackscript_id)
);
sendCreateLinodeEvent('one-click', stackscript.label);
}
};
2 changes: 1 addition & 1 deletion packages/manager/src/queries/stackscripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const getAllOCAsRequest = (passedParams: Params = {}) =>
getOneClickApps({ ...params, ...passedParams })
)().then((data) => data.data);

const stackscriptQueries = createQueryKeys('stackscripts', {
export const stackscriptQueries = createQueryKeys('stackscripts', {
infinite: (filter: Filter = {}) => ({
queryFn: ({ pageParam }) =>
getStackScripts({ page: pageParam, page_size: 25 }, filter),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const sendCreateNodeBalancerEvent = (eventLabel: string): void => {
// LinodeCreateContainer.tsx
export const sendCreateLinodeEvent = (
eventAction: string,
eventLabel: string,
eventLabel: string | undefined,
eventData?: CustomAnalyticsData
): void => {
sendEvent({
Expand Down

0 comments on commit 22a8bcf

Please sign in to comment.