Skip to content
10 changes: 10 additions & 0 deletions src/components/actionbar/ComfyActionbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { computed, nextTick, onMounted, ref, watch } from 'vue'

import { t } from '@/i18n'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import { cn } from '@/utils/tailwindUtil'

import ComfyRunButton from './ComfyRunButton'
Expand Down Expand Up @@ -132,6 +133,15 @@ watch(visible, async (newVisible) => {
}
})

/**
* Track run button handle drag start using mousedown on the drag handle.
*/
useEventListener(dragHandleRef, 'mousedown', () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'actionbar_run_handle_drag_start'
})
})

const lastDragState = ref({
x: x.value,
y: y.value,
Expand Down
14 changes: 13 additions & 1 deletion src/components/actionbar/ComfyRunButton/ComfyQueueButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ import BatchCountEdit from '../BatchCountEdit.vue'

const workspaceStore = useWorkspaceStore()
const queueCountStore = storeToRefs(useQueuePendingTaskCountStore())
const { mode: queueMode } = storeToRefs(useQueueSettingsStore())
const { mode: queueMode, batchCount } = storeToRefs(useQueueSettingsStore())

const { t } = useI18n()
const queueModeMenuItemLookup = computed(() => {
Expand All @@ -118,6 +118,9 @@ const queueModeMenuItemLookup = computed(() => {
label: `${t('menu.run')} (${t('menu.onChange')})`,
tooltip: t('menu.onChangeTooltip'),
command: () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'queue_mode_option_run_on_change_selected'
})
queueMode.value = 'change'
}
}
Expand All @@ -128,6 +131,9 @@ const queueModeMenuItemLookup = computed(() => {
label: `${t('menu.run')} (${t('menu.instant')})`,
tooltip: t('menu.instantTooltip'),
command: () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'queue_mode_option_run_instant_selected'
})
queueMode.value = 'instant'
}
}
Expand Down Expand Up @@ -160,6 +166,12 @@ const queuePrompt = async (e: Event) => {

useTelemetry()?.trackRunButton({ subscribe_to_run: false })

if (batchCount.value > 1) {
useTelemetry()?.trackUiButtonClicked({
button_id: 'queue_run_multiple_batches_submitted'
})
}

await commandStore.execute(commandId)
}
</script>
Expand Down
7 changes: 7 additions & 0 deletions src/components/breadcrumb/SubgraphBreadcrumb.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { computed, onUpdated, ref, watch } from 'vue'

