Skip to content

Commit

Permalink
chore: adds sanity create telemetry
Browse files Browse the repository at this point in the history
  • Loading branch information
snorrees committed Oct 20, 2024
1 parent f85deb8 commit e2d3a71
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 8 deletions.
32 changes: 32 additions & 0 deletions packages/sanity/src/core/create/__telemetry__/create.telemetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {defineEvent} from '@sanity/telemetry'

export const StartInCreateClicked = defineEvent({
name: 'Start in Create clicked',
version: 1,
description: 'The "Start in Sanity Create" button is clicked.',
})

export const StartInCreateAccepted = defineEvent({
name: 'Start in Create accepted',
version: 1,
description:
'Continue in the "Start in Sanity Create" dialog was pressed, or auto-confirm was enabled.',
})

export const CreateUnlinkClicked = defineEvent({
name: 'Create Unlink clicked',
version: 1,
description: 'The Unlink action was clicked',
})

export const CreateUnlinkAccepted = defineEvent({
name: 'Create Unlink accepted',
version: 1,
description: 'User confirmed that they want the Studio document unlinked',
})

export const EditInCreateClicked = defineEvent({
name: 'Edit in Create clicked',
version: 1,
description: 'User clicked "Edit in Create"',
})
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,25 @@ import {useTranslation} from '../../i18n'
import {createLocaleNamespace} from '../i18n'
import {type CreateLinkedActionsProps} from '../types'
import {useCreateDocumentUrl} from '../useCreateDocumentUrl'
import {useSanityCreateTelemetry} from '../useSanityCreateTelemetry'
import {CreateUnlinkConfirmDialog} from './CreateUnlinkConfirmDialog'

export function CreateLinkedActions(props: CreateLinkedActionsProps) {
const {metadata, panelPortalElementId, onDocumentChange, documentTitle} = props
const {t} = useTranslation(createLocaleNamespace)
const href = useCreateDocumentUrl(metadata)

const telemetry = useSanityCreateTelemetry()

const onEditInCreateClicked = useCallback(() => telemetry.editInCreateClicked(), [telemetry])

const [unlinkConfirm, setUnlinkConfirm] = useState(false)

const confirmUnlink = useCallback(() => setUnlinkConfirm(true), [])
const confirmUnlink = useCallback(() => {
setUnlinkConfirm(true)
telemetry.unlinkClicked()
}, [telemetry])

const cancelUnlink = useCallback(() => setUnlinkConfirm(false), [])
return (
<Flex gap={2}>
Expand All @@ -27,6 +36,7 @@ export function CreateLinkedActions(props: CreateLinkedActionsProps) {
mode="ghost"
paddingY={3}
href={href}
onClick={onEditInCreateClicked}
/>
<Button text={t('unlink-from-create-button.text')} paddingY={3} onClick={confirmUnlink} />
{unlinkConfirm && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {Button, Dialog} from '../../../ui-components'
import {PatchEvent, unset} from '../../form'
import {Translate, useTranslation} from '../../i18n'
import {createLocaleNamespace} from '../i18n'
import {useSanityCreateTelemetry} from '../useSanityCreateTelemetry'

export interface CreateUnlinkConfirmDialogProps {
onClose: () => void
Expand All @@ -17,14 +18,16 @@ export function CreateUnlinkConfirmDialog(props: CreateUnlinkConfirmDialogProps)
const id = useId()
const [unlinking, setUnlinking] = useState(false)
const {t} = useTranslation(createLocaleNamespace)
const telemetry = useSanityCreateTelemetry()

const unlink = useCallback(() => {
setUnlinking(true)
onDocumentChange(PatchEvent.from(unset(['_create'])))
telemetry.unlinkAccepted()
// on not calling onClose:
// when this mutation propagates down the render tree again, this dialog will me unmounted;
// the code-path leading here will no longer be rendered
}, [onDocumentChange])
}, [onDocumentChange, telemetry])

return (
<Dialog id={id} header={t('unlink-from-create-dialog.header')} onClose={onClose}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import {
type DocumentActionDescription,
type DocumentActionProps,
} from '../../config'
import {useSchema} from '../../hooks'
import {useTranslation} from '../../i18n'
import {useSchemaType} from '../../scheduledPublishing/hooks/useSchemaType'
import {isStartInCreateAutoConfirmed, setStartInCreateAutoConfirm} from '../createStorage'
import {isSanityCreateExcludedType} from '../createUtils'
import {createLocaleNamespace} from '../i18n'
import {type AppIdCache} from '../studio-app/appIdCache'
import {useStudioAppIdStore} from '../studio-app/useStudioAppIdStore'
import {type CreateLinkedSanityDocument} from '../types'
import {useSanityCreateTelemetry} from '../useSanityCreateTelemetry'
import {CreateLinkingDialog} from './CreateLinkingDialog'
import {StartInCreateDialog} from './StartInCreateDialog'

Expand Down Expand Up @@ -40,20 +41,21 @@ export function StartInCreateAction(

const {appId} = useStudioAppIdStore(appIdCache)
const {t} = useTranslation(createLocaleNamespace)
const schema = useSchema()
const schemaType = schema.get(type)
const isExcludedByOption = schemaType && isSanityCreateExcludedType(schemaType)
const schemaType = useSchemaType(type)
const telemetry = useSanityCreateTelemetry()

const [isDialogOpen, setDialogOpen] = useState(false)
const [isLinking, setLinking] = useState(false)
const [autoConfirm, setAutoConfirm] = useState(() => isStartInCreateAutoConfirmed())

const closeDialog = useCallback(() => setDialogOpen(false), [])

const linkingStarted = useCallback((dontShowAgain: boolean) => {
setStartInCreateAutoConfirm(dontShowAgain)
setAutoConfirm(dontShowAgain)
setLinking(true)
}, [])

const isExcludedByOption = schemaType && isSanityCreateExcludedType(schemaType)
const createLinkId = (draft?._id ?? published?._id ?? liveEdit) ? id : `drafts.${id}`

//appId will always be undefined when start in create is disabled via config
Expand Down Expand Up @@ -85,6 +87,9 @@ export function StartInCreateAction(
),
},
onHandle: () => {
if (!isDialogOpen) {
telemetry.startInCreateClicked()
}
setDialogOpen(true)
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {createLocaleNamespace} from '../i18n'
import {type CreateLinkMetadata} from '../types'
import {getCreateLinkUrl} from '../useCreateDocumentUrl'
import {useGlobalUserId} from '../useGlobalUserId'
import {useSanityCreateTelemetry} from '../useSanityCreateTelemetry'

export const CREATE_LINK_TARGET = 'create'

Expand All @@ -31,6 +32,7 @@ export function StartInCreateDialog(props: StartInCreateDialogProps) {
const checkboxId = useId()
const [dontShowAgain, setDontShowAgain] = useState(false)

const telemetry = useSanityCreateTelemetry()
const toggleDontShowAgain = useCallback(() => setDontShowAgain((current) => !current), [])

const {patch} = useDocumentOperation(publicId, type)
Expand All @@ -56,8 +58,10 @@ export function StartInCreateDialog(props: StartInCreateDialogProps) {
})
return
}

window?.open(createUrl, CREATE_LINK_TARGET)?.focus()
onLinkingStarted(autoConfirm || dontShowAgain)
telemetry.startInCreateAccepted()

//@todo delete me
setTimeout(() => {
Expand All @@ -76,7 +80,7 @@ export function StartInCreateDialog(props: StartInCreateDialogProps) {
]),
)
}, 10000)
}, [patch, createUrl, onLinkingStarted, pushToast, t, dontShowAgain, autoConfirm])
}, [patch, createUrl, onLinkingStarted, pushToast, t, dontShowAgain, autoConfirm, telemetry])

useEffect(() => {
if (autoConfirm && createUrl) {
Expand Down
46 changes: 46 additions & 0 deletions packages/sanity/src/core/create/useSanityCreateTelemetry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {useTelemetry} from '@sanity/telemetry/react'
import {useCallback, useMemo} from 'react'

import {
CreateUnlinkAccepted,
CreateUnlinkClicked,
EditInCreateClicked,
StartInCreateAccepted,
StartInCreateClicked,
} from './__telemetry__/create.telemetry'

interface SanityCreateTelemetryHookValue {
startInCreateClicked: () => void
startInCreateAccepted: () => void
unlinkClicked: () => void
unlinkAccepted: () => void
editInCreateClicked: () => void
}

/** @internal */
export function useSanityCreateTelemetry(): SanityCreateTelemetryHookValue {
const telemetry = useTelemetry()

const startInCreateClicked = useCallback(() => telemetry.log(StartInCreateClicked), [telemetry])
const startInCreateAccepted = useCallback(() => telemetry.log(StartInCreateAccepted), [telemetry])
const unlinkClicked = useCallback(() => telemetry.log(CreateUnlinkClicked), [telemetry])
const unlinkAccepted = useCallback(() => telemetry.log(CreateUnlinkAccepted), [telemetry])
const editInCreateClicked = useCallback(() => telemetry.log(EditInCreateClicked), [telemetry])

return useMemo(
(): SanityCreateTelemetryHookValue => ({
startInCreateClicked,
startInCreateAccepted,
unlinkClicked,
unlinkAccepted,
editInCreateClicked,
}),
[
startInCreateClicked,
startInCreateAccepted,
unlinkClicked,
unlinkAccepted,
editInCreateClicked,
],
)
}

0 comments on commit e2d3a71

Please sign in to comment.