Feat/add studio events (#33148)

* add tracking for help, feedback, import data, and example clicked

* clarify www pricing plan and add run sql query event

* add pricing plan cta tracking

* Add one more event to Import data from CSV

* Consistent copy

* Clean up and refactors

* Some fixes

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
Pamela ChiaandJoshen Lim authored and GitHub committed 2025-02-03 20:08:30 +08:00
1 parent b6aa2af832
commit b6cefe5c25
15 files changed
+358 -64

No files matched your search

@@ -4,6 +4,7 @@ import { forwardRef, useRef } from 'react'
import DataGrid, { DataGridHandle, RowsChangeData } from 'react-data-grid'
import { memo } from 'react-tracked'
import { TelemetryActions } from 'common/telemetry-constants'
import { formatClipboardValue } from 'components/grid/utils/common'
import { TableGridInnerLoadingState } from 'components/interfaces/TableGridEditor/LoadingState'
import { formatForeignKeys } from 'components/interfaces/TableGridEditor/SidePanelEditor/ForeignKeySelector/ForeignKeySelector.utils'
@@ -11,6 +12,8 @@ import { ForeignRowSelectorProps } from 'components/interfaces/TableGridEditor/S
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import AlertError from 'components/ui/AlertError'
import { useForeignKeyConstraintsQuery } from 'data/database/foreign-key-constraints-query'
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
import { useUrlState } from 'hooks/ui/useUrlState'
import { copyToClipboard } from 'lib/helpers'
import { Button, cn } from 'ui'
@@ -133,6 +136,8 @@ export const Grid = memo(
const table = state.table
const { mutate: sendEvent } = useSendEventMutation()
const org = useSelectedOrganization()
const { project } = useProjectContext()
const { data } = useForeignKeyConstraintsQuery({
projectRef: project?.ref,
@@ -214,8 +219,21 @@ export const Grid = memo(
</p>
<div className="flex items-center space-x-2 mt-4">
{onAddRow !== undefined && onImportData !== undefined && (
<Button type="default" onClick={onImportData}>
Import data via CSV
<Button
type="default"
onClick={() => {
onImportData()
sendEvent({
action: TelemetryActions.IMPORT_DATA_BUTTON_CLICKED,
properties: { tableType: 'Existing Table' },
groups: {
project: project?.ref ?? 'Unknown',
organization: org?.slug ?? 'Unknown',
},
})
}}
>
Import data from CSV
</Button>
)}
</div>
@@ -1,10 +1,13 @@
import { PermissionAction } from '@supabase/shared-types/out/constants'
import saveAs from 'file-saver'
import { ArrowUp, ChevronDown, FileText, Trash } from 'lucide-react'
import Link from 'next/link'
import Papa from 'papaparse'
import { ReactNode, useState } from 'react'
import { toast } from 'sonner'
import { useParams } from 'common'
import { TelemetryActions } from 'common/telemetry-constants'
import { useDispatch, useTrackedState } from 'components/grid/store/Store'
import type { Filter, Sort, SupaTable } from 'components/grid/types'
import { formatTableRowsToSQL } from 'components/interfaces/TableGridEditor/TableEntity.utils'
@@ -12,7 +15,9 @@ import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectConte
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
import { useTableRowsCountQuery } from 'data/table-rows/table-rows-count-query'
import { fetchAllTableRows, useTableRowsQuery } from 'data/table-rows/table-rows-query'
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
import { useCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
import { useUrlState } from 'hooks/ui/useUrlState'
import {
useRoleImpersonationStateSnapshot,
@@ -30,7 +35,6 @@ import {
} from 'ui'
import FilterPopover from './filter/FilterPopover'
import { SortPopover } from './sort'
import Link from 'next/link'
// [Joshen] CSV exports require this guard as a fail-safe if the table is
// just too large for a browser to keep all the rows in memory before
@@ -105,6 +109,9 @@ type DefaultHeaderProps = {
onImportData?: () => void
}
const DefaultHeader = ({ table, onAddColumn, onAddRow, onImportData }: DefaultHeaderProps) => {
const { ref } = useParams()
const org = useSelectedOrganization()
const canAddNew = onAddRow !== undefined || onAddColumn !== undefined
// [Joshen] Using this logic to block both column and row creation/update/delete
@@ -114,6 +121,8 @@ const DefaultHeader = ({ table, onAddColumn, onAddRow, onImportData }: DefaultHe
arrayKeys: ['sort', 'filter'],
})
const { mutate: sendEvent } = useSendEventMutation()
return (
<div className="flex items-center gap-4">
<div className="flex items-center gap-2">
@@ -195,7 +204,17 @@ const DefaultHeader = ({ table, onAddColumn, onAddRow, onImportData }: DefaultHe
<DropdownMenuItem
key="import-data"
className="group space-x-2"
onClick={onImportData}
onClick={() => {
onImportData()
sendEvent({
action: TelemetryActions.IMPORT_DATA_BUTTON_CLICKED,
properties: { tableType: 'Existing Table' },
groups: {
project: ref ?? 'Unknown',
organization: org?.slug ?? 'Unknown',
},
})
}}
>
<div className="relative -mt-2">
<FileText
@@ -1,8 +1,13 @@
import { BASE_PATH } from 'lib/constants'
import { ChevronRight } from 'lucide-react'
import { useTheme } from 'next-themes'
import Link from 'next/link'
import { useParams } from 'common'
import { TelemetryActions } from 'common/telemetry-constants'
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
import { BASE_PATH } from 'lib/constants'
interface ExampleProjectProps {
framework: string
title: string
@@ -12,9 +17,24 @@ interface ExampleProjectProps {
const ExampleProject = ({ framework, title, description, url }: ExampleProjectProps) => {
const { resolvedTheme } = useTheme()
const { ref: projectRef } = useParams()
const org = useSelectedOrganization()
const { mutate: sendEvent } = useSendEventMutation()
return (
<Link href={url} target="_blank" rel="noreferrer">
<Link
href={url}
target="_blank"
rel="noreferrer"
onClick={() =>
sendEvent({
action: TelemetryActions.EXAMPLE_PROJECT_CARD_CLICKED,
properties: { cardTitle: title },
groups: { project: projectRef ?? 'Unknown', organization: org?.slug ?? 'Unknown' },
})
}
>
<div
className={[
'group relative',
@@ -1,5 +1,9 @@
import { Check } from 'lucide-react'
import { TelemetryActions } from 'common/telemetry-constants'
import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query'
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
import { PricingInformation } from 'shared-data'
import { pickFeatures } from 'shared-data/plans'
import { Button, cn } from 'ui'
@@ -10,8 +14,15 @@ export interface EnterpriseCardProps {
billingPartner: 'fly' | 'aws' | 'vercel_marketplace' | undefined
}
const EnterpriseCard = ({ plan, isCurrentPlan, billingPartner }: EnterpriseCardProps) => {
export const EnterpriseCard = ({ plan, isCurrentPlan, billingPartner }: EnterpriseCardProps) => {
const selectedOrganization = useSelectedOrganization()
const orgSlug = selectedOrganization?.slug
const features = pickFeatures(plan, billingPartner)
const { data: subscription } = useOrgSubscriptionQuery({ orgSlug })
const currentPlan = subscription?.plan.name
const { mutate: sendEvent } = useSendEventMutation()
return (
<div
@@ -37,11 +48,23 @@ const EnterpriseCard = ({ plan, isCurrentPlan, billingPartner }: EnterpriseCardP
<p className="text-sm mt-2 mb-4">{plan.description}</p>
<a href={plan.href} className="hidden md:block" target="_blank">
<Button block type="default" size="tiny">
<Button
block
asChild
type="default"
size="tiny"
onClick={() =>
sendEvent({
action: TelemetryActions.STUDIO_PRICING_PLAN_CTA_CLICKED,
properties: { selectedPlan: 'Enterprise', currentPlan },
groups: { organization: orgSlug ?? 'Unknown' },
})
}
>
<a href={plan.href} className="hidden md:block" target="_blank">
{plan.cta}
</Button>
</a>
</a>
</Button>
</div>
<div className="flex flex-col justify-center col-span-2 px-4 md:px-0">
@@ -62,14 +85,24 @@ const EnterpriseCard = ({ plan, isCurrentPlan, billingPartner }: EnterpriseCardP
))}
</ul>
<a href={plan.href} className="visible md:hidden mt-8" target="_blank">
<Button block type="default" size="tiny">
<Button
block
asChild
type="default"
size="tiny"
onClick={() =>
sendEvent({
action: TelemetryActions.STUDIO_PRICING_PLAN_CTA_CLICKED,
properties: { selectedPlan: 'Enterprise', currentPlan },
groups: { organization: orgSlug ?? 'Unknown' },
})
}
>
<a href={plan.href} className="visible md:hidden mt-8" target="_blank">
{plan.cta}
</Button>
</a>
</a>
</Button>
</div>
</div>
)
}
export default EnterpriseCard
@@ -7,6 +7,7 @@ import { useRouter } from 'next/router'
import { useEffect, useRef, useState } from 'react'
import { toast } from 'sonner'
import { TelemetryActions } from 'common/telemetry-constants'
import { billingPartnerLabel } from 'components/interfaces/Billing/Subscription/Subscription.utils'
import Table from 'components/to-be-cleaned/Table'
import AlertError from 'components/ui/AlertError'
@@ -22,6 +23,7 @@ import { useOrgPlansQuery } from 'data/subscriptions/org-plans-query'
import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query'
import { useOrgSubscriptionUpdateMutation } from 'data/subscriptions/org-subscription-update-mutation'
import type { OrgPlan, SubscriptionTier } from 'data/subscriptions/types'
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
import { useCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
import { useFlag } from 'hooks/ui/useFlag'
@@ -31,7 +33,7 @@ import { pickFeatures, pickFooter, plans as subscriptionsPlans } from 'shared-da
import { useOrgSettingsPageStateSnapshot } from 'state/organization-settings'
import { Button, Modal, SidePanel, cn } from 'ui'
import DowngradeModal from './DowngradeModal'
import EnterpriseCard from './EnterpriseCard'
import { EnterpriseCard } from './EnterpriseCard'
import ExitSurveyModal from './ExitSurveyModal'
import MembersExceedLimitModal from './MembersExceedLimitModal'
import PaymentMethodSelection from './PaymentMethodSelection'
@@ -41,6 +43,7 @@ const PlanUpdateSidePanel = () => {
const router = useRouter()
const selectedOrganization = useSelectedOrganization()
const slug = selectedOrganization?.slug
const { mutate: sendEvent } = useSendEventMutation()
const queryClient = useQueryClient()
const originalPlanRef = useRef<string>()
@@ -260,7 +263,17 @@ const PlanUpdateSidePanel = () => {
hasOrioleProjects ||
!canUpdateSubscription
}
onClick={() => setSelectedTier(plan.id as any)}
onClick={() => {
setSelectedTier(plan.id as any)
sendEvent({
action: TelemetryActions.STUDIO_PRICING_PLAN_CTA_CLICKED,
properties: {
selectedPlan: plan.name,
currentPlan: subscription?.plan?.name,
},
groups: { organization: slug ?? 'Unknown' },
})
}}
tooltip={{
content: {
side: 'bottom',
@@ -316,6 +316,11 @@ export const SQLEditor = () => {
throw error
},
})
sendEvent({
action: TelemetryActions.SQL_EDITOR_QUERY_RUN_BUTTON_CLICKED,
groups: { project: ref ?? 'Unknown', organization: org?.slug ?? 'Unknown' },
})
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
@@ -13,7 +13,9 @@ import { toast } from 'sonner'
import { useParams } from 'common'
import { RoleImpersonationPopover } from 'components/interfaces/RoleImpersonationSelector'
import DatabaseSelector from 'components/ui/DatabaseSelector'
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage'
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
import { IS_PLATFORM, LOCAL_STORAGE_KEYS } from 'lib/constants'
import { detectOS } from 'lib/helpers'
import { useSqlEditorV2StateSnapshot } from 'state/sql-editor-v2'
@@ -51,6 +53,9 @@ const UtilityActions = ({
const os = detectOS()
const { ref } = useParams()
const snapV2 = useSqlEditorV2StateSnapshot()
const org = useSelectedOrganization()
const { mutate: sendEvent } = useSendEventMutation()
const [isAiOpen] = useLocalStorageQuery(LOCAL_STORAGE_KEYS.SQL_EDITOR_AI_OPEN, true)
const [intellisenseEnabled, setIntellisenseEnabled] = useLocalStorageQuery(
@@ -191,7 +196,7 @@ const UtilityActions = ({
/>
<RoleImpersonationPopover serviceRoleLabel="postgres" variant="connected-on-both" />
<Button
onClick={() => executeQuery()}
onClick={executeQuery}
disabled={isDisabled || isExecuting}
type="primary"
size="tiny"
@@ -1,8 +1,8 @@
import { FileText, Loader } from 'lucide-react'
import { DragEvent, useRef, useState } from 'react'
import { Button } from 'ui'
import SparkBar from 'components/ui/SparkBar'
import { FileText, Loader } from 'lucide-react'
import { Button } from 'ui'
interface SpreadSheetFileUploadProps {
parseProgress: number
@@ -5,6 +5,10 @@ import Link from 'next/link'
import { useCallback, useEffect, useState } from 'react'
import { toast } from 'sonner'
import { useParams } from 'common'
import { TelemetryActions } from 'common/telemetry-constants'
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
import { Button, SidePanel, Tabs } from 'ui'
import ActionBar from '../ActionBar'
import type { ImportContent } from '../TableEditor/TableEditor.types'
@@ -43,11 +47,8 @@ const SpreadsheetImport = ({
closePanel,
updateEditorDirty = noop,
}: SpreadsheetImportProps) => {
useEffect(() => {
if (visible && headers.length === 0) {
resetSpreadsheetImport()
}
}, [visible])
const { ref: projectRef } = useParams()
const org = useSelectedOrganization()
const [tab, setTab] = useState<'fileUpload' | 'pasteText'>('fileUpload')
const [input, setInput] = useState<string>('')
@@ -62,6 +63,8 @@ const SpreadsheetImport = ({
const [errors, setErrors] = useState<any>([])
const [selectedHeaders, setSelectedHeaders] = useState<string[]>([])
const { mutate: sendEvent } = useSendEventMutation()
const selectedTableColumns = (selectedTable?.columns ?? []).map((column) => column.name)
const incompatibleHeaders = selectedHeaders.filter(
(header) => !selectedTableColumns.includes(header)
@@ -168,9 +171,17 @@ const SpreadsheetImport = ({
resolve()
} else {
saveContent({ file: uploadedFile, ...spreadsheetData, selectedHeaders, resolve })
sendEvent({
action: TelemetryActions.IMPORT_DATA_ADDED,
groups: { project: projectRef ?? 'Unknown', organization: org?.slug ?? 'Unknown' },
})
}
}
useEffect(() => {
if (visible && headers.length === 0) resetSpreadsheetImport()
}, [visible])
return (
<SidePanel
size="large"
@@ -9,8 +9,12 @@ import {
DroppableProvided,
} from 'react-beautiful-dnd'
import { useParams } from 'common'
import { TelemetryActions } from 'common/telemetry-constants'
import InformationBox from 'components/ui/InformationBox'
import type { EnumeratedType } from 'data/enumerated-types/enumerated-types-query'
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
import {
AlertDescription_Shadcn_,
AlertTitle_Shadcn_,
@@ -54,10 +58,15 @@ const ColumnManagement = ({
onClearImportContent = noop,
onUpdateFkRelations,
}: ColumnManagementProps) => {
const { ref: projectRef } = useParams()
const org = useSelectedOrganization()
const [open, setOpen] = useState(false)
const [selectedColumn, setSelectedColumn] = useState<ColumnField>()
const [selectedFk, setSelectedFk] = useState<ForeignKey>()
const { mutate: sendEvent } = useSendEventMutation()
const hasImportContent = !isEmpty(importContent)
const [primaryKeyColumns, otherColumns] = partition(
columns,
@@ -156,8 +165,21 @@ const ColumnManagement = ({
</Button>
</div>
) : (
<Button type="default" onClick={onSelectImportData}>
Import data via spreadsheet
<Button
type="default"
onClick={() => {
onSelectImportData()
sendEvent({
action: TelemetryActions.IMPORT_DATA_BUTTON_CLICKED,
properties: { tableType: 'New Table' },
groups: {
project: projectRef ?? 'Unknown',
organization: org?.slug ?? 'Unknown',
},
})
}}
>
Import data from CSV
</Button>
)}
</>
@@ -4,6 +4,13 @@ import Link from 'next/link'
import { useRouter } from 'next/router'
import { ChangeEvent, useEffect, useRef, useState } from 'react'
import { toast } from 'sonner'
import { useParams } from 'common'
import { TelemetryActions } from 'common/telemetry-constants'
import { useSendFeedbackMutation } from 'data/feedback/feedback-send'
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
import { timeout } from 'lib/helpers'
import {
Button,
DropdownMenu,
@@ -12,10 +19,6 @@ import {
DropdownMenuTrigger,
Input,
} from 'ui'
import { useParams } from 'common'
import { useSendFeedbackMutation } from 'data/feedback/feedback-send'
import { timeout } from 'lib/helpers'
import { convertB64toBlob, uploadAttachment } from './FeedbackDropdown.utils'
interface FeedbackWidgetProps {
@@ -38,11 +41,14 @@ const FeedbackWidget = ({
const router = useRouter()
const { ref, slug } = useParams()
const org = useSelectedOrganization()
const uploadButtonRef = useRef(null)
const [isSending, setSending] = useState(false)
const [isSavingScreenshot, setIsSavingScreenshot] = useState(false)
const { mutate: sendEvent } = useSendEventMutation()
const { mutate: submitFeedback } = useSendFeedbackMutation({
onSuccess: () => {
setFeedback('')
@@ -261,7 +267,17 @@ const FeedbackWidget = ({
accept="image/png"
onChange={onFilesUpload}
/>
<Button disabled={isSending} loading={isSending} onClick={sendFeedback}>
<Button
disabled={feedback.length === 0 || isSending}
loading={isSending}
onClick={() => {
sendFeedback()
sendEvent({
action: TelemetryActions.SEND_FEEDBACK_BUTTON_CLICKED,
groups: { project: ref, organization: org?.slug },
})
}}
>
Send feedback
</Button>
</div>
@@ -4,7 +4,10 @@ import Link from 'next/link'
import { useRouter } from 'next/router'
import SVG from 'react-inlinesvg'
import { TelemetryActions } from 'common/telemetry-constants'
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
import { useSelectedOrganization } from 'hooks/misc/useSelectedOrganization'
import {
Button,
Popover,
@@ -17,6 +20,10 @@ import { useProjectContext } from '../ProjectContext'
const HelpPopover = () => {
const router = useRouter()
const { project } = useProjectContext()
const org = useSelectedOrganization()
const { mutate: sendEvent } = useSendEventMutation()
const projectRef = project?.parent_project_ref ?? router.query.ref
const supportUrl = `/support/new${projectRef ? `?ref=${projectRef}` : ''}`
@@ -29,6 +36,12 @@ const HelpPopover = () => {
className="px-1"
icon={<HelpCircle size={16} strokeWidth={1.5} className="text-foreground-light" />}
tooltip={{ content: { side: 'bottom', text: 'Help' } }}
onClick={() => {
sendEvent({
action: TelemetryActions.HELP_BUTTON_CLICKED,
groups: { project: project?.ref, organization: org?.slug },
})
}}
/>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ className="w-[400px] space-y-4 p-0 py-5" align="end" side="bottom">
@@ -57,7 +57,7 @@ const MobileHeader = ({
organizations={organizations}
onClick={() =>
sendTelemetryEvent({
action: TelemetryActions.PRICING_PLAN_CTA_CLICKED,
action: TelemetryActions.WWW_PRICING_PLAN_CTA_CLICKED,
properties: {
plan,
showUpgradeText: true,
@@ -74,7 +74,7 @@ const MobileHeader = ({
href={selectedPlan.href}
onClick={() =>
sendTelemetryEvent({
action: TelemetryActions.PRICING_PLAN_CTA_CLICKED,
action: TelemetryActions.WWW_PRICING_PLAN_CTA_CLICKED,
properties: {
plan,
showUpgradeText: false,
@@ -403,7 +403,7 @@ const PricingComparisonTable = ({
organizations={organizations}
onClick={() =>
sendTelemetryEvent({
action: TelemetryActions.PRICING_PLAN_CTA_CLICKED,
action: TelemetryActions.WWW_PRICING_PLAN_CTA_CLICKED,
properties: {
plan: plan.name,
showUpgradeText: true,
@@ -425,7 +425,7 @@ const PricingComparisonTable = ({
href={plan.href}
onClick={() =>
sendTelemetryEvent({
action: TelemetryActions.PRICING_PLAN_CTA_CLICKED,
action: TelemetryActions.WWW_PRICING_PLAN_CTA_CLICKED,
properties: {
plan: plan.name,
showUpgradeText: false,
+1 -1
View File
@@ -29,7 +29,7 @@ const PricingPlans = ({ organizations, hasExistingOrganizations }: PricingPlansP
const sendPricingEvent = () => {
sendTelemetryEvent({
action: TelemetryActions.PRICING_PLAN_CTA_CLICKED,
action: TelemetryActions.WWW_PRICING_PLAN_CTA_CLICKED,
properties: {
plan: plan.name,
showUpgradeText: isUpgradablePlan && hasExistingOrganizations ? true : false,
+144 -25
View File
@@ -50,8 +50,7 @@ export enum TelemetryActions {
HOMEPAGE_HERO_REQUEST_DEMO_CLICKED = 'homepage_hero_request_demo_clicked',
HOMEPAGE_FRAMEWORK_QUICKSTART_CLICKED = 'homepage_framework_quickstart_clicked',
HOMEPAGE_PRODUCT_CARD_CLICKED = 'homepage_product_card_clicked',
PRICING_PLAN_CTA_CLICKED = 'pricing_plan_cta_clicked',
PRICING_COMPARISON_PLAN_CLICKED = 'pricing_comparison_plan_clicked',
WWW_PRICING_PLAN_CTA_CLICKED = 'www_pricing_plan_cta_clicked',
EVENT_PAGE_CTA_CLICKED = 'event_page_cta_clicked',
HOMEPAGE_GITHUB_BUTTON_CLICKED = 'homepage_github_button_clicked',
HOMEPAGE_GITHUB_DISCUSSIONS_BUTTON_CLICKED = 'homepage_github_discussions_button_clicked',
@@ -63,6 +62,14 @@ export enum TelemetryActions {
SEE_DOCUMENTATION_BUTTON_CLICKED = 'see_documentation_button_clicked',
REQUEST_DEMO_BUTTON_CLICKED = 'request_demo_button_clicked',
SIGN_IN_BUTTON_CLICKED = 'sign_in_button_clicked',
HELP_BUTTON_CLICKED = 'help_button_clicked',
SEND_FEEDBACK_BUTTON_CLICKED = 'send_feedback_button_clicked',
EXAMPLE_PROJECT_CARD_CLICKED = 'example_project_card_clicked',
IMPORT_DATA_BUTTON_CLICKED = 'import_data_button_clicked',
IMPORT_DATA_ADDED = 'import_data_added',
SQL_EDITOR_QUERY_RUN_BUTTON_CLICKED = 'sql_editor_query_run_button_clicked',
STUDIO_PRICING_PLAN_CTA_CLICKED = 'studio_pricing_plan_cta_clicked',
}
/**
@@ -734,14 +741,14 @@ export interface HomepageProductCardClickedEvent {
}
/**
* User clicked the green button on a plan in the pricing page.
* User clicked on the CTA button on a plan in the pricing page.
*
* @group Events
* @source www
* @page /pricing
*/
export interface PricingPlanCtaClickedEvent {
action: TelemetryActions.PRICING_PLAN_CTA_CLICKED
export interface WwwPricingPlanCtaClickedEvent {
action: TelemetryActions.WWW_PRICING_PLAN_CTA_CLICKED
properties: {
/**
* The plan type that was clicked.
@@ -761,24 +768,6 @@ export interface PricingPlanCtaClickedEvent {
}
}
/**
* User clicked the plan in the pricing comparison section.
*
* @group Events
* @source www
* @page /pricing
*/
export interface PricingComparisonPlanClickedEvent {
action: TelemetryActions.PRICING_COMPARISON_PLAN_CLICKED
properties: {
category: 'pricing_comparison'
/**
* The plan type that was clicked.
*/
plan: 'free' | 'pro' | 'team' | 'enterprise'
}
}
/**
* User clicked the main CTA button in an event page.
*
@@ -946,6 +935,130 @@ export interface SignInButtonClickedEvent {
}
}
/**
* User clicked the "Help" button in the top right corner of the page header.
*
* @group Events
* @source studio
*/
export interface HelpButtonClickedEvent {
action: TelemetryActions.HELP_BUTTON_CLICKED
groups: {
project?: string
organization?: string
}
}
/**
* User clicked the "Send Feedback" button in the top right corner of the page header.
*
* @group Events
* @source studio
*/
export interface SendFeedbackButtonClickedEvent {
action: TelemetryActions.SEND_FEEDBACK_BUTTON_CLICKED
groups: {
project?: string
organization?: string
}
}
/**
* User clicked on an example project card.
*
* @group Events
* @source studio
* @page /project/{ref}
*/
export interface ExampleProjectCardClickedEvent {
action: TelemetryActions.EXAMPLE_PROJECT_CARD_CLICKED
properties: {
/**
* The title of the example project card clicked.
*/
cardTitle: string
}
groups: {
project: string
organization: string
}
}
/**
* User clicked the "Import Data" button.
*
* @group Events
* @source studio
* @page /dashboard/project/{ref}/editor
*/
export interface ImportDataButtonClickedEvent {
action: TelemetryActions.IMPORT_DATA_BUTTON_CLICKED
properties: {
/**
* The type of table the data is imported to.
* New Table means added when creating new table by clicking from New table sidebar,
* Existing Table means added to an existing table by going to the table and clicking from the green Insert button..
*/
tableType: 'New Table' | 'Existing Table'
}
groups: {
project: string
organization: string
}
}
/**
* User added data from the import data via CSV/spreadsheet successfully.
*
* @group Events
* @source studio
* @page /dashboard/project/{ref}/editor
*/
export interface ImportDataAddedEvent {
action: TelemetryActions.IMPORT_DATA_ADDED
groups: {
project: string
organization: string
}
}
/**
* User clicked the run query button in the SQL editor.
*
* @group Events
* @source studio
* @page /dashboard/project/{ref}/sql/{id}
*/
export interface SqlEditorQueryRunButtonClickedEvent {
action: TelemetryActions.SQL_EDITOR_QUERY_RUN_BUTTON_CLICKED
groups: {
project: string
organization: string
}
}
/**
* User clicked on the CTA button on a plan in the pricing side panel in studio.
*
* @group Events
* @source studio
* @page /billing?panel=subscriptionPlan
*/
export interface StudioPricingPlanCtaClickedEvent {
action: TelemetryActions.STUDIO_PRICING_PLAN_CTA_CLICKED
properties: {
/**
* The plan type that was clicked.
*/
selectedPlan: string
/**
* The plan type the org is currently on.
*/
currentPlan?: string
}
groups: { organization: string }
}
export type TelemetryEvent =
| SignUpEvent
| SignInEvent
@@ -985,8 +1098,7 @@ export type TelemetryEvent =
| HomepageHeroRequestDemoClickedEvent
| HomepageFrameworkQuickstartClickedEvent
| HomepageProductCardClickedEvent
| PricingPlanCtaClickedEvent
| PricingComparisonPlanClickedEvent
| WwwPricingPlanCtaClickedEvent
| EventPageCtaClickedEvent
| HomepageGitHubButtonClickedEvent
| HomepageGitHubDiscussionsButtonClickedEvent
@@ -1000,3 +1112,10 @@ export type TelemetryEvent =
| SeeDocumentationButtonClickedEvent
| RequestDemoButtonClickedEvent
| SignInButtonClickedEvent
| HelpButtonClickedEvent
| ExampleProjectCardClickedEvent
| ImportDataButtonClickedEvent
| ImportDataAddedEvent
| SendFeedbackButtonClickedEvent
| SqlEditorQueryRunButtonClickedEvent
| StudioPricingPlanCtaClickedEvent