import SubgraphBreadcrumbItem from '@/components/breadcrumb/SubgraphBreadcrumbItem.vue'
import { useOverflowObserver } from '@/composables/element/useOverflowObserver'
import { useTelemetry } from '@/platform/telemetry'
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { useSubgraphNavigationStore } from '@/stores/subgraphNavigationStore'
Expand Down Expand Up @@ -73,6 +74,9 @@ const items = computed(() => {
const items = navigationStore.navigationStack.map<MenuItem>((subgraph) => ({
label: subgraph.name,
command: () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'breadcrumb_subgraph_item_selected'
})
const canvas = useCanvasStore().getCanvas()
if (!canvas.graph) throw new TypeError('Canvas has no graph')

Expand All @@ -97,6 +101,9 @@ const home = computed(() => ({
key: 'root',
isBlueprint: isBlueprint.value,
command: () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'breadcrumb_subgraph_root_selected'
})
const canvas = useCanvasStore().getCanvas()
if (!canvas.graph) throw new TypeError('Canvas has no graph')

Expand Down
9 changes: 9 additions & 0 deletions src/components/dialog/content/ErrorDialogContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@ const repoOwner = 'comfyanonymous'
const repoName = 'ComfyUI'
const reportContent = ref('')
const reportOpen = ref(false)
/**
* Open the error report content and track telemetry.
*/
const showReport = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'error_dialog_show_report_clicked'
})
reportOpen.value = true
}
const toast = useToast()
Expand All @@ -99,6 +105,9 @@ const title = computed<string>(
() => error.nodeType ?? error.exceptionType ?? t('errorDialog.defaultTitle')
)

/**
* Open contact support flow from error dialog and track telemetry.
*/
const showContactSupport = async () => {
telemetry?.trackHelpResourceClicked({
resource_type: 'help_feedback',
Expand Down
8 changes: 8 additions & 0 deletions src/components/dialog/content/error/FindIssueButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import Button from 'primevue/button'
import { computed } from 'vue'

import { useTelemetry } from '@/platform/telemetry'

const props = defineProps<{
errorMessage: string
repoOwner: string
Expand All @@ -19,7 +21,13 @@ const props = defineProps<{

const queryString = computed(() => props.errorMessage + ' is:issue')

/**
* Open GitHub issues search and track telemetry.
*/
const openGitHubIssues = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'error_dialog_find_existing_issues_clicked'
})
const query = encodeURIComponent(queryString.value)
const url = `https://github.com/${props.repoOwner}/${props.repoName}/issues?q=${query}`
window.open(url, '_blank')
Expand Down
2 changes: 2 additions & 0 deletions src/components/dialog/content/setting/CreditsPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ watch(
)

const handlePurchaseCreditsClick = () => {
// Track purchase credits entry from Settings > Credits panel
useTelemetry()?.trackAddApiCreditButtonClicked()
dialogService.showTopUpCreditsDialog()
}

Expand Down
25 changes: 23 additions & 2 deletions src/components/graph/GraphCanvasMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
data-testid="toggle-minimap-button"
:style="stringifiedMinimapStyles.buttonStyles"
:class="minimapButtonClass"
@click="() => commandStore.execute('Comfy.Canvas.ToggleMinimap')"
@click="onMinimapToggleClick"
>
<template #icon>
<i class="icon-[lucide--map] h-4 w-4" />
Expand All @@ -82,7 +82,7 @@
:aria-label="linkVisibilityAriaLabel"
data-testid="toggle-link-visibility-button"
:style="stringifiedMinimapStyles.buttonStyles"
@click="() => commandStore.execute('Comfy.Canvas.ToggleLinkVisibility')"
@click="onLinkVisibilityToggleClick"
>
<template #icon>
<i class="icon-[lucide--route-off] h-4 w-4" />
Expand All @@ -101,6 +101,7 @@ import { useI18n } from 'vue-i18n'
import { useZoomControls } from '@/composables/useZoomControls'
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteractions'
import { useMinimap } from '@/renderer/extensions/minimap/composables/useMinimap'
Expand Down Expand Up @@ -218,6 +219,26 @@ onMounted(() => {
canvasStore.initScaleSync()
})

/**
* Track minimap toggle button click and execute the command.
*/
const onMinimapToggleClick = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'graph_menu_minimap_toggle_clicked'
})
void commandStore.execute('Comfy.Canvas.ToggleMinimap')
}

/**
* Track hide/show links button click and execute the command.
*/
const onLinkVisibilityToggleClick = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'graph_menu_hide_links_toggle_clicked'
})
void commandStore.execute('Comfy.Canvas.ToggleLinkVisibility')
}

onBeforeUnmount(() => {
canvasStore.cleanupScaleSync()
})
Expand Down
13 changes: 12 additions & 1 deletion src/components/graph/selectionToolbox/InfoButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
data-testid="info-button"
text
severity="secondary"
@click="toggleHelp"
@click="onInfoClick"
>
<i class="icon-[lucide--info] h-4 w-4" />
</Button>
Expand All @@ -17,6 +17,17 @@
import Button from 'primevue/button'

import { useSelectionState } from '@/composables/graph/useSelectionState'
import { useTelemetry } from '@/platform/telemetry'

const { showNodeHelp: toggleHelp } = useSelectionState()

/**
* Track node info button click and toggle node help.
*/
const onInfoClick = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'selection_toolbox_node_info_opened'
})
toggleHelp()
}
</script>
19 changes: 17 additions & 2 deletions src/components/sidebar/ComfyMenuButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
:class="{
'comfy-menu-button-active': menuRef?.visible
}"
@click="menuRef?.toggle($event)"
@click="onLogoMenuClick($event)"
>
<ComfyLogoTransparent
alt="ComfyUI Logo"
Expand Down Expand Up @@ -78,6 +78,7 @@ import SettingDialogHeader from '@/components/dialog/header/SettingDialogHeader.
import ComfyLogoTransparent from '@/components/icons/ComfyLogoTransparent.vue'
import { useWorkflowTemplateSelectorDialog } from '@/composables/useWorkflowTemplateSelectorDialog'
import SettingDialogContent from '@/platform/settings/components/SettingDialogContent.vue'
import { useTelemetry } from '@/platform/telemetry'
import { useColorPaletteService } from '@/services/colorPaletteService'
import { useCommandStore } from '@/stores/commandStore'
import { useDialogStore } from '@/stores/dialogStore'
Expand All @@ -104,6 +105,15 @@ const menuRef = ref<
({ dirty: boolean } & TieredMenuMethods & TieredMenuState) | null
>(null)

const telemetry = useTelemetry()

function onLogoMenuClick(event: MouseEvent) {
telemetry?.trackUiButtonClicked({
button_id: 'sidebar_comfy_menu_opened'
})
menuRef.value?.toggle(event)
}

const translateMenuItem = (item: MenuItem): MenuItem => {
const label = typeof item.label === 'function' ? item.label() : item.label
const translatedLabel = label
Expand Down Expand Up @@ -167,7 +177,12 @@ const extraMenuItems = computed(() => [
key: 'settings',
label: t('g.settings'),
icon: 'mdi mdi-cog-outline',
command: () => showSettings()
command: () => {
telemetry?.trackUiButtonClicked({
button_id: 'sidebar_settings_menu_opened'
})
showSettings()
}
},
{
key: 'manage-extensions',
Expand Down
33 changes: 32 additions & 1 deletion src/components/sidebar/SideToolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import ComfyMenuButton from '@/components/sidebar/ComfyMenuButton.vue'
import SidebarBottomPanelToggleButton from '@/components/sidebar/SidebarBottomPanelToggleButton.vue'
import SidebarShortcutsToggleButton from '@/components/sidebar/SidebarShortcutsToggleButton.vue'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { useCommandStore } from '@/stores/commandStore'
import { useKeybindingStore } from '@/stores/keybindingStore'
Expand Down Expand Up @@ -97,10 +98,40 @@ const isConnected = computed(
const tabs = computed(() => workspaceStore.getSidebarTabs())
const selectedTab = computed(() => workspaceStore.sidebarTab.activeSidebarTab)

const onTabClick = async (item: SidebarTabExtension) =>
/**
* Handle sidebar tab icon click.
* - Emits UI button telemetry for known tabs
* - Delegates to the corresponding toggle command
*/
const onTabClick = async (item: SidebarTabExtension) => {
const telemetry = useTelemetry()

const isNodeLibraryTab = item.id === 'node-library'
const isModelLibraryTab = item.id === 'model-library'
const isWorkflowsTab = item.id === 'workflows'
const isAssetsTab = item.id === 'assets'

if (isNodeLibraryTab)
telemetry?.trackUiButtonClicked({
button_id: 'sidebar_tab_node_library_selected'
})
else if (isModelLibraryTab)
telemetry?.trackUiButtonClicked({
button_id: 'sidebar_tab_model_library_selected'
})
else if (isWorkflowsTab)
telemetry?.trackUiButtonClicked({
button_id: 'sidebar_tab_workflows_selected'
})
else if (isAssetsTab)
telemetry?.trackUiButtonClicked({
button_id: 'sidebar_tab_assets_media_selected'
})

await commandStore.commands
.find((cmd) => cmd.id === `Workspace.ToggleSidebarTab.${item.id}`)
?.function?.()
}

const keybindingStore = useKeybindingStore()
const getTabTooltipSuffix = (tab: SidebarTabExtension) => {
Expand Down
13 changes: 12 additions & 1 deletion src/components/sidebar/SidebarBottomPanelToggleButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
:label="$t('sideToolbar.labels.console')"
:tooltip="$t('menu.toggleBottomPanel')"
:selected="bottomPanelStore.activePanel == 'terminal'"
@click="bottomPanelStore.toggleBottomPanel"
@click="toggleConsole"
>
<template #icon>
<i-ph:terminal-bold />
Expand All @@ -12,9 +12,20 @@
</template>

<script setup lang="ts">
import { useTelemetry } from '@/platform/telemetry'
import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'

import SidebarIcon from './SidebarIcon.vue'

const bottomPanelStore = useBottomPanelStore()

/**
* Toggle console bottom panel and track UI button click.
*/
const toggleConsole = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'sidebar_bottom_panel_console_toggled'
})
bottomPanelStore.toggleBottomPanel()
}
</script>
7 changes: 7 additions & 0 deletions src/components/sidebar/SidebarHelpCenterIcon.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import { computed, onMounted, toRefs } from 'vue'

import HelpCenterMenuContent from '@/components/helpcenter/HelpCenterMenuContent.vue'
import { useSettingStore } from '@/platform/settings/settingStore'
import { useTelemetry } from '@/platform/telemetry'
import { useReleaseStore } from '@/platform/updates/common/releaseStore'
import ReleaseNotificationToast from '@/platform/updates/components/ReleaseNotificationToast.vue'
import WhatsNewPopup from '@/platform/updates/components/WhatsNewPopup.vue'
Expand Down Expand Up @@ -104,7 +105,13 @@ const sidebarLocation = computed(() =>
settingStore.get('Comfy.Sidebar.Location')
)

/**
* Toggle Help Center and track UI button click.
*/
const toggleHelpCenter = () => {
useTelemetry()?.trackUiButtonClicked({
button_id: 'sidebar_help_center_toggled'
})
helpCenterStore.toggle()
}

Expand Down
Loading
Loading