mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-04 04:30:04 +00:00
feat(telemetry): help center and workflow creation (#6505)
## Summary For Cloud distribution: 1. Track help center usage 2. Track workflow creation ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6505-feat-telemetry-help-center-and-workflow-creation-29e6d73d36508185af8ccbf19d5af9e7) by [Unito](https://www.unito.io) --------- Co-authored-by: Christian Byrne <chrbyrne96@gmail.com> Co-authored-by: Christian Byrne <cbyrne@comfy.org> Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -158,9 +158,7 @@ const queuePrompt = async (e: Event) => {
|
||||
? 'Comfy.QueuePromptFront'
|
||||
: 'Comfy.QueuePrompt'
|
||||
|
||||
if (isCloud) {
|
||||
useTelemetry()?.trackRunButton({ subscribe_to_run: false })
|
||||
}
|
||||
useTelemetry()?.trackRunButton({ subscribe_to_run: false })
|
||||
|
||||
await commandStore.execute(commandId)
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import NoResultsPlaceholder from '@/components/common/NoResultsPlaceholder.vue'
|
||||
import FindIssueButton from '@/components/dialog/content/error/FindIssueButton.vue'
|
||||
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { api } from '@/scripts/api'
|
||||
import { app } from '@/scripts/app'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
@@ -92,12 +93,18 @@ const showReport = () => {
|
||||
const toast = useToast()
|
||||
const { t } = useI18n()
|
||||
const systemStatsStore = useSystemStatsStore()
|
||||
const telemetry = useTelemetry()
|
||||
|
||||
const title = computed<string>(
|
||||
() => error.nodeType ?? error.exceptionType ?? t('errorDialog.defaultTitle')
|
||||
)
|
||||
|
||||
const showContactSupport = async () => {
|
||||
telemetry?.trackHelpResourceClicked({
|
||||
resource_type: 'help_feedback',
|
||||
is_external: true,
|
||||
source: 'error_dialog'
|
||||
})
|
||||
await useCommandStore().execute('Comfy.ContactSupport')
|
||||
}
|
||||
|
||||
|
||||
@@ -124,6 +124,7 @@ import UserCredit from '@/components/common/UserCredit.vue'
|
||||
import UsageLogsTable from '@/components/dialog/content/setting/UsageLogsTable.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
@@ -140,6 +141,7 @@ const dialogService = useDialogService()
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const commandStore = useCommandStore()
|
||||
const telemetry = useTelemetry()
|
||||
const { isActiveSubscription } = useSubscription()
|
||||
const loading = computed(() => authStore.loading)
|
||||
const balanceLoading = computed(() => authStore.isFetchingBalance)
|
||||
@@ -170,6 +172,11 @@ const handleCreditsHistoryClick = async () => {
|
||||
}
|
||||
|
||||
const handleMessageSupport = async () => {
|
||||
telemetry?.trackHelpResourceClicked({
|
||||
resource_type: 'help_feedback',
|
||||
is_external: true,
|
||||
source: 'credits_panel'
|
||||
})
|
||||
await commandStore.execute('Comfy.ContactSupport')
|
||||
}
|
||||
|
||||
|
||||
@@ -138,13 +138,14 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import Button from 'primevue/button'
|
||||
import { computed, nextTick, onMounted, ref } from 'vue'
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import type { CSSProperties, Component } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import PuzzleIcon from '@/components/icons/PuzzleIcon.vue'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import type { ReleaseNote } from '@/platform/updates/common/releaseService'
|
||||
import { useReleaseStore } from '@/platform/updates/common/releaseStore'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
@@ -196,6 +197,7 @@ const { t, locale } = useI18n()
|
||||
const releaseStore = useReleaseStore()
|
||||
const commandStore = useCommandStore()
|
||||
const settingStore = useSettingStore()
|
||||
const telemetry = useTelemetry()
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
@@ -207,6 +209,7 @@ const isSubmenuVisible = ref(false)
|
||||
const submenuRef = ref<HTMLElement | null>(null)
|
||||
const submenuStyle = ref<CSSProperties>({})
|
||||
let hoverTimeout: number | null = null
|
||||
const openedAt = ref<number>(Date.now())
|
||||
|
||||
// Computed
|
||||
const hasReleases = computed(() => releaseStore.releases.length > 0)
|
||||
@@ -226,6 +229,7 @@ const moreItems = computed<MenuItem[]>(() => {
|
||||
label: t('helpCenter.desktopUserGuide'),
|
||||
visible: isElectron(),
|
||||
action: () => {
|
||||
trackResourceClick('docs', true)
|
||||
const docsUrl =
|
||||
electronAPI().getPlatform() === 'darwin'
|
||||
? EXTERNAL_LINKS.DESKTOP_GUIDE_MACOS
|
||||
@@ -281,6 +285,7 @@ const menuItems = computed<MenuItem[]>(() => {
|
||||
icon: 'pi pi-book',
|
||||
label: t('helpCenter.docs'),
|
||||
action: () => {
|
||||
trackResourceClick('docs', true)
|
||||
openExternalLink(EXTERNAL_LINKS.DOCS)
|
||||
emit('close')
|
||||
}
|
||||
@@ -291,6 +296,7 @@ const menuItems = computed<MenuItem[]>(() => {
|
||||
icon: 'pi pi-discord',
|
||||
label: 'Discord',
|
||||
action: () => {
|
||||
trackResourceClick('discord', true)
|
||||
openExternalLink(EXTERNAL_LINKS.DISCORD)
|
||||
emit('close')
|
||||
}
|
||||
@@ -301,6 +307,7 @@ const menuItems = computed<MenuItem[]>(() => {
|
||||
icon: 'pi pi-github',
|
||||
label: t('helpCenter.github'),
|
||||
action: () => {
|
||||
trackResourceClick('github', true)
|
||||
openExternalLink(EXTERNAL_LINKS.GITHUB)
|
||||
emit('close')
|
||||
}
|
||||
@@ -311,6 +318,7 @@ const menuItems = computed<MenuItem[]>(() => {
|
||||
icon: 'pi pi-question-circle',
|
||||
label: t('helpCenter.helpFeedback'),
|
||||
action: () => {
|
||||
trackResourceClick('help_feedback', false)
|
||||
void commandStore.execute('Comfy.ContactSupport')
|
||||
emit('close')
|
||||
}
|
||||
@@ -326,6 +334,7 @@ const menuItems = computed<MenuItem[]>(() => {
|
||||
label: t('helpCenter.managerExtension'),
|
||||
showRedDot: shouldShowManagerRedDot.value,
|
||||
action: async () => {
|
||||
trackResourceClick('manager', false)
|
||||
await useManagerState().openManager({
|
||||
initialTab: ManagerTab.All,
|
||||
showToastOnLegacyError: false
|
||||
@@ -349,6 +358,23 @@ const menuItems = computed<MenuItem[]>(() => {
|
||||
})
|
||||
|
||||
// Utility Functions
|
||||
const trackResourceClick = (
|
||||
resourceType:
|
||||
| 'docs'
|
||||
| 'discord'
|
||||
| 'github'
|
||||
| 'help_feedback'
|
||||
| 'manager'
|
||||
| 'release_notes',
|
||||
isExternal: boolean
|
||||
): void => {
|
||||
telemetry?.trackHelpResourceClicked({
|
||||
resource_type: resourceType,
|
||||
is_external: isExternal,
|
||||
source: 'help_center'
|
||||
})
|
||||
}
|
||||
|
||||
const openExternalLink = (url: string): void => {
|
||||
window.open(url, '_blank', 'noopener,noreferrer')
|
||||
}
|
||||
@@ -504,6 +530,7 @@ const onReinstall = (): void => {
|
||||
}
|
||||
|
||||
const onReleaseClick = (release: ReleaseNote): void => {
|
||||
trackResourceClick('release_notes', true)
|
||||
void releaseStore.handleShowChangelog(release.version)
|
||||
const versionAnchor = formatVersionAnchor(release.version)
|
||||
const changelogUrl = `${getChangelogUrl()}#${versionAnchor}`
|
||||
@@ -512,6 +539,7 @@ const onReleaseClick = (release: ReleaseNote): void => {
|
||||
}
|
||||
|
||||
const onUpdate = (_: ReleaseNote): void => {
|
||||
trackResourceClick('docs', true)
|
||||
openExternalLink(EXTERNAL_LINKS.UPDATE_GUIDE)
|
||||
emit('close')
|
||||
}
|
||||
@@ -526,10 +554,16 @@ const getChangelogUrl = (): string => {
|
||||
|
||||
// Lifecycle
|
||||
onMounted(async () => {
|
||||
telemetry?.trackHelpCenterOpened({ source: 'sidebar' })
|
||||
if (!hasReleases.value) {
|
||||
await releaseStore.fetchReleases()
|
||||
}
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
const timeSpentSeconds = Math.round((Date.now() - openedAt.value) / 1000)
|
||||
telemetry?.trackHelpCenterClosed({ time_spent_seconds: timeSpentSeconds })
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